<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>keith devon web development</title>
	<atom:link href="http://keithdevon.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://keithdevon.com</link>
	<description>Freelance web design and WordPress development</description>
	<lastBuildDate>Fri, 18 May 2012 10:17:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Brightcove video test</title>
		<link>http://keithdevon.com/2012/labs/brightcove-test/</link>
		<comments>http://keithdevon.com/2012/labs/brightcove-test/#comments</comments>
		<pubDate>Fri, 18 May 2012 10:04:11 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[labs]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=727</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><object id="flashObj" width="" height="" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,47,0"><param name="movie" value="http://c.brightcove.com/services/viewer/federated_f9?isVid=1&amp;isUI=1"><param name="bgcolor" value="#FFFFFF"><param name="flashVars" value="@videoPlayer=1410759619001&amp;playerID=950749960001&amp;playerKey=AQ~~,AAAAWvDOVlk~,NjlZ1cjt7xGRbBHHoFgkDnQBOlFrlvMF&amp;domain=embed&amp;dynamicStreaming=true"><param name="base" value="http://admin.brightcove.com"><param name="seamlesstabbing" value="false"><param name="allowFullScreen" value="true"><param name="swLiveConnect" value="true"><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"><embed src="http://c.brightcove.com/services/viewer/federated_f9?isVid=1&amp;isUI=1" bgcolor="#FFFFFF" flashvars="@videoPlayer=1410759619001&amp;playerID=950749960001&amp;playerKey=AQ~~,AAAAWvDOVlk~,NjlZ1cjt7xGRbBHHoFgkDnQBOlFrlvMF&amp;domain=embed&amp;dynamicStreaming=true" base="http://admin.brightcove.com" name="flashObj" width="" height="" seamlesstabbing="false" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" swliveconnect="true" wmode="transparent" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></object></p>
<p><!-- Start of Brightcove Player --></p>
<div style="display:none">
</div>
<p><!--<br />
By use of this code snippet, I agree to the Brightcove Publisher T and C<br />
found at https://accounts.brightcove.com/en/terms-and-conditions/.<br />
--></p>
<p><script language="JavaScript" type="text/javascript" src="http://admin.brightcove.com/js/BrightcoveExperiences.js"></script></p>
<p><object id="myExperience1300073578001" class="BrightcoveExperience"><param name="bgcolor" value="#FFFFFF" /><param name="width" value="480" /><param name="height" value="270" /><param name="playerID" value="950749960001" /><param name="playerKey" value="AQ~~,AAAAWvDOVlk~,NjlZ1cjt7xGRbBHHoFgkDnQBOlFrlvMF" /><param name="isVid" value="true" /><param name="isUI" value="true" /><param name="dynamicStreaming" value="true" /><param name="@videoPlayer" value="1300073578001" /></object></p>
<p><!--<br />
This script tag will cause the Brightcove Players defined above it to be created as soon<br />
as the line is read by the browser. If you wish to have the player instantiated only after<br />
the rest of the HTML is processed and the page load is complete, remove the line.<br />
--><br />
<script type="text/javascript">brightcove.createExperiences();</script></p>
<p><!-- End of Brightcove Player --></p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2012/labs/brightcove-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perfect WordPress checkboxes</title>
		<link>http://keithdevon.com/2012/tuts/perfect-wordpress-checkboxes/</link>
		<comments>http://keithdevon.com/2012/tuts/perfect-wordpress-checkboxes/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 10:43:48 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[tuts]]></category>
		<category><![CDATA[checkbox]]></category>
		<category><![CDATA[custom meta boxes]]></category>
		<category><![CDATA[Theme Development]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[wp_debug]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=717</guid>
		<description><![CDATA[I keep running into the same issue &#8211; dealing with checkboxes in custom meta boxes in WordPress. I&#8217;ve found a way to make these work for me. hopefully this can be of some use. Here&#8217;s an example of the code that I was using: The problem I&#8217;ve used a few code snippets before for generating [...]]]></description>
			<content:encoded><![CDATA[<p>I keep running into the same issue &#8211; dealing with checkboxes in custom meta boxes in WordPress. I&#8217;ve found a way to make these work for me. hopefully this can be of some use.</p>
<p>Here&#8217;s an example of the code that I was using:</p>
<pre class="brush: php; title: ; notranslate">
// Add the Top and Featured News Meta Boxes ----------------------------------------//
add_action( 'add_meta_boxes', 'add_news_metaboxes' );

function add_news_metaboxes() {
add_meta_box('kdev_top_featured_news', 'Post status', 'kdev_top_featured_news', 'post', 'side', 'default');
}

// The Top and Featured Metabox
function kdev_top_featured_news(){
global $post;
$custom = get_post_custom($post-&gt;ID);
$kdev_meta_box_top = $custom[&quot;kdev_meta_box_top&quot;][0];
$kdev_meta_box_feat = $custom[&quot;kdev_meta_box_feat&quot;][0];
?&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;kdev_meta_box_top&quot; &lt;?php if( $kdev_meta_box_top == true ) { ?&gt;checked=&quot;checked&quot;&lt;?php } ?&gt; /&gt;  Top story?&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;kdev_meta_box_feat&quot; &lt;?php if( $kdev_meta_box_feat == true ) { ?&gt;checked=&quot;checked&quot;&lt;?php } ?&gt; /&gt;  Featured story?&lt;?php
}

add_action('save_post', 'save_details');

function save_details($post_ID = 0) {
$post_ID = (int) $post_ID;
$post_type = get_post_type( $post_ID );
$post_status = get_post_status( $post_ID );

if ($post_type) {
update_post_meta($post_ID, &quot;kdev_meta_box_top&quot;, $_POST[&quot;kdev_meta_box_top&quot;]);
update_post_meta($post_ID, &quot;kdev_meta_box_feat&quot;, $_POST[&quot;kdev_meta_box_feat&quot;]);
}
return $post_ID;
}
</pre>
<h2>The problem</h2>
<p>I&#8217;ve used a few code snippets before for generating my custom meta boxes. The method above was working really well for me. At least it was, until I turned on wp_debug (which should always be on when developing!).</p>
<p>It turns out that this code generates a &#8216;notice&#8217;:</p>
<p><strong>Notice</strong>: Undefined index: kdev_meta_box_top in path/to<strong>/functions/custom-meta-boxes.php</strong> on line <strong>83</strong></p>
<p>and if debug was on it would also generate:</p>
<p><strong>Warning</strong>: Cannot modify header information &#8211; headers already sent by (output started at /path/to/wp-content/themes/mytheme/functions/custom-meta-boxes.php:83) in <strong>/path/to/wp-includes/pluggable.php</strong> on line <strong>866</strong></p>
<p>Line 83 of custom-meta-boxes.php contained this:</p>
<pre class="brush: php; title: ; notranslate">

update_post_meta($post_ID, &quot;kdev_meta_box_top&quot;, $_POST[&quot;kdev_meta_box_top&quot;]);
</pre>
<p>&#8220;<strong>Warning</strong>: Cannot modify header information&#8221; usually relates to extra whitespace at the start or end of your function files, but in this case I could see that the warning was coming from line 83 which wasn&#8217;t at the end. The notice and warning had to be related as they were both referencing the same line of the same file.</p>
<p>I still haven&#8217;t fully wrapped my head around the &#8220;Cannot modify header information&#8221; warning (help me out in the comments!), but I knew that if I stopped the notice, the warning would disappear.</p>
<p>The notice, &#8220;Undefined index&#8221; occurs when a variable has not been set. Basically, the function save_details() was referencing something that didn&#8217;t exist.</p>
<p>Why did it not exist? Because when the checkboxes were left unchecked, no variable was being set and passed to $_POST. So when the function asked for $_POST["kdev_meta_box_top"] (i.e. asked for the value of kdev_meta_box_top), that key didn&#8217;t even exist, never mind a value. Hence the notice.</p>
<h2>The solution</h2>
<p>I fiddled with various bits of logic to test for the value, etc. I realised that I needed to set a value for the checkbox, even if it wasn&#8217;t checked. That way kdev_meta_box_top would always have a value and the notice wouldn&#8217;t be generated.</p>
<p>Here&#8217;s my finished code:</p>
<pre class="brush: php; title: ; notranslate">

// Add the Top and Featured News Meta Boxes ----------------------------------------//
add_action( 'add_meta_boxes', 'add_news_metaboxes' ); function add_news_metaboxes() {    add_meta_box('kdev_top_featured_news', 'Post status', 'kdev_top_featured_news', 'post', 'side', 'default');    }

// The Top and Featured Metabox
function kdev_top_featured_news(){
global $post;
$custom = get_post_custom($post-&amp;gt;ID);
$kdev_meta_box_top = $custom[&quot;kdev_meta_box_top&quot;][0];
$kdev_meta_box_feat = $custom[&quot;kdev_meta_box_feat&quot;][0];

// We'll use this nonce field later on when saving.

wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' ); ?&amp;gt;

&amp;lt;input type=&quot;checkbox&quot; name=&quot;kdev_meta_box_top&quot; &amp;lt;?php if( $kdev_meta_box_top != 'off' ) { ?&amp;gt;checked=&quot;checked&quot;&amp;lt;?php } ?&amp;gt; /&amp;gt;  Top story?&amp;lt;br /&amp;gt;
&amp;lt;input type=&quot;checkbox&quot; name=&quot;kdev_meta_box_feat&quot; &amp;lt;?php if( $kdev_meta_box_feat != 'off' ) { ?&amp;gt;checked=&quot;checked&quot;&amp;lt;?php } ?&amp;gt; /&amp;gt;  Featured story?&amp;lt;?php}

add_action('save_post', 'save_details');

function save_details($post_ID = 0) {
$post_ID = (int) $post_ID;
$post_type = get_post_type( $post_ID );
$post_status = get_post_status( $post_ID );

// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;

// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
if(isset($_POST[&quot;kdev_meta_box_top&quot;])) $kdev_meta_box_top = $_POST[&quot;kdev_meta_box_top&quot;];
else $kdev_meta_box_top = 'off';
if(isset($_POST[&quot;kdev_meta_box_feat&quot;])) $kdev_meta_box_feat = $_POST[&quot;kdev_meta_box_feat&quot;];    else $kdev_meta_box_feat = 'off';

if ($post_type) {
update_post_meta($post_ID, &quot;kdev_meta_box_top&quot;, $kdev_meta_box_top);
update_post_meta($post_ID, &quot;kdev_meta_box_feat&quot;, $kdev_meta_box_feat);
}

return $post_ID;
}
</pre>
<p>I&#8217;ve added a nonce in there for validation too. Just to beef up the security! Let me know if it works for you.</p>
<h3>Not perfect?</h3>
<p>I doubt that this is actually the perfect solution. I&#8217;d love to hear some feedback about how this code can be improved. Please add your thoughts in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2012/tuts/perfect-wordpress-checkboxes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to find your SSH key fingerprint on a Mac</title>
		<link>http://keithdevon.com/2012/tuts/how-to-find-your-ssh-key-fingerprint-on-a-mac/</link>
		<comments>http://keithdevon.com/2012/tuts/how-to-find-your-ssh-key-fingerprint-on-a-mac/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 21:08:59 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[tuts]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=714</guid>
		<description><![CDATA[Open up your terminal and paste this in: It will return all your keys.]]></description>
			<content:encoded><![CDATA[<p>Open up your terminal and paste this in:</p>
<pre class="brush: plain; title: ; notranslate">

ls ~/.ssh/*.pub | xargs -L 1 ssh-keygen -l -f
</pre>
<p>It will return all your keys.</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2012/tuts/how-to-find-your-ssh-key-fingerprint-on-a-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Post Types</title>
		<link>http://keithdevon.com/2011/tuts/custom-post-types/</link>
		<comments>http://keithdevon.com/2011/tuts/custom-post-types/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 19:35:20 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[tuts]]></category>
		<category><![CDATA[Custom post types]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[WordPress London]]></category>
		<category><![CDATA[wpldn]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=622</guid>
		<description><![CDATA[Last night I gave a presentation at the WordPress London meetup. I talked about custom post types in WordPress, something that has really excited me since WordPress 3. I&#8217;ve included the video, a rough transcript of the presentation and the slides at the bottom. What we&#8217;ll cover What are custom post types When to use [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I gave a presentation at the WordPress London meetup. I talked about custom post types in WordPress, something that has really excited me since WordPress 3. I&#8217;ve included the video, a rough transcript of the presentation and the slides at the bottom.</p>
<p><iframe width="450" height="253" src="http://www.youtube.com/embed/zQiYLDF9w-g?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<h2>What we&#8217;ll cover</h2>
<div>
<ul id="internal-source-marker_0.5758616640232503">
<li>What are custom post types</li>
<li>When to use them</li>
<li>How to use custom post types</li>
<li>Taking things further</li>
<li>Resources</li>
</ul>
<h2>What are custom post types?</h2>
</div>
<p>I&#8217;ve searched high and low on the internet for a decent definition of custom post types, with no luck. The best that I&#8217;ve seen is that they are really custom <em>content</em> types.</p>
<p>Replacing the word &#8216;posts&#8217; with &#8216;content&#8217; gives us a much better understanding of what custom post types are all about. The idea is that there is some content on your website that might not fit neatly into the typical page&#8217; or &#8216;post&#8217; mould. Think of the following examples:</p>
<ul>
<li>Movies</li>
<li>Staff</li>
<li>Podcasts</li>
<li>Books</li>
<li>Products</li>
<li>Portfolio items</li>
<li>Testimonials, etc, etc.</li>
</ul>
<h3>Then why are they called custom post types?</h3>
<p>Within WordPress there are already various post types: posts, pages, menus and revisions. With version 2.9 came the ability to define your own, &#8216;custom&#8217;, post type. These are stored in the wp_posts table. Hence custom post types.</p>
<h2>When to use custom post types</h2>
<p>Here is a fairly typical client request:</p>
<div>
<blockquote>
<p id="internal-source-marker_0.5758616640232503" dir="ltr">“I want to create a website for my holiday home rentals company. I have a portfolio of 20 properties that I want to be able to manage and update. Each property has the following information:</p>
<ul>
<li>Name</li>
<li>Address</li>
<li>Short intro</li>
<li>Full property description</li>
<li>An image</li>
<li>Price per week</li>
<li>Number of rooms</li>
</ul>
<p dir="ltr">I would like the user to able to sort the properties by ‘Price’ and ‘Number of rooms. I will also be blogging on the site.&#8221;</p>
</blockquote>
</div>
<h3>Without custom post types</h3>
<p>In those dark days before WP 2.9 I probably would have used posts for the properties. I then would have created a category of &#8216;properties&#8217; so that I could style those property posts differently than the regular blog posts. I then would have used custom fields for the meta data &#8211; rooms and price.</p>
<p>This used to work, but it was an ugly solution, a &#8216;hack&#8217;. The property posts would be mixed in with the regular blog posts both in the admin and the front-end.</p>
<h3>Enter, custom post types</h3>
<p>With custom post types we can separate our content into logical groups. Posts are now just chronological blog/news items again and properties have their own section.</p>
<p>This also makes theme development easier. The posts and properties are no longer lumped together, so no need to hack the index.php loop. New templates are available specifically for your properties post type too.</p>
<p>Basically, using custom post types is going to seriously improve workflow for both you and your client.</p>
<h2>How to use custom post types</h2>
<h3>Creating your custom post type</h3>
<p>Before I start, I have to tell you that there are ways to create custom post types on your WordPress site without having to touch a single line of code. There are several plugins and online code generators that will do it all for you. However, I strongly encourage you to have a go at this yourself. Even if this is the first bit of theme development that you have done, give it a go. You&#8217;ll have a much better idea of what&#8217;s going on and you&#8217;ll find it so satisfying.</p>
<p>Open up your theme&#8217;s functions.php file using your favourite text editor, and add the following:</p>
<pre class="brush: php; title: ; notranslate">

add_action( 'init', 'create_my_post_types' );

function create_my_post_types() {
	register_post_type( 'kdev_properties',
		array(
			'labels' =&gt; array(
				'name' =&gt; __( 'Properties' ),
				'singular_name' =&gt; __( 'Property' )
			),
			'public' =&gt; true,
			'has_archive' =&gt; true,
            'supports' =&gt; array('title','editor','excerpt','thumbnail'),
            'rewrite' =&gt; array( 'slug' =&gt; 'property' ),
            'register_meta_box_cb' =&gt; 'add_property_metaboxes',

		)
	);
}
</pre>
<p>This code is all we need to get custom post types working on our WordPress site. in fact, it&#8217;s more than we need, I&#8217;ve added a few lines, 11, 13 and 14, that aren&#8217;t essential but useful for what we&#8217;re trying to achieve.</p>
<p>Line 4 is where the magic starts, we&#8217;re registering our post type and giving it a name. I&#8217;ve prefixed the name with &#8216;kdev_&#8217; to avoid clashes with any other plugins.</p>
<p>Line 6 starts the &#8216;labels&#8217; array and at this point we&#8217;re only using two labels &#8216;name&#8217; and &#8216;singular_name&#8217;. These will appear in our theme instead of the ugly &#8216;kdev_properties&#8217;. There are lots more labelling options, check them out here <a href="http://codex.wordpress.org/Function_Reference/register_post_type#Arguments" target="_blank">http://codex.wordpress.org/Function_Reference/register_post_type#Arguments</a>.</p>
<p>Line 10 is telling WordPress to make the post type public, that is visible, in the admin and front-end. Strangely this defaults to false, so you must include it if you want to see your post type.</p>
<p>&#8216;has_archive&#8217; on line 11 is optional. I&#8217;m using it to tell WordPress that I will be using a custom archive template.</p>
<p>The &#8216;supports&#8217; array on line 12 is where it starts to get interesting. Everything that you are familiar with from posts and pages are available to you here. I&#8217;m just enabling the elements that we&#8217;ll need for our property post type.</p>
<p>Line 13 enables a URL rewrite. This changes our URL structure from kdev_properties/propertyname to property/propertyname (assuming we&#8217;re using a &#8216;pretty&#8217; permalink structure).</p>
<p>The last line, 14, is telling WordPress that I wish to use a custom meta box on this post type. this will be explained in greater detail later on.</p>
<p>Now log in to your WordPress admin area and you should see something similar to the following:</p>
<p style="text-align: center;"><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Properties-added-to-admin-menu.png"><img class="size-medium wp-image-631 aligncenter" title="CPT - Properties added to admin menu" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Properties-added-to-admin-menu-300x220.png" alt="" width="300" height="220" /></a></p>
<p>You can see that our custom post type, &#8216;properties&#8217;, has been added to the main menu, keeping it separate from posts and pages.</p>
<p>If you click on the &#8216;Properties&#8217; link and then &#8216;Add New&#8217; you will get to the following screen.</p>
<p style="text-align: center;"><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Edit-Properties-CPT.png"><img class="size-medium wp-image-632 aligncenter" title="CPT - Edit Properties CPT" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Edit-Properties-CPT-300x203.png" alt="" width="300" height="203" /></a></p>
<p>Here we can see the &#8216;supports&#8217; array in action. We&#8217;ve added some useful functionality here but it&#8217;s also important to note what we&#8217;ve left out. The categories and tags that we are familiar with from posts are gone, as are page attributes, revisions, comments and discussions. This leaves us with a nice clean UI. There are no extraneous admin elements to distract the user.</p>
<p>Our code hasn&#8217;t just created a great admin screen, it&#8217;s also enabled us to view our custom post type live on the site. From the &#8216;Edit Post&#8217; screen, click on &#8216;Preview&#8217; to see what your post will look like (add some content first for a better effect!). You&#8217;ll see something like this:</p>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Property-single.png"><img class="aligncenter size-medium wp-image-637" title="CPT - Property single" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Property-single-300x287.png" alt="" width="300" height="287" /></a></p>
<p>That&#8217;s great so far, but the chances are that you&#8217;ll want your custom post type to look slightly different to regular posts. WordPress gives us two template files to do this; single-[posttype].php and archive-[posttype].php.</p>
<p>The single template will let you style your individual custom post types, in our case the single property page. It&#8217;s often easiest just to create the new template file (e.g. single-kdev_properties.php), in your theme directory, and copy and paste the code from your theme&#8217;s single.php file. Then you can make any changes that you require. Before you do that though, there are some more tricks that will help you make your custom post type really come to life!</p>
<p>The archive-[posttype].php template will create a page that displays a list of your custom posts. Using the same idea as above, you can copy and paste from your index.php file and edit from there. Remember the &#8216;has_archive&#8217; argument that we added? That line is telling WordPress to use our custom archive file.</p>
<p>Congratulations! You&#8217;ve created your first custom post type. That wasn&#8217;t too hard was it? There is loads more that we can do with our custom post type.</p>
<h2>Taking things further</h2>
<p>Remember the original client request? She wanted to be able to add &#8216;price&#8217; and &#8216;number of rooms&#8217; data to her properties. Of course, we could just add this to the main text editor, but then it would be tricky to separate the data if we wanted to use it by itself. This is where custom meta boxes come in.</p>
<h3>Custom meta boxes</h3>
<p>Here&#8217;s where custom post types start to get really cool. We&#8217;re not limited to the &#8216;title&#8217;, &#8216;excerpt&#8217;, etc. that WordPress provides us with. We can add new boxes to our edit screen that accept any kind of data that we can think of.</p>
<p>Here&#8217;s an example of some meta boxes:</p>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Rooms-Meta-Box.png"><img class="alignleft size-full wp-image-638" title="CPT - Rooms Meta Box" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Rooms-Meta-Box.png" alt="" width="239" height="79" /></a></p>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Radio-button-meta-box.png"><img class="alignleft size-full wp-image-639" title="CPT - Radio button meta box" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Radio-button-meta-box.png" alt="" width="241" height="72" /></a></p>
<p>The first meta box is a simple text field, the second a radio button. You could have checkboxes, text-areas, TinyMCEs, etc. By now your imagination should be kicking in to show you the possibilities available!</p>
<p>We want two meta boxes, one for price and one for rooms. Here&#8217;s the code that we need to achieve this:</p>
<pre class="brush: php; title: ; notranslate">

//Add custom meta box

// Add the Properties Meta Boxes

function add_property_metaboxes() {
    add_meta_box('kdev_properties_rooms', 'Number of Rooms', 'kdev_properties_rooms', 'kdev_properties', 'side', 'default');
    add_meta_box('kdev_properties_price', 'Price per week', 'kdev_properties_price', 'kdev_properties', 'side', 'default');
}

// Output the Property metaboxes

function kdev_properties_rooms() {
    global $post;

    $prop_rooms = get_post_meta($post-&gt;ID, '_rooms', true);

    echo '&lt;label&gt;Rooms&lt;/label&gt;&lt;input class=&quot;widefat&quot; name=&quot;_rooms&quot; type=&quot;text&quot; value=&quot;' . $prop_rooms  . '&quot; /&gt;';
}

function kdev_properties_price() {
    global $post;

    $prop_price = get_post_meta($post-&gt;ID, '_price', true);

    echo '&lt;label&gt;Price per week&lt;/label&gt;&lt;input class=&quot;widefat&quot; name=&quot;_price&quot; type=&quot;text&quot; value=&quot;' . $prop_price  . '&quot; /&gt;';
}

// Save the Metabox Data

function kdev_save_property_meta($post_id, $post) {
    if ( 'kdev_properties' == get_post_type() ) {

        if ( !current_user_can( 'edit_post' , $post -&gt;ID )) return $post -&gt;ID;

        $property_meta['_rooms'] = $_POST['_rooms'];
        $property_meta['_price'] = $_POST['_price'];

        foreach ($property_meta as $key =&gt; $value) { // Cycle through the $property_meta array!
            if( $post-&gt;post_type == 'revision' ) return; // Don't store custom data twice
            $value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
            if(get_post_meta($post-&gt;ID, $key, FALSE)) { // If the custom field already has a value
                update_post_meta($post-&gt;ID, $key, $value);
            } else { // If the custom field doesn't have a value
                add_post_meta($post-&gt;ID, $key, $value);
            }
            if(!$value) delete_post_meta($post-&gt;ID, $key); // Delete if blank
        }
    }
}

add_action('save_post', 'kdev_save_property_meta', 1, 2); // save the custom fields
</pre>
<p>This is a bit more complex and I won&#8217;t go through every line. Add this to your functions.php file and make sure that the variable names are correct (if you have used something other than &#8216;kdev_properties you&#8217;ll need to change it here too).</p>
<p>There are some arguments that you may wish to tinker with. Remember, you won&#8217;t learn if you don&#8217;t make mistakes, so don&#8217;t be scared. It&#8217;s always a good idea to make backups before you start experimenting though, especially with a live site.</p>
<p>Adding that code will give you something like this:</p>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Meta-boxes-in-admin.png"><img class="aligncenter size-medium wp-image-640" title="CPT - Meta boxes in admin" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Meta-boxes-in-admin-300x183.png" alt="" width="300" height="183" /></a></p>
<p>Check out those custom meta boxes on the right! Sweet.</p>
<p>As cool as it is to have custom meta boxes, they&#8217;re not going to do anything for you without a bit of work to your template files.</p>
<p>Open up one of your custom template files and add the following:</p>
<pre class="brush: php; title: ; notranslate">

Price per week: £&lt;!--?php echo get_post_meta(get_the_ID(), '_price', true); ?--&gt;

Number of rooms: &lt;!--?php echo get_post_meta(get_the_ID(), '_rooms', true); ?--&gt;
</pre>
<p>The get_post_meta() function is creating all the magic here. It takes a few arguments, the post ID, the meta key, and whether to return a single string or an array (&#8216;true&#8217; will return the string).</p>
<p>I&#8217;ve added those lines to my custom archive template to get the following:</p>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-archive-page.png"><img class="aligncenter size-medium wp-image-641" title="CPT - archive page" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-archive-page-300x255.png" alt="" width="300" height="255" /></a></p>
<p>Nice work. Our custom post types have meta boxes and we have some pretty nifty templates. There&#8217;s one more part to the holy trinity of custom awesomeness&#8230;</p>
<h3>Custom taxonomies</h3>
<p>Taxonomies are ways to classify your data. If you&#8217;re familiar with WordPress you will already be using them; categories and tags. These are both taxonomies, but they are very general, and you&#8217;ll probably want to keep these for your blog posts.</p>
<p>For our custom post types we can create our own custom taxonomies. There are two main types; hierarchical and, erm, not.</p>
<h3>Hierarchical taxonomies</h3>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-hierarchical-tax.png"><img class="aligncenter size-medium wp-image-643" title="CPT - hierarchical tax" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-hierarchical-tax-207x300.png" alt="" width="207" height="300" /></a></p>
<p>Hierarchical taxonomies have the concept of parents and children, like categories. You can create tree like structures of nested classifications.</p>
<h3>Non-hierarchical taxonomies</h3>
<p><a href="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Custom-tax-meta-box.png"><img class="aligncenter size-full wp-image-644" title="CPT - Custom tax meta box" src="http://keithdevon.com/wp-content/uploads/2011/11/CPT-Custom-tax-meta-box.png" alt="" width="241" height="130" /></a></p>
<p>These are like post tags. They don&#8217;t have parents or children.</p>
<h3>Creating a custom taxonomy</h3>
<pre class="brush: php; title: ; notranslate">
function my_register_taxonomies() {

	register_taxonomy(
		'area',
		array( 'kdev_properties' ),
		array(
			'public' =&gt; true,
			'labels' =&gt; array( 'name' =&gt; 'Area', 'singular_name' =&gt; 'Area' ),
			'hierarchical' =&gt; true,
		)
	);
}

add_action( 'init', 'my_register_taxonomies' );
</pre>
<p>This is all we need to create a custom taxonomy for our custom post type. I&#8217;ve given it a name, assigned it to the &#8216;kdev_properties&#8217; post type and given it some arguments. Again, have a play around. The code can be added to your functions.php file as before.</p>
<p>And so we have it. Well done for getting to the end!</p>
<p>Hopefully, you&#8217;ll be inspired to use custom post types on your next project. You&#8217;ll never look back, I promise.</p>
<h2>Resources</h2>
<p>http://codex.wordpress.org/Post_Types</p>
<p>http://codex.wordpress.org/Function_Reference/register_post_type</p>
<h3>Plugins</h3>
<p>http://wordpress.org/extend/plugins/custom-post-type-ui/</p>
<p>http://wordpress.org/extend/plugins/custom-content-type-manager/</p>
<h3>Posts</h3>
<p>http://justintadlock.com/archives/2010/04/29/custom-post-types-in-wordpress</p>
<p>http://devpress.com/blog/conditional-checks-for-custom-post-types/</p>
<p>http://css-tricks.com/forums/discussion/8538/wordpress-3.0-custom-post-types-and-meta-boxes/</p>
<h3>Easy meta boxes with WPAlchemy</h3>
<p>http://www.farinspace.com/wpalchemy-metabox/</p>
<h2>The slides</h2>
<div id="__ss_10235699" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a title="Custom post types - WordPress" href="http://www.slideshare.net/keithdevon/custom-post-types-wordpress">Custom post types &#8211; WordPress</a></strong><object id="__sse10235699" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=customposttypes-111119133139-phpapp01&amp;stripped_title=custom-post-types-wordpress&amp;userName=keithdevon" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="wmode" value="transparent" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=customposttypes-111119133139-phpapp01&amp;stripped_title=custom-post-types-wordpress&amp;userName=keithdevon" name="__sse10235699" allowscriptaccess="always" allowfullscreen="true" wmode="transparent"></embed></object>&nbsp;</p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/keithdevon">keithdevon</a>.</div>
</div>
<p><script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script><br />
<script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script></p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/tuts/custom-post-types/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>WordPress London meetup #5</title>
		<link>http://keithdevon.com/2011/news/wordpress-london-meetup-5/</link>
		<comments>http://keithdevon.com/2011/news/wordpress-london-meetup-5/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 09:46:28 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[BuddyPress]]></category>
		<category><![CDATA[SOLR]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[WordPress London]]></category>
		<category><![CDATA[WP E-commerce]]></category>

		<guid isPermaLink="false">http://keithdevon.com/2011/uncategorized/wordpress-london-meetup-5/</guid>
		<description><![CDATA[The group continues to go from strength to strength with at least 30 members attending. This month&#8217;s meetup included a talk from BuddyPress developer Paul Gibbs. He talks us through the new release, the epic version 1.5. Paul&#8217;s blog post, with slides, can be found here: http://byotos.com/2011/09/27/buddypress-at-wordpress-london-220911/. Then Jeff Ghazally shows us how easy it us [...]]]></description>
			<content:encoded><![CDATA[<p>The group continues to go from strength to strength with at least 30 members attending.</p>
<p>This month&#8217;s meetup included a talk from BuddyPress developer Paul Gibbs. He talks us through the new release, the epic version 1.5.</p>
<p><object width="450" height="253"><param name="movie" value="http://www.youtube.com/v/K3RksDBTFu0?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/K3RksDBTFu0?version=3" type="application/x-shockwave-flash" width="450" height="253" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Paul&#8217;s blog post, with slides, can be found here: http://byotos.com/2011/09/27/buddypress-at-wordpress-london-220911/.</p>
<p>Then Jeff Ghazally shows us how easy it us to sell music online using WordPress and the WP E-commerce plugin.</p>
<p><object width="450" height="253"><param name="movie" value="http://www.youtube.com/v/uKGySSU09jI?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/uKGySSU09jI?version=3" type="application/x-shockwave-flash" width="450" height="253" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>We also had a great presentation from Shakur about the SOLR search plugin and how it can be used to improve the search performance and capabilities on your WordPress site. Unfortunately due to technical difficulties (an over-heated camera!) we didn&#8217;t get this one on video. Sorry Shaksi!</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/news/wordpress-london-meetup-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Circuit of Kent Transport</title>
		<link>http://keithdevon.com/2011/stuff/circuit-of-kent-transport/</link>
		<comments>http://keithdevon.com/2011/stuff/circuit-of-kent-transport/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 08:48:01 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=612</guid>
		<description><![CDATA[Transport from London I&#8217;m looking for someone to carpool with for the Circuit of Kent on the 11th September 2011. I live in Wapping, London. If anyone has a space in a car or minibus, please get in touch. I&#8217;m very happy to pay for fuel, etc. Please email me at keith@keithdevon.com. Cheers, Keith]]></description>
			<content:encoded><![CDATA[<h3>Transport from London</h3>
<p>I&#8217;m looking for someone to carpool with for the Circuit of Kent on the 11th September 2011.</p>
<p>I live in Wapping, London. If anyone has a space in a car or minibus, please get in touch. I&#8217;m very happy to pay for fuel, etc.</p>
<p>Please email me at keith@keithdevon.com.</p>
<p>Cheers,</p>
<p>Keith</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/stuff/circuit-of-kent-transport/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protected: ArtPress Alpha</title>
		<link>http://keithdevon.com/2011/stuff/artpress-alpha/</link>
		<comments>http://keithdevon.com/2011/stuff/artpress-alpha/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 15:00:01 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=607</guid>
		<description><![CDATA[There is no excerpt because this is a protected post.]]></description>
			<content:encoded><![CDATA[<form action="http://keithdevon.com/wp-pass.php" method="post">
<p>This post is password protected. To view it please enter your password below:</p>
<p><label for="pwbox-607">Password:<br />
<input name="post_password" id="pwbox-607" type="password" size="20" /></label><br />
<input type="submit" name="Submit" value="Submit" /></p></form>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/stuff/artpress-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beginner WordPress Theme Development</title>
		<link>http://keithdevon.com/2011/news/beginner-wordpress-theme-development/</link>
		<comments>http://keithdevon.com/2011/news/beginner-wordpress-theme-development/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 09:49:35 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Child Themes]]></category>
		<category><![CDATA[LDNWP]]></category>
		<category><![CDATA[Template Hierarchy]]></category>
		<category><![CDATA[The Loop]]></category>
		<category><![CDATA[Theme Development]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[WP]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=599</guid>
		<description><![CDATA[Last Thursday (28th July 2011) we held the third London WordPress meetup. The meetup is for WordPress users and professionals in London and aims to provide a networking and learning platform. I gave a talk on Beginner WordPress Theme Development, which introduced the basic structure of a theme and some key concepts. Here are the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://keithdevon.com/wp-content/uploads/2011/08/Meetup-Photo.jpeg"><img class="alignleft size-thumbnail wp-image-600" title="Meetup Photo" src="http://keithdevon.com/wp-content/uploads/2011/08/Meetup-Photo-272x204.jpg" alt="" width="272" height="204" /></a>Last Thursday (28th July 2011) we held the third <a title="London WordPress meetup" href="http://www.meetup.com/London-WordPress/">London WordPress</a> meetup. The meetup is for WordPress users and professionals in London and aims to provide a networking and learning platform.</p>
<p>I gave a talk on Beginner WordPress Theme Development, which introduced the basic structure of a theme and some key concepts. Here are the presentation <a title="Beginner WordPress Theme Development - Prezi" href="http://bit.ly/nqOHya">&#8216;slides&#8217;</a> and the <a title="Beginner WordPress Theme Development - YouTube video" href="http://youtu.be/XZNp-NiXf_E">video</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/news/beginner-wordpress-theme-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Custom Image Size Problem</title>
		<link>http://keithdevon.com/2011/stuff/the-custom-image-size-problem/</link>
		<comments>http://keithdevon.com/2011/stuff/the-custom-image-size-problem/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 10:47:06 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=596</guid>
		<description><![CDATA[I&#8217;m building a WordPress theme where I use custom thumbnail sizes. I use the filter add_image_size( 'Gallery list', 350, 200, true ); That works fine until I edit the original image in WordPress. For example, I&#8217;ve rotated a few of the images. When I click on the thumbnail it takes me to the now corrected [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m building a WordPress theme where I use custom thumbnail sizes. I use the filter</p>
<pre>add_image_size( 'Gallery list', 350, 200, true );</pre>
<p>That works fine until I edit the original image in WordPress. For example, I&#8217;ve rotated a few of the images. When I click on the thumbnail it takes me to the now corrected image, however the thumbnail itself is as it was.</p>
<p>Do I need to regenerate these thumbnails? Is there a way to do this automatically after editing the image?</p>
<p>Thanks for your help.</p>
<p>Keith</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/stuff/the-custom-image-size-problem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Proper float clearing</title>
		<link>http://keithdevon.com/2011/tuts/proper-float-clearing/</link>
		<comments>http://keithdevon.com/2011/tuts/proper-float-clearing/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 13:37:37 +0000</pubDate>
		<dc:creator>kdev</dc:creator>
				<category><![CDATA[tuts]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://keithdevon.com/?p=567</guid>
		<description><![CDATA[I was browsing through Forrst recently and happened across the following advice on float clearing. An easy way to properly clear floats without extra markup. If you&#8217;re not using some sort of clearfix you probably should be. .clearself:before, .clearself:after { content: " "; display: block; height: 0; overflow: hidden; } .clearself:after {clear: both;} .clearself {zoom: [...]]]></description>
			<content:encoded><![CDATA[<p>I was browsing through Forrst recently and happened across the following advice on float clearing.</p>
<blockquote><p>An easy way to properly clear floats without extra markup. If you&#8217;re not using some sort of clearfix you probably should be.</p></blockquote>
<p><code>.clearself:before,<br />
.clearself:after {<br />
content: " ";<br />
display: block;<br />
height: 0;<br />
overflow: hidden;<br />
}<br />
.clearself:after {clear: both;}<br />
.clearself {zoom: 1;} /* IE &lt; 8 */</code></p>
<p>This looks like a great way of reducing design related markup in your HTML. What do you think? Have you tried this technique before?</p>
<p>The original post is <a href="http://forrst.com/posts/Proper_Float_Clearing-Y6S">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://keithdevon.com/2011/tuts/proper-float-clearing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

