<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Control your own WordPress custom fields</title>
	<atom:link href="http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/feed/" rel="self" type="application/rss+xml" />
	<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/</link>
	<description>Freelance WordPress developer in London - XHTML, CSS &#38; design</description>
	<lastBuildDate>Wed, 19 Oct 2011 15:15:33 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10960</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Thu, 09 Dec 2010 14:07:53 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10960</guid>
		<description>&lt;strong&gt;PLEASE NOTE:&lt;/strong&gt; This code has now evolved into the &lt;a href=&quot;http://sltaylor.co.uk/wordpress/plugins/slt-custom-fields/&quot;&gt;SLT Custom Fields plugin&lt;/a&gt;. There&#039;ll be no more updates to this code - please use the plugin.</description>
		<content:encoded><![CDATA[<p><strong>PLEASE NOTE:</strong> This code has now evolved into the <a href="http://sltaylor.co.uk/wordpress/plugins/slt-custom-fields/">SLT Custom Fields plugin</a>. There&#8217;ll be no more updates to this code &#8211; please use the plugin.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10740</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Tue, 30 Nov 2010 01:00:23 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10740</guid>
		<description>To anyone subscribed to this post&#039;s comments, please check out my new version of this code!

http://sltaylor.co.uk/blog/wordpress-custom-fields-reloaded/</description>
		<content:encoded><![CDATA[<p>To anyone subscribed to this post&#8217;s comments, please check out my new version of this code!</p>
<p><a href="http://sltaylor.co.uk/blog/wordpress-custom-fields-reloaded/">http://sltaylor.co.uk/blog/wordpress-custom-fields-reloaded/</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10699</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Sun, 28 Nov 2010 21:52:07 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10699</guid>
		<description>Hi Greg, your above example should work, though I&#039;ve not tried anything like this.

The reasons for the prefix are (1) to make sure the values managed by this code don&#039;t pop up in the default custom fields interface, if that&#039;s left in place (the initial underscore makes sure of that), and (2) general good coding practice of avoiding field name clashes with plugins, etc.

If you hide the default custom fields meta box (which the above code does by default), and you&#039;re happy that your existing field names won&#039;t clash with anything, I don&#039;t see why your code won&#039;t work. Maybe set the prefix to any empty string rather than comment it out though? Also, go through every place where the prefix is used, I&#039;m not sure if there might be other impacts.</description>
		<content:encoded><![CDATA[<p>Hi Greg, your above example should work, though I&#8217;ve not tried anything like this.</p>
<p>The reasons for the prefix are (1) to make sure the values managed by this code don&#8217;t pop up in the default custom fields interface, if that&#8217;s left in place (the initial underscore makes sure of that), and (2) general good coding practice of avoiding field name clashes with plugins, etc.</p>
<p>If you hide the default custom fields meta box (which the above code does by default), and you&#8217;re happy that your existing field names won&#8217;t clash with anything, I don&#8217;t see why your code won&#8217;t work. Maybe set the prefix to any empty string rather than comment it out though? Also, go through every place where the prefix is used, I&#8217;m not sure if there might be other impacts.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Greg</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10698</link>
		<dc:creator>Greg</dc:creator>
		<pubDate>Sun, 28 Nov 2010 21:41:59 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10698</guid>
		<description>Thanks for the code, it works great!

I am a bit new to this as well, and I have a question about existing data. Basically, if I comment out your prefix var will content from currently populated customfields display in applicable fields defined by this code?

For instance: I have been adding a custom field manually via the default drop down, the key is TKRNumber and a value could be 0123

I have created a custom field array that looks like so:

&lt;code&gt;
array(
&quot;name&quot;=&gt;&quot;TKRNumber&quot;,
&quot;title&quot;=&gt;&quot;TKR Number&quot;,
&quot;description&quot;=&gt;&quot;Optional TKR Number for album release posts.&quot;,
&quot;type&quot;=&gt;&quot;text&quot;,
&quot;scope&quot;=&gt;array( &quot;post&quot; ),
&quot;capability&quot;=&gt;&quot;edit_posts&quot;
)
&lt;/code&gt;

Currently existing data isn&#039;t populating this field, so I&#039;m wondering if deleting the prefix would solve this, or if I need to do something else?

Thanks again.
-g</description>
		<content:encoded><![CDATA[<p>Thanks for the code, it works great!</p>
<p>I am a bit new to this as well, and I have a question about existing data. Basically, if I comment out your prefix var will content from currently populated customfields display in applicable fields defined by this code?</p>
<p>For instance: I have been adding a custom field manually via the default drop down, the key is TKRNumber and a value could be 0123</p>
<p>I have created a custom field array that looks like so:</p>
<p><code><br />
array(<br />
"name"=&gt;"TKRNumber",<br />
"title"=&gt;"TKR Number",<br />
"description"=&gt;"Optional TKR Number for album release posts.",<br />
"type"=&gt;"text",<br />
"scope"=&gt;array( "post" ),<br />
"capability"=&gt;"edit_posts"<br />
)<br />
</code></p>
<p>Currently existing data isn&#8217;t populating this field, so I&#8217;m wondering if deleting the prefix would solve this, or if I need to do something else?</p>
<p>Thanks again.<br />
-g</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10624</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Wed, 24 Nov 2010 21:57:46 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10624</guid>
		<description>Hi Jayson, watch this space - I&#039;m about to work on a project that needs some more refined custom field handling, so I&#039;m planning an overhaul of this code, which will include drop-down handling!</description>
		<content:encoded><![CDATA[<p>Hi Jayson, watch this space &#8211; I&#8217;m about to work on a project that needs some more refined custom field handling, so I&#8217;m planning an overhaul of this code, which will include drop-down handling!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jayson Brown</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10623</link>
		<dc:creator>Jayson Brown</dc:creator>
		<pubDate>Wed, 24 Nov 2010 21:28:03 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10623</guid>
		<description>Hi Steve, had some issues implementing a simple dropdown field like &lt;strong&gt;Flavius&lt;/strong&gt;, so I posted a question on WPQuestions … thought maybe someone might be interested in the answers; &lt;a href=&quot;http://wcdco.info/dy&quot;&gt;http://wcdco.info/dy&lt;/a&gt; either way I appreciate the code, it’s great to work with!</description>
		<content:encoded><![CDATA[<p>Hi Steve, had some issues implementing a simple dropdown field like <strong>Flavius</strong>, so I posted a question on WPQuestions … thought maybe someone might be interested in the answers; <a href="http://wcdco.info/dy">http://wcdco.info/dy</a> either way I appreciate the code, it’s great to work with!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10527</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Fri, 19 Nov 2010 19:25:04 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10527</guid>
		<description>Hi Matthias, I just looked into this and it looks like the error is just a PHP notice-level error. I think on the autosave &lt;code&gt;$_POST[ &#039;my-custom-fields_wpnonce&#039; ]&lt;/code&gt; isn&#039;t defined, hence the &quot;undefined index&quot;. I&#039;ve added a check for this variable and it seems to be fine.

Note that this was just a &quot;notice&quot;, i.e. I don&#039;t think it wasn&#039;t really affecting the functionality of the code. A number of plugins, and possibly some core code, generate notice-level errors. They&#039;re just alerting you to things that mean your code isn&#039;t perfect, but the problem isn&#039;t necessarily going to break anything. If you were seeing this error, I assume it was on a development server? If it&#039;s on your live site, you might look into disabling PHP error output.</description>
		<content:encoded><![CDATA[<p>Hi Matthias, I just looked into this and it looks like the error is just a PHP notice-level error. I think on the autosave <code>$_POST[ 'my-custom-fields_wpnonce' ]</code> isn&#8217;t defined, hence the &#8220;undefined index&#8221;. I&#8217;ve added a check for this variable and it seems to be fine.</p>
<p>Note that this was just a &#8220;notice&#8221;, i.e. I don&#8217;t think it wasn&#8217;t really affecting the functionality of the code. A number of plugins, and possibly some core code, generate notice-level errors. They&#8217;re just alerting you to things that mean your code isn&#8217;t perfect, but the problem isn&#8217;t necessarily going to break anything. If you were seeing this error, I assume it was on a development server? If it&#8217;s on your live site, you might look into disabling PHP error output.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matthias</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-10526</link>
		<dc:creator>Matthias</dc:creator>
		<pubDate>Fri, 19 Nov 2010 19:04:45 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-10526</guid>
		<description>&lt;blockquote cite=&quot;miklb&quot;&gt;Very nice tutorial, and just what I was looking for. One problem I’m seeing is that I’m getting a “Undefined index: my-custom-fields_wpnonce” as well as a header already sent warning. Not sure if it’s happening on an autosave or not. The undefined index is happening on the second reference to the wpnonce. Using 2.9.1.1. Any tips appreciated.&lt;/blockquote&gt;

I have the same error! Please help :)
Using version 3.0.1</description>
		<content:encoded><![CDATA[<blockquote cite="miklb"><p>Very nice tutorial, and just what I was looking for. One problem I’m seeing is that I’m getting a “Undefined index: my-custom-fields_wpnonce” as well as a header already sent warning. Not sure if it’s happening on an autosave or not. The undefined index is happening on the second reference to the wpnonce. Using 2.9.1.1. Any tips appreciated.</p></blockquote>
<p>I have the same error! Please help :)<br />
Using version 3.0.1</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adam van den Hoven</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-5438</link>
		<dc:creator>Adam van den Hoven</dc:creator>
		<pubDate>Sat, 03 Apr 2010 21:33:04 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-5438</guid>
		<description>I really like your code...

I figured I&#039;d send you this improvement. I didn&#039;t like the fact that you couldn&#039;t easily create a field that allowed a field on both pages and posts for people who have permissions to edit either (not that someone without edit_page permission would end up editing or creating a page).

I also didn&#039;t like your way of testing permissions. its a matter of taste but I like using array_reduce (I&#039;m not really a PHP guy, more Ruby with some Java). I noodled around and I think that this is a more robust system:

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;var $customFields = array(
 array(
 &quot;name&quot; =_ &quot;...&quot;,
 &quot;title&quot; =_ &quot;...&quot;,
 &quot;description&quot; =_ &quot;...&quot;,
 &quot;type&quot; =_ &quot;...&quot;,
 &quot;permission&quot; =_ array(
 array( &quot;scope&quot; =_ &quot;post&quot;, &quot;capability&quot; =_&quot;edit_posts&quot;),
 array( &quot;scope&quot; =_ &quot;page&quot;, &quot;capability&quot; =_&quot;edit_pages&quot;),
 array(
 &quot;scope&quot; =_ array(&quot;type-one&quot;, &quot;type-2&quot;),
 &quot;capability&quot; =_ array(&quot;cap1&quot;, &quot;cap2&quot;)
 ),
 )
 )
);
function reduce_scope ($memo, $scope){
 global $post;
 return $memo &#124;&#124; (basename( $_SERVER[&#039;SCRIPT_FILENAME&#039;] ) == $scope . &quot;-new.php&quot; &#124;&#124; $post-_post_type == $scope);
}
function reduce_capability ($memo, $cap){
 global $post;
 return $memo &#124;&#124; current_user_can( $cap, $post-_ID );
}
function reduce_permissions( $memo, $permssion){
 $scopes = is_array($val) ? $permission[&#039;scope&#039;] : array($permission[&#039;scope&#039;]);
 $capabilities = is_array($val) ? $permission[&#039;capability&#039;] : array($permission[&#039;capability&#039;]);
 return $memo &#124;&#124; (array_reduce($scopes, &quot;reduce_scope&quot;, false) &amp;&amp; array_reduce($scopes, &quot;reduce_capability&quot;, capabilities));
}
function can_show($permissions){
 return array_reduce($permissions, &quot;reduce_permissions&quot;, false);
}&lt;/pre&gt;

You can now replace this code:

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;foreach ( $scope as $scopeItem ) {
       switch ( $scopeItem ) {
               case &quot;post&quot;: {
                       // Output on any post screen
                       if ( basename( $_SERVER[&#039;SCRIPT_FILENAME&#039;] )==&quot;post-new.php&quot; &#124;&#124; $post-_post_type==&quot;post&quot; )
                               $output = true;
                       break;
               }
               case &quot;page&quot;: {
                       // Output on any page screen
                       if ( basename( $_SERVER[&#039;SCRIPT_FILENAME&#039;] )==&quot;page-new.php&quot; &#124;&#124; $post-_post_type==&quot;page&quot; )
                               $output = true;
                       break;
               }
       }
       if ( $output ) break;
}
// Check capability
if ( !current_user_can( $customField[&#039;capability&#039;], $post-_ID ) )
 $output = false;&lt;/pre&gt;

with simply:

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$output = $this-_can_show($customField[&#039;permission&#039;]);&lt;/pre&gt;

(You&#039;ll have to put the reduce_* functions outside the class definition).

Now, aside from simplifying the code (I&#039;m a big fan of breaking down my functions so they are no more than 20 lines of code if possible), the permission system is now a lot more flexible.

The logic is this:

&lt;ul&gt;
	&lt;li&gt;You can show the field if any of the permissions is satisfied&lt;/li&gt;
	&lt;li&gt;A permission is satisfied if one of its scopes and one of its capabilities are satisfied&lt;/li&gt;
	&lt;li&gt;A scope is satisfied if the script filename is $scope . &quot;-new.php&quot; or the post_type == $scope&lt;/li&gt;
	&lt;li&gt;A capability is satisfied if the current user is capable of that action on the current post.&lt;/li&gt;
&lt;/ul&gt;

This method of determining permissions has an interesting side effect (which is not necessary for typical WP installs, but interesting none the less). It lends itself to a &quot;map-reduce&quot; algo where you first map the arrays to booleans, which can be done in parallel (say over many processor cores and/or machines), then reduce the array to a boolean, which cannot be done in parallel but its comparitively efficient to reduce booleans.</description>
		<content:encoded><![CDATA[<p>I really like your code&#8230;</p>
<p>I figured I&#8217;d send you this improvement. I didn&#8217;t like the fact that you couldn&#8217;t easily create a field that allowed a field on both pages and posts for people who have permissions to edit either (not that someone without edit_page permission would end up editing or creating a page).</p>
<p>I also didn&#8217;t like your way of testing permissions. its a matter of taste but I like using array_reduce (I&#8217;m not really a PHP guy, more Ruby with some Java). I noodled around and I think that this is a more robust system:</p>
<pre name="code" class="php">var $customFields = array(
 array(
 "name" =_ "...",
 "title" =_ "...",
 "description" =_ "...",
 "type" =_ "...",
 "permission" =_ array(
 array( "scope" =_ "post", "capability" =_"edit_posts"),
 array( "scope" =_ "page", "capability" =_"edit_pages"),
 array(
 "scope" =_ array("type-one", "type-2"),
 "capability" =_ array("cap1", "cap2")
 ),
 )
 )
);
function reduce_scope ($memo, $scope){
 global $post;
 return $memo || (basename( $_SERVER['SCRIPT_FILENAME'] ) == $scope . "-new.php" || $post-_post_type == $scope);
}
function reduce_capability ($memo, $cap){
 global $post;
 return $memo || current_user_can( $cap, $post-_ID );
}
function reduce_permissions( $memo, $permssion){
 $scopes = is_array($val) ? $permission['scope'] : array($permission['scope']);
 $capabilities = is_array($val) ? $permission['capability'] : array($permission['capability']);
 return $memo || (array_reduce($scopes, "reduce_scope", false) &amp;&amp; array_reduce($scopes, "reduce_capability", capabilities));
}
function can_show($permissions){
 return array_reduce($permissions, "reduce_permissions", false);
}</pre>
<p>You can now replace this code:</p>
<pre name="code" class="php">foreach ( $scope as $scopeItem ) {
       switch ( $scopeItem ) {
               case "post": {
                       // Output on any post screen
                       if ( basename( $_SERVER['SCRIPT_FILENAME'] )=="post-new.php" || $post-_post_type=="post" )
                               $output = true;
                       break;
               }
               case "page": {
                       // Output on any page screen
                       if ( basename( $_SERVER['SCRIPT_FILENAME'] )=="page-new.php" || $post-_post_type=="page" )
                               $output = true;
                       break;
               }
       }
       if ( $output ) break;
}
// Check capability
if ( !current_user_can( $customField['capability'], $post-_ID ) )
 $output = false;</pre>
<p>with simply:</p>
<pre name="code" class="php">$output = $this-_can_show($customField['permission']);</pre>
<p>(You&#8217;ll have to put the reduce_* functions outside the class definition).</p>
<p>Now, aside from simplifying the code (I&#8217;m a big fan of breaking down my functions so they are no more than 20 lines of code if possible), the permission system is now a lot more flexible.</p>
<p>The logic is this:</p>
<ul>
<li>You can show the field if any of the permissions is satisfied</li>
<li>A permission is satisfied if one of its scopes and one of its capabilities are satisfied</li>
<li>A scope is satisfied if the script filename is $scope . &#8220;-new.php&#8221; or the post_type == $scope</li>
<li>A capability is satisfied if the current user is capable of that action on the current post.</li>
</ul>
<p>This method of determining permissions has an interesting side effect (which is not necessary for typical WP installs, but interesting none the less). It lends itself to a &#8220;map-reduce&#8221; algo where you first map the arrays to booleans, which can be done in parallel (say over many processor cores and/or machines), then reduce the array to a boolean, which cannot be done in parallel but its comparitively efficient to reduce booleans.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Taylor</title>
		<link>http://sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/#comment-3860</link>
		<dc:creator>Steve Taylor</dc:creator>
		<pubDate>Wed, 27 Jan 2010 15:42:00 +0000</pubDate>
		<guid isPermaLink="false">http://sltaylor.co.uk/?p=269#comment-3860</guid>
		<description>I&#039;ve not restricted the code to one category before, but it should be doable with some digging around with the &lt;code&gt;$post&lt;/code&gt; object. The only thing is that of course you wouldn&#039;t be able to display them until a post is created (and the category set).</description>
		<content:encoded><![CDATA[<p>I&#8217;ve not restricted the code to one category before, but it should be doable with some digging around with the <code>$post</code> object. The only thing is that of course you wouldn&#8217;t be able to display them until a post is created (and the category set).</p>
]]></content:encoded>
	</item>
</channel>
</rss>
<!-- This Quick Cache file was built for (  sltaylor.co.uk/blog/control-your-own-wordpress-custom-fields/feed/ ) in 0.25315 seconds, on Feb 4th, 2012 at 3:01 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 4th, 2012 at 4:01 am UTC -->
