<?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>Justin Tadlock &#187; WordPress Tutorials</title>
	<atom:link href="http://justintadlock.com/tags/wordpress-tutorials/feed" rel="self" type="application/rss+xml" />
	<link>http://justintadlock.com</link>
	<description>Life, Blogging, and WordPress</description>
	<lastBuildDate>Mon, 06 Feb 2012 18:39:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Custom user taxonomies in WordPress</title>
		<link>http://justintadlock.com/archives/2011/10/20/custom-user-taxonomies-in-wordpress</link>
		<comments>http://justintadlock.com/archives/2011/10/20/custom-user-taxonomies-in-wordpress#comments</comments>
		<pubDate>Thu, 20 Oct 2011 18:45:31 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=4267</guid>
		<description><![CDATA[How to create, manage, and use a custom taxonomy for users (not posts) in WordPress.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re at all familiar with taxonomies in WordPress, you already know how awesome it is to add custom taxonomies to your posts or custom post types.  WordPress developers have known this for a while.</p>
<p>What many people don&#8217;t know is that the current taxonomy schema was added way <a href="http://ryan.boren.me/2007/08/26/wordpress-23-taxonomy-schema/" title="WordPress 2.3 taxonomy schema">back in WordPress 2.3</a>.  Yes, that means the ability to create and use custom taxonomies has been around since 2007.  We didn&#8217;t get all the cool functions added until 2.8 though.</p>
<p>However, one thing we&#8217;ve had since 2.3 was the ability to create taxonomies for any object type, not just posts.  In WordPress, there are several object types:</p>
<ul>
<li>Posts</li>
<li>Users</li>
<li>Comments</li>
<li>Links</li>
</ul>
<p>So, you can technically create a taxonomy for any object type.  Most of WordPress core support is for posts, but the API is extremely well thought out and can handle the other object types with minimal code effort.</p>
<p>This tutorial will focus on registering and using a taxonomy on the user object type.  It will not be a 100% solution for everything you can do with a custom user taxonomy.  Consider this an extremely rough draft of what&#8217;s possible.</p>
<p>Because this is such an in-depth topic, I cannot explain every minute detail.  That would make for about a 50-page tutorial.  You&#8217;ll need to be familiar with a few key areas in WordPress development before proceeding:  plugins, themes, users, and taxonomies.</p>
<h2>Registering a user taxonomy</h2>
<p>In this tutorial, you will use and register a taxonomy called &#8220;Profession.&#8221;  This is just an example, so feel free to experiment and create your own taxonomies for your uses.</p>
<p>To register the user taxonomy, you use the <a href="http://codex.wordpress.org/Function_Reference/register_taxonomy" title="WordPress Codex: register_taxonomy()">register_taxonomy()</a> function just like you would with any other taxonomy.  The following code block will register the profession taxonomy and set up its arguments.</p>
<pre><code>/**
 * Registers the 'profession' taxonomy for users.  This is a taxonomy for the 'user' object type rather than a
 * post being the object type.
 */
function my_register_user_taxonomy() {

	 register_taxonomy(
		'profession',
		'user',
		array(
			'public' => true,
			'labels' => array(
				'name' => __( 'Professions' ),
				'singular_name' => __( 'Profession' ),
				'menu_name' => __( 'Professions' ),
				'search_items' => __( 'Search Professions' ),
				'popular_items' => __( 'Popular Professions' ),
				'all_items' => __( 'All Professions' ),
				'edit_item' => __( 'Edit Profession' ),
				'update_item' => __( 'Update Profession' ),
				'add_new_item' => __( 'Add New Profession' ),
				'new_item_name' => __( 'New Profession Name' ),
				'separate_items_with_commas' => __( 'Separate professions with commas' ),
				'add_or_remove_items' => __( 'Add or remove professions' ),
				'choose_from_most_used' => __( 'Choose from the most popular professions' ),
			),
			'rewrite' => array(
				'with_front' => true,
				'slug' => 'author/profession' // Use 'author' (default WP user slug).
			),
			'capabilities' => array(
				'manage_terms' => 'edit_users', // Using 'edit_users' cap to keep this simple.
				'edit_terms'   => 'edit_users',
				'delete_terms' => 'edit_users',
				'assign_terms' => 'read',
			),
			'update_count_callback' => 'my_update_profession_count' // Use a custom function to update the count.
		)
	);
}</code></pre>
<p>I won&#8217;t cover all the arguments used in the code above.  I&#8217;ve written about those in a <a href="http://justintadlock.com/archives/2010/06/10/a-refresher-on-custom-taxonomies" title="A refresher on custom taxonomies">previous tutorial</a>.  However, there are a few arguments you should pay careful attention to:</p>
<ul>
<li><strong>rewrite['slug']:</strong>  I used <code>author/profession</code> so that the slug would fall in line with the WordPress user slug, <code>author</code>.  We&#8217;ll need a slight fix for this too, which I&#8217;ll get to later in the tutorial.</li>
<li><strong>capabilities:</strong>  For simplicity, I&#8217;ve set most of the capabilities to <code>edit_users</code>.  Only administrators can manage, edit, and delete professions with this by default.  The <code>assign_terms</code> capability is set to <code>read</code> so all users can edit this on their profile page.  You&#8217;ll want to set up some custom capabilities or configure this to do what you want.</li>
<li><strong>update_count_callback:</strong>  You must use a custom function for this because WordPress expects the taxonomy to be for the post object type.</li>
</ul>
<p>Once you&#8217;ve registered your taxonomy, WordPress really doesn&#8217;t do much for you.  It won&#8217;t add any custom admin pages, meta boxes, or anything of the sort like it does for posts.  That&#8217;ll be left up to you.</p>
<h2>Custom term update count callback</h2>
<p>Right off the bat, you&#8217;ll already need some custom code.  Since WordPress will only update the term counts for taxonomies on posts, you&#8217;ll need a function to do this for users.</p>
<p>When you registered your taxonomy, you set the <code>update_count_callback</code> argument to <code>my_update_profession_count</code>.  The following code is that callback function.</p>
<pre><code>/**
 * Function for updating the 'profession' taxonomy count.  What this does is update the count of a specific term
 * by the number of users that have been given the term.  We're not doing any checks for users specifically here.
 * We're just updating the count with no specifics for simplicity.
 *
 * See the _update_post_term_count() function in WordPress for more info.
 *
 * @param array $terms List of Term taxonomy IDs
 * @param object $taxonomy Current taxonomy object of terms
 */
function my_update_profession_count( $terms, $taxonomy ) {
	global $wpdb;

	foreach ( (array) $terms as $term ) {

		$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term ) );

		do_action( 'edit_term_taxonomy', $term, $taxonomy );
		$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
		do_action( 'edited_term_taxonomy', $term, $taxonomy );
	}
}</code></pre>
<p>I just kept this extremely simple and modified the <code>_update_post_term_count()</code> WordPress function.  Feel free to further modify it to suit your needs.</p>
<h2>Creating the manage terms page</h2>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/10/manage-professions.png" alt="Manage user taxonomy terms admin page" title="Custom user taxonomy admin page" width="600" height="341" class="aligncenter size-full wp-image-4272" /></p>
<p>Since WordPress does not create an admin page for managing terms of custom user taxonomies, you&#8217;ll need to create that.  For the sake of simplicity and laziness, I just used the admin page WordPress already uses for other taxonomies.  </p>
<p>The problem with this is that WordPress doesn&#8217;t recognize that the &#8220;Professions&#8221; admin page is a sub-menu of the &#8220;Users&#8221; admin page when viewing it.  The sub-menu is placed correctly, but when clicking on it, the &#8220;Posts&#8221; menu is opened in the admin.  I&#8217;d really love to see some WordPress core support for this.</p>
<p class="alert"><strong>Update:</strong>  See the <a href="http://justintadlock.com/archives/2011/10/20/custom-user-taxonomies-in-wordpress#comment-568682">comment by James</a> below to get a fix for this.</p>
<p>The following code is what I used, but you can definitely create a custom admin page for managing your terms.</p>
<pre><code>/* Adds the taxonomy page in the admin. */
add_action( 'admin_menu', 'my_add_profession_admin_page' );

/**
 * Creates the admin page for the 'profession' taxonomy under the 'Users' menu.  It works the same as any
 * other taxonomy page in the admin.  However, this is kind of hacky and is meant as a quick solution.  When
 * clicking on the menu item in the admin, WordPress' menu system thinks you're viewing something under 'Posts'
 * instead of 'Users'.  We really need WP core support for this.
 */
function my_add_profession_admin_page() {

	$tax = get_taxonomy( 'profession' );

	add_users_page(
		esc_attr( $tax->labels->menu_name ),
		esc_attr( $tax->labels->menu_name ),
		$tax->cap->manage_terms,
		'edit-tags.php?taxonomy=' . $tax->name
	);
}</code></pre>
<p>This will at least allow you to create and manage custom terms of the profession taxonomy.  If you have a better solution for this, please post it in the comments for other people to see.</p>
<h3>Fixing the &#8220;Posts&#8221; column</h3>
<p>After creating the admin page, you probably noticed a column on it called &#8220;Posts.&#8221;  Instead, it should display a &#8220;Users&#8221; column.  The following code will fix this issue and list the number of users with each term from the profession taxonomy.</p>
<pre><code>/* Create custom columns for the manage profession page. */
add_filter( 'manage_edit-profession_columns', 'my_manage_profession_user_column' );

/**
 * Unsets the 'posts' column and adds a 'users' column on the manage profession admin page.
 *
 * @param array $columns An array of columns to be shown in the manage terms table.
 */
function my_manage_profession_user_column( $columns ) {

	unset( $columns['posts'] );

	$columns['users'] = __( 'Users' );

	return $columns;
}

/* Customize the output of the custom column on the manage professions page. */
add_action( 'manage_profession_custom_column', 'my_manage_profession_column', 10, 3 );

/**
 * Displays content for custom columns on the manage professions page in the admin.
 *
 * @param string $display WP just passes an empty string here.
 * @param string $column The name of the custom column.
 * @param int $term_id The ID of the term being displayed in the table.
 */
function my_manage_profession_column( $display, $column, $term_id ) {

	if ( 'users' === $column ) {
		$term = get_term( $term_id, 'profession' );
		echo $term->count;
	}
}</code></pre>
<h2>Assigning terms to users</h2>
<p>Thus far, you&#8217;ve got a custom taxonomy and can add terms for it, but you need a way to assign these terms to individual users.  For this example, you&#8217;ll be adding a custom section to the edit user/profile page in the admin.  It will display a list of radio select boxes so the user can choose their profession.</p>
<p>This is just an extremely basic example.  You have tons of room for customization.  You can do select elements, checkboxes, a text input, or whatever best works for you.</p>
<p>The following PHP code will add this section to the edit user/profile page.</p>
<pre><code>/* Add section to the edit user page in the admin to select profession. */
add_action( 'show_user_profile', 'my_edit_user_profession_section' );
add_action( 'edit_user_profile', 'my_edit_user_profession_section' );

/**
 * Adds an additional settings section on the edit user/profile page in the admin.  This section allows users to
 * select a profession from a checkbox of terms from the profession taxonomy.  This is just one example of
 * many ways this can be handled.
 *
 * @param object $user The user object currently being edited.
 */
function my_edit_user_profession_section( $user ) {

	$tax = get_taxonomy( 'profession' );

	/* Make sure the user can assign terms of the profession taxonomy before proceeding. */
	if ( !current_user_can( $tax->cap->assign_terms ) )
		return;

	/* Get the terms of the 'profession' taxonomy. */
	$terms = get_terms( 'profession', array( 'hide_empty' => false ) ); ?>

	&lt;h3>&lt;?php _e( 'Profession' ); ?>&lt;/h3>

	&lt;table class="form-table">

		&lt;tr>
			&lt;th>&lt;label for="profession">&lt;?php _e( 'Select Profession' ); ?>&lt;/label>&lt;/th>

			&lt;td>&lt;?php

			/* If there are any profession terms, loop through them and display checkboxes. */
			if ( !empty( $terms ) ) {

				foreach ( $terms as $term ) { ?>
					&lt;input type="radio" name="profession" id="profession-&lt;?php echo esc_attr( $term->slug ); ?>" value="&lt;?php echo esc_attr( $term->slug ); ?>" &lt;?php checked( true, is_object_in_term( $user->ID, 'profession', $term ) ); ?> /> &lt;label for="profession-&lt;?php echo esc_attr( $term->slug ); ?>">&lt;?php echo $term->name; ?>&lt;/label> &lt;br />
				&lt;?php }
			}

			/* If there are no profession terms, display a message. */
			else {
				_e( 'There are no professions available.' );
			}

			?>&lt;/td>
		&lt;/tr>

	&lt;/table>
&lt;?php }</code></pre>
<p>After adding the preceding code, you&#8217;ll get a new section near the bottom of your edit user/profile page that looks like the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/10/edit-user-profession.png" alt="Assigning taxonomy terms on user profile page" title="Edit user profile with taxonomy" width="600" height="191" class="aligncenter size-full wp-image-4272" /></p>
<p>You&#8217;ll need a way to save the selected term (profession) for the user.  The next code block will handle that.</p>
<pre><code>/* Update the profession terms when the edit user page is updated. */
add_action( 'personal_options_update', 'my_save_user_profession_terms' );
add_action( 'edit_user_profile_update', 'my_save_user_profession_terms' );

/**
 * Saves the term selected on the edit user/profile page in the admin. This function is triggered when the page
 * is updated.  We just grab the posted data and use wp_set_object_terms() to save it.
 *
 * @param int $user_id The ID of the user to save the terms for.
 */
function my_save_user_profession_terms( $user_id ) {

	$tax = get_taxonomy( 'profession' );

	/* Make sure the current user can edit the user and assign terms before proceeding. */
	if ( !current_user_can( 'edit_user', $user_id ) &#038;&#038; current_user_can( $tax->cap->assign_terms ) )
		return false;

	$term = esc_attr( $_POST['profession'] );

	/* Sets the terms (we're just using a single term) for the user. */
	wp_set_object_terms( $user_id, array( $term ), 'profession', false);

	clean_object_term_cache( $user_id, 'profession' );
}</code></pre>
<h2>Displaying user taxonomy terms</h2>
<p>You can use any of the standard WordPress taxonomy functions for listing out your terms.  For example, <a href="http://codex.wordpress.org/Function_Reference/wp_list_categories" title="WordPress Codex: wp_list_categories()">wp_list_categories()</a> and <a href="http://codex.wordpress.org/Function_Reference/wp_tag_cloud" title="WordPress Codex: wp_tag_cloud()">wp_tag_cloud()</a> will both work fine.  Each will link to the term archive page (covered in the section below).</p>
<p>If you wanted to show a tag cloud with all of your &#8220;professions&#8221; (profession cloud) in a theme template, your code would look something like the following.</p>
<pre><code>&lt;?php wp_tag_cloud( array( 'taxonomy' => 'profession' ) ); ?></code></pre>
<p>One thing to look out for though is that the <code>title</code> attribute for links in the tag cloud will read &#8220;1 topic&#8221; or &#8220;X topics.&#8221;  An easy way to change this is to write a custom callback function to modify the text.  In the following screenshot, you can see this changed from &#8220;topics&#8221; to &#8220;users&#8221;.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/10/user-term-tooltip.png" alt="Tooltip changed to &#039;users&#039; on term archive link" title="Topic count callback tooltip" width="600" height="120" class="aligncenter size-full wp-image-4271" /></p>
<p>The following code block is a function that will handle that.</p>
<pre><code>/**
 * Function for outputting the correct text in a tag cloud.  Use as the 'update_topic_count_callback' argument
 * when calling wp_tag_cloud().  Instead of 'topics' it displays 'users'.
 *
 * @param int $count The count of the objects for the term.
 */
function my_profession_count_text( $count ) {
	return sprintf( _n('%s user', '%s users', $count ), number_format_i18n( $count ) );
}</code></pre>
<p>You&#8217;d use it when displaying your tag cloud like so:</p>
<pre><code>&lt;?php wp_tag_cloud(
	array(
		'taxonomy' => 'profession',
		'topic_count_text_callback' => 'my_profession_count_text'
	)
); ?></code></pre>
<h2>Templates for term archives</h2>
<p><a href="http://justintadlock.com/blog/wp-content/uploads/2011/10/user-tax-screenshot.png"><img src="http://justintadlock.com/blog/wp-content/uploads/2011/10/user-tax-screenshot-265x300.png" alt="User taxonomy archive page" title="Term archive page of users" width="265" height="300" class="alignright size-medium wp-image-4270" /></a></p>
<p>The <a href="http://codex.wordpress.org/Template_Hierarchy#Custom_Taxonomies_display" title="WordPress Codex: Template Hierarchy: Taxonomy">template for term archives</a> is handled the same as any other taxonomy.  So, if you wanted to create a custom template (you probably should) for your theme to display users by profession, you&#8217;ll want to create a template named <code>taxonomy-profession.php</code>.</p>
<p>I won&#8217;t cover creating theme templates here.  It&#8217;s outside the scope of this tutorial.  </p>
<p>The big difference between this template and a normal template is there&#8217;s no post loop.  Instead, you need to create a user loop.  The following code should replace your normal post loop in this template.</p>
<pre><code>&lt;?php
$term_id = get_queried_object_id();
$term = get_queried_object();

$users = get_objects_in_term( $term_id, $term->taxonomy );

if ( !empty( $users ) ) {
?>
	&lt;?php foreach ( $users as $user_id ) { ?>

		&lt;div class="user-entry">
			&lt;?php echo get_avatar( get_the_author_meta( 'email', $user_id ), '96' ); ?>
			&lt;h2 class="user-title">&lt;a href="&lt;?php echo esc_url( get_author_posts_url( $user_id ) ); ?>">&lt;?php the_author_meta( 'display_name', $user_id ); ?>&lt;/a>&lt;/h2>

			&lt;div class="description">
				&lt;?php echo wpautop( get_the_author_meta( 'description', $user_id ) ); ?>
			&lt;/div>
		&lt;/div>

	&lt;?php } ?>
&lt;?php } ?></code></pre>
<p>The most important function used in the code above is the WordPress <a href="http://codex.wordpress.org/Function_Reference/get_objects_in_term" title="WordPress Codex: get_objects_in_term()">get_objects_in_term()</a> function.  By putting in a term ID and taxonomy name, you can grab an array of all the object (user) IDs with that term (profession).  With the user ID, you can load any information about a user you want with any standard WordPress functions.</p>
<p>Of course, you&#8217;re free to customize this however you want.  The preceding code merely loops through each of the users with a specific profession.  It then displays each user&#8217;s avatar, name with a link to their posts archive, and description.</p>
<h2>Disabling the &#8216;profession&#8217; username</h2>
<p>When you registered the profession taxonomy, you created the slug <code>author/profession</code> so that the profession archive pages would have a URL like <code>yoursite.com/author/profession/designer</code>.  The problem with this that &#8220;profession&#8221; could potentially be a username someone signs up to your site with.</p>
<p>The following code will make sure no one can sign up with this username:</p>
<pre><code>/* Filter the 'sanitize_user' to disable username. */
add_filter( 'sanitize_user', 'my_disable_username' );

/**
 * Disables the 'profession' username when someone registers.  This is to avoid any conflicts with the custom
 * 'author/profession' slug used for the 'rewrite' argument when registering the 'profession' taxonomy.  This
 * will cause WordPress to output an error that the username is invalid if it matches 'profession'.
 *
 * @param string $username The username of the user before registration is complete.
 */
function my_disable_username( $username ) {

	if ( 'profession' === $username )
		$username = '';

	return $username;
}</code></pre>
<p>Of course, if you use a different rewrite structure for your taxonomy, don&#8217;t worry about that code.</p>
<h2>Time to create your own user taxonomies</h2>
<p>Whoah!  That was certainly a ton of information to cover in a single tutorial.  I&#8217;m sure some of you have questions, so please ask away in the comments.</p>
<p>Now it&#8217;s time for you to venture out on your own and create some cool stuff.  I&#8217;d love to hear what ideas you have and see any projects that you use this code in.  I&#8217;m definitely interested in seeing some practical, real-world use cases of user taxonomies.</p>
<p>One final note:  The code in this tutorial is just something I played around with in about a two-hour span.  It&#8217;s still a work in progress.  Honestly, it took me much longer to write this tutorial.  Therefore, I leave it up to you, dear reader, to improve upon the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/10/20/custom-user-taxonomies-in-wordpress/feed</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>How to create custom post meta boxes</title>
		<link>http://justintadlock.com/archives/2011/10/06/how-to-create-custom-post-meta-boxes</link>
		<comments>http://justintadlock.com/archives/2011/10/06/how-to-create-custom-post-meta-boxes#comments</comments>
		<pubDate>Thu, 06 Oct 2011 20:40:05 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://justintadlock.com/?p=3226</guid>
		<description><![CDATA[My first post on Smashing WordPress is up: How to create custom post meta boxes.]]></description>
			<content:encoded><![CDATA[<p>My first post on Smashing WordPress is up: <a href="http://wp.smashingmagazine.com/2011/10/04/create-custom-post-meta-boxes-wordpress/" title="How to create custom post meta boxes: Smashing Magazine">How to create custom post meta boxes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/10/06/how-to-create-custom-post-meta-boxes/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Creating basic theme templates</title>
		<link>http://justintadlock.com/archives/2011/09/28/creating-basic-theme-templates</link>
		<comments>http://justintadlock.com/archives/2011/09/28/creating-basic-theme-templates#comments</comments>
		<pubDate>Wed, 28 Sep 2011 16:21:18 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[I wanna be a theme designer]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=4023</guid>
		<description><![CDATA[Part #3 in the "I wanna be a theme designer" series, which teaches you how to create basic WordPress theme templates.]]></description>
			<content:encoded><![CDATA[<p>Now that you&#8217;ve already learned how to <a href="http://justintadlock.com/archives/2011/09/20/i-wanna-be-a-theme-designer-theme-setup" title="Theme setup">set up a theme</a>, you&#8217;ll need to learn how to structure a theme.</p>
<p>If you haven&#8217;t already done so, you need to read through the earlier posts in this <a href="http://justintadlock.com/tags/i-wanna-be-a-theme-designer/" title="I wanna be a theme designer series">tutorial series</a> to do some catching up.  From this point forward, you&#8217;ll be expected to know the lessons taught in previous tutorials.</p>
<h2>Basic template structure</h2>
<p>Most WordPress themes will have a few basic templates that define the overall structure of the theme:</p>
<ul>
<li><code>index.php</code></li>
<li><code>header.php</code></li>
<li><code>footer.php</code></li>
<li><code>sidebar.php</code></li>
</ul>
<p>The following screenshot shows a simple overview of what these templates might look like in a finished theme design.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/09/basic-template-structure.png" alt="Basic template structure of a WordPress theme" title="Basic template structure" width="600" height="520" class="aligncenter size-full wp-image-4025" /></p>
<h2>What are templates?</h2>
<p>The term &#8220;template&#8221; can be a bit confusing, especially since it&#8217;s easily interchangeable with the terms &#8220;theme&#8221; and &#8220;skin.&#8221;  In WordPress it means something different.  A template in WordPress is a PHP file that is used for the display of content on the front end of the site.</p>
<p>For those of you familiar with creating HTML Web pages, you&#8217;re probably accustomed to creating a single HTML file and having it display all of the content on the page.  In WordPress, each part of the page is broken into separate sections.  The reason for this is that WordPress is a dynamic system, which runs an entire Web site rather than just a single page.  </p>
<p>Having the templates separated allows you to re-use templates across different page views.  For example, the <code>header.php</code> file contains all of the content the header of a site would display.  Instead of creating many files with the same header information over and over, you can use a single file (template) to display this information on all pages.</p>
<h2>index.php</h2>
<p>The <code>index.php</code> template is the default template for displaying content (blog posts, pages, etc.) on a site.  There are other files that can overwrite it, but you&#8217;ll learn about those in a later tutorial.  For now, you&#8217;ll learn about its most important function:  holding everything together.  </p>
<p>When any page on a WordPress site is loaded, it looks for a template.  In our case, this is the <code>index.php</code> template.  It will be the template that&#8217;s expected to display the page.</p>
<p>In <a href="http://justintadlock.com/archives/2011/09/20/i-wanna-be-a-theme-designer-theme-setup" title="Theme setup">part 1</a> of this tutorial series, you created an empty <code>index.php</code> file.  You need to open this file in your text editor.  Type the following code in this file.</p>
<pre><code>&lt;?php get_header(); // Load the header.php template. ?>

&lt;div id="content">

&lt;/div>&lt;!-- #content -->

&lt;?php get_footer(); // Load the footer.php template. ?></code></pre>
<p>This code does several things:</p>
<ul>
<li>Uses the WordPress function <a href="http://codex.wordpress.org/Function_Reference/get_header" title="WordPress Codex: get_header()">get_header()</a> to load the <code>header.php</code> template.</li>
<li>Defines some basic HTML for the structure of our future content.</li>
<li>Uses the WordPress function <a href="http://codex.wordpress.org/Function_Reference/get_footer" title="WordPress Codex: get_footer()">get_footer()</a> to load the <code>footer.php</code> template.</li>
</ul>
<p>Don&#8217;t worry if you don&#8217;t understand those PHP functions.  You&#8217;ll learn more about them in the next tutorials.</p>
<h2>header.php</h2>
<p>In the previous section, you used a PHP function called <code>get_header()</code> to load a template called <code>header.php</code>.  Since this file doesn&#8217;t exist yet, you&#8217;ll need to create it.  So, create a new file using your text editor called <code>header.php</code> and save it within your theme folder.  </p>
<p>Remember, your theme folder&#8217;s name is <code>super-mario</code>, so the files in your theme should look like the following at this point.</p>
<ul>
<li><code>super-mario</code>
<ul>
<li><code>header.php</code></li>
<li><code>index.php</code></li>
<li><code>style.css</code></li>
</ul>
</li>
</ul>
<p>Once you&#8217;ve created your <code>header.php</code> template, type the following code into it.</p>
<pre><code>&lt;!DOCTYPE html>
&lt;html>
&lt;head>

&lt;title>Example&lt;/title>

&lt;link rel="stylesheet" href="style.css" type="text/css" media="all" />

&lt;/head>

&lt;body class="wordpress">

	&lt;div id="container">

		&lt;div id="header">

		&lt;/div>&lt;!-- #header -->

		&lt;div id="main"></code></pre>
<p>What the preceding code does is define a simple HTML structure for your header.  Those of you familiar with basic Web pages and HTML, this should look familiar to you.  There&#8217;s no PHP code involved at all at this point for the header.  You&#8217;ll learn about that later.</p>
<h2>footer.php</h2>
<p>The footer template should close out all open HTML tags that were opened in the header template.  </p>
<p>In the <code>index.php</code> section of this tutorial, you used the <code>get_footer()</code> function to load the <code>footer.php</code> template.  Just as you did with the header template, create a new file with your text editor called <code>footer.php</code> and place it within your theme folder.</p>
<p>Now, type the following code into the file.</p>
<pre><code>			&lt;?php get_sidebar(); // Load the sidebar.php template. ?>

		&lt;/div>&lt;!-- #main -->

		&lt;div id="footer">

		&lt;/div>&lt;!-- #footer -->

	&lt;/div>&lt;!-- #container -->

&lt;/body>
&lt;/html></code></pre>
<p>As you can see, these are mostly all closing HTML tags.  You probably also noticed the PHP function call to <a href="http://codex.wordpress.org/Function_Reference/get_sidebar" title="WordPress Codex: get_sidebar()">get_sidebar()</a>, which is a WordPress function for loading the <code>sidebar.php</code> template.</p>
<h2>sidebar.php</h2>
<p>A sidebar is a template in WordPress for displaying content in addition to the main page content.  For now, you&#8217;ll just be building the basic HTML structure for a single sidebar.</p>
<p>Once again, crack open your favorite text editor.  This time, create a new file called <code>sidebar.php</code> and place it within your theme folder alongside your new <code>header.php</code> and <code>footer.php</code> templates.</p>
<p>Type the following code in your <code>sidebar.php</code> template.</p>
<pre><code>&lt;div id="sidebar">

&lt;/div>&lt;!-- #sidebar --></code></pre>
<h2>When do we get to the good stuff?</h2>
<p>I know.  I know.  You&#8217;re really itching to make your theme actually do something.  Remember, you need to learn to crawl before you can walk.  It&#8217;s better to learn how some of the basic functionality comes together before you dive head first into more advanced things.  You&#8217;ll get lost later without a solid foundation to build from.</p>
<p>In the next three tutorials, you&#8217;ll learn how to make your <code>header.php</code>, <code>footer.php</code>, and <code>index.php</code> templates display content from WordPress, so get ready.  This tutorial series is about to get a little more complex.  Therefore, you should feel good in knowing that you&#8217;re learning the basics now.</p>
<h2>Downloads</h2>
<p>If you want to see all of today&#8217;s lesson files, <a href="http://justintadlock.com/blog/wp-content/uploads/2011/09/super-mario-03.zip" title="Theme lesson zip file">download a zip file</a> of the theme.  This version builds on the version from the previous tutorial, so there&#8217;ll be files included from that lesson too.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/09/28/creating-basic-theme-templates/feed</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>I wanna be a theme designer: Theme setup</title>
		<link>http://justintadlock.com/archives/2011/09/20/i-wanna-be-a-theme-designer-theme-setup</link>
		<comments>http://justintadlock.com/archives/2011/09/20/i-wanna-be-a-theme-designer-theme-setup#comments</comments>
		<pubDate>Wed, 21 Sep 2011 02:27:40 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[I wanna be a theme designer]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=3939</guid>
		<description><![CDATA[Part two in the theme creation tutorial series, a how-to on setting up and creating your first WordPress theme.]]></description>
			<content:encoded><![CDATA[<p>Are you ready to get started on the path to becoming a theme designer?</p>
<p>Good.  I&#8217;ll assume you&#8217;ve already read through the <a href="http://justintadlock.com/archives/2011/09/15/i-wanna-be-a-theme-designer-intro" title="I wanna be a theme designer: Intro">introduction post</a> of this series and prepared yourself.  If not, go ahead and do that now.</p>
<p>In this tutorial, you will learn how to create your first WordPress theme.</p>
<h2>Naming your theme</h2>
<p>I&#8217;ll assume you&#8217;re already thinking up some crafty names for your first theme.  The one thing you might not have thought of is that there are some rules for naming WordPress themes.  Technically, you can name your theme anything.  However, if you want to have it hosted on the WordPress theme repository, you&#8217;ll need to follow its <a href="http://codex.wordpress.org/Theme_Review#Theme_Name" title="Theme Review Guidelines: Theme Name">guidelines on naming</a>.</p>
<p>In short, don&#8217;t put these things in your theme name:</p>
<ul>
<li>The term &#8220;WordPress&#8221;.</li>
<li>The term &#8220;Theme&#8221;.</li>
<li>Version-specific or markup-related terms.</li>
<li>Your name or site name.</li>
</ul>
<p>Basically, don&#8217;t put things that are irrelevant to the actual theme.  Be creative.  Come up with something fun that represents your theme.</p>
<p>Throughout this series, we&#8217;ll be building a theme from start to finish.  The name of the theme will be <strong>Super Mario</strong>.  <em>Why?</em>  Well, it&#8217;s just cool.  And, we have to name it something.</p>
<h2>Creating a theme folder</h2>
<p>Before diving into any files or code, you need to have a theme folder.  All theme files are kept within a single folder, so your theme will need one.</p>
<p>Since the name of the theme is &#8220;Super Mario,&#8221; the theme folder name should be <code>super-mario</code>.</p>
<p class="note">As a sidenote, any theme folders or filenames you create should contain all lowercase letters and use hyphens if it has multiple words.  This is the general standard used in WordPress file/folder naming.</p>
<p>Your theme folder should be placed within your <code>wp-content/themes</code> directory.  The directory structure should be set up like the following.</p>
<ul>
<li><code>wp-content</code>
<ul>
<li><code>themes</code>
<ul>
<li><code>super-mario</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Or, if you prefer, take a look at how this is set up in the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/09/wp-themes-folder-structure.png" alt="WordPress themes directory structure" title="WordPress theme folder" width="600" height="359" class="aligncenter size-full wp-image-3940" /></p>
<h2>The style.css file</h2>
<p>All WordPress themes require at least two files to work.  The first of these files is <code>style.css</code>.  This is the most important file because it houses your theme information.</p>
<p>So, the next step you should take is to create a new file called <code>style.css</code> with your preferred text editor.  This file should be saved within your <code>super-mario</code> theme folder.</p>
<p>Using your text editor, type the below code into your <code>style.css</code> file.</p>
<pre><code>/**
 * Theme Name: Super Mario
 * Theme URI: http://devpress.com
 * Description: An example theme description.
 * Author: Your Name
 * Author URI: http://devpress.com
 * Version: 0.1
 * Tags: threaded-comments, translation-ready, two-columns, fixed-width
 * License: GNU General Public License v2.0
 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
 */</code></pre>
<p>This information is called the <a href="http://codex.wordpress.org/File_Header#Theme_File_Header_Example" title="WordPress Codex: Theme File Header">Theme File Header</a>.  Each new line in the file header is called a &#8220;header&#8221; and represents a distinct key/value pair.</p>
<ul>
<li><strong>Theme Name:</strong>  This is the name of your theme.  Remember the rules you learned earlier on properly naming your theme.</li>
<li><strong>Theme URI:</strong>  This is the <abbr title="Uniform Resource Indicator">URI</abbr> to your theme&#8217;s page.  If submitting your theme to the WordPress theme repository, make sure to follow the guidelines on <a href="http://codex.wordpress.org/Theme_Review#Credit_Links" title="Theme Review: Credit Links">credit links</a>.</li>
<li><strong>Description:</strong>  The description of your theme.  Simple enough.  Don&#8217;t write a novel here.  Keep it short and descriptive.</li>
<li><strong>Author:</strong>  Your name.</li>
<li><strong>Author URI:</strong>  This should be a link to your personal or WordPress site.  Again, make sure to follow the theme review guidelines on <a href="http://codex.wordpress.org/Theme_Review#Credit_Links" title="Theme Review: Credit Links">credit links</a> if submitting to the repo.</li>
<li><strong>Tags:</strong>  These are a way to label what features your theme has.  WordPress.org has a standard <a href="http://wordpress.org/extend/themes/about/" title="WordPress Theme Repository: About">set of allowed tags</a> you can use.</li>
<li><strong>License:</strong>  What license your theme is under.  This is not currently a standard in WordPress but is <a href="http://codex.wordpress.org/Theme_Review#Licensing" title="Theme Review: Licensing">required for repository-hosted themes</a>.</li>
<li><strong>License URI:</strong>  A link to a page where your theme&#8217;s license can be read in full.</li>
</ul>
<p>Once you&#8217;ve gotten all of your theme information added, you can save your <code>style.css</code> file.  You won&#8217;t need it for the remainder of this tutorial.  Most likely, you&#8217;ll edit your theme info later as you figure out the features your theme will have.</p>
<h2>The index.php template</h2>
<p>I won&#8217;t cover templates in detail just yet.  You&#8217;ll learn about them in another tutorial.  However, you do need one template to have a <em>real</em> WordPress theme:  <code>index.php</code>.  This is the second required file for a WordPress theme to work.</p>
<p>Open your text editor and create a new file called <code>index.php</code>.  Save this file in your <code>super-mario</code> folder.  Don&#8217;t type anything in this file just yet.  You&#8217;ll learn what to do with it later.  For now, you&#8217;re done.</p>
<h2>Congratulations!</h2>
<p>You&#8217;ve just created your first WordPress theme!  Of course, your theme doesn&#8217;t actually do anything yet.  It doesn&#8217;t show blog posts, have nav menus, or display widgets.  You&#8217;ve still got a long journey ahead of you.</p>
<p>Now, pat yourself on the back and relax.  There&#8217;s lots more to come in the next tutorial.</p>
<h2>Downloads</h2>
<p>In each tutorial of this series that has code, I&#8217;ll provide a download link to the day&#8217;s lesson in theme form.  This will be a a zipped theme folder with the current, combined code of the theme you&#8217;re learning to build.</p>
<p>So, go ahead and <a href="http://justintadlock.com/blog/wp-content/uploads/2011/09/super-mario-02.zip" title="Super Mario 02">download a copy</a> of today&#8217;s version of the theme.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/09/20/i-wanna-be-a-theme-designer-theme-setup/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>I wanna be a theme designer: Intro</title>
		<link>http://justintadlock.com/archives/2011/09/15/i-wanna-be-a-theme-designer-intro</link>
		<comments>http://justintadlock.com/archives/2011/09/15/i-wanna-be-a-theme-designer-intro#comments</comments>
		<pubDate>Thu, 15 Sep 2011 18:13:27 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[I wanna be a theme designer]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=3837</guid>
		<description><![CDATA[An introduction to a tutorial series on creating WordPress themes from start to finish.]]></description>
			<content:encoded><![CDATA[<p>DevPress co-founder, Tung, wrote the most amazing <a href="http://www.wpdesigner.com/2007/02/19/so-you-want-to-create-wordpress-themes-huh/" title="So you want to create WordPress themes huh?">series of tutorials</a> on creating WordPress themes from start to finish in 2007.  </p>
<p>I want to start this post by giving credit where it&#8217;s due.  When I first started creating my own WordPress themes, this tutorial taught me everything.  I know a ton of other theme developers who learned from him.  Honestly, I should&#8217;ve just written a post thanking him for what he gave back to the community during that time.</p>
<p>It&#8217;s amazing how time flies.  It&#8217;s now been just over four years since the completion of the series.  Things have changed quite dramatically in the WordPress theme landscape since then.  The original series still has a lot to offer, but it&#8217;s definitely showing its age.</p>
<p>Many have attempted to recreate the magic of that old set of tutorials, but no one has truly topped it.  That will be my goal.  I will attempt to write a better tutorial series on the topic, one that&#8217;s now long overdue in the WordPress community.</p>
<h2>What this tutorial series is about</h2>
<p>I have a strict philosophy on what belongs in WordPress themes.  That philosophy will be the driving force behind this series.  I will teach you how to create themes that use WordPress standards and don&#8217;t have a ton of plugin functionality thrown into the mix.</p>
<p>I plan to strip theme development down to its bare essentials.  You will be taught the standard functions and be given the skills you need to get started creating your own themes.</p>
<p>If you create a theme after following this tutorial series, your theme will have a high likelihood of passing the <a href="http://codex.wordpress.org/Theme_Review" title="WordPress theme review guidelines">theme review guidelines</a>.  Therefore, you shouldn&#8217;t have any issues getting your theme hosted on the WordPress theme repository.  You will also have a more solid code base than 90% of the commercial themes I&#8217;ve seen.</p>
<p>This series of tutorials will be geared toward absolute beginners to theme development.  However, there will be bits and pieces that seasoned developers can use.</p>
<h2>Skills you need</h2>
<p>Technically, you don&#8217;t need any skills to learn from this series aside from some familiarity with WordPress and themes.  It will be a major plus if you have some beginning knowledge of:</p>
<ul>
<li><strong>HTML:</strong>  You can probably get by with little HTML know-how by just following this series.  I highly recommend learning this in your free time though.</li>
<li><strong>CSS:</strong>  I will be covering some standard WordPress CSS elements throughout the tutorial, but I can&#8217;t teach you how to design.  Once you learn how to create a WordPress theme, it will be up to you to decide how to style it.  You might actually want to create something pretty.</li>
<li><strong>PHP:</strong>  You don&#8217;t need to know any PHP at all.  WordPress actually makes this fairly simple for theme developers.  I will also explain all PHP used throughout the series, but knowing some basics will help tremendously.</li>
</ul>
<h2>Tools you need</h2>
<p>I&#8217;ll keep this simple.  Make sure you have these things before the first tutorial is posted:</p>
<ul>
<li><strong>WordPress:</strong>  You need to have a test installation of WordPress set up.  I&#8217;ll assume you know how to do this beforehand.  Preferably, you would set up a test install on your computer (locally).  If you&#8217;re unfamiliar with this process, read <a href="http://tamba2.org.uk/wordpress/xampp/" title="Installing WordPress and Xampp">Installing WordPress and Xampp</a>.</li>
<li><strong>Test data:</strong>  You can create your own test data or use the <a href="http://codex.wordpress.org/Theme_Unit_Test">theme unit test data</a>.  This will give you some content to test your theme.</li>
<li><strong>Text/code editor:</strong>  There are tons to choose from.  I&#8217;m a fan of <a href="http://notepad-plus-plus.org/" title="Notepad++">Notepad++</a> for its simplicity and code highlighting.</li>
</ul>
<h2>Ready to be a theme designer?</h2>
<p>I&#8217;ll try not to overwhelm you with each tutorial in the series and break each post up into digestible parts.  Just let me know if you get lost.</p>
<p>So, before we get started, make sure you have the proper tools.  Then, you&#8217;ll be ready for the first tutorial when its published.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/09/15/i-wanna-be-a-theme-designer-intro/feed</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Adding a login form to a page</title>
		<link>http://justintadlock.com/archives/2011/08/30/adding-a-login-form-to-a-page</link>
		<comments>http://justintadlock.com/archives/2011/08/30/adding-a-login-form-to-a-page#comments</comments>
		<pubDate>Tue, 30 Aug 2011 10:30:43 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=3460</guid>
		<description><![CDATA[How to create a login form on a WordPress page using a custom shortcode.]]></description>
			<content:encoded><![CDATA[<p>In older versions of WordPress, creating a login form on a page was a complex process for the average site owner.  One had to rely on page templates and know how to properly handle forms with PHP.  It wasn&#8217;t a lot of fun.</p>
<p>Fortunately, WordPress eventually introduced the <a href="http://codex.wordpress.org/Function_Reference/wp_login_form" title="WordPress Codex: wp_login_form()">wp_login_form()</a> function, which allows you to easily display a login form anywhere on your site.  Couple that with a custom <a href="http://codex.wordpress.org/Shortcode_API" title="WordPress Codex: Shortcodes">shortcode</a> and you have a recipe for some awesomeness.</p>
<p>This tutorial will walk you through the steps required for creating a login form shortcode to use in any shortcode-ready area (e.g., your post/page editor).</p>
<h2>Creating a login form shortcode</h2>
<p>The first step is opening either your theme&#8217;s <code>functions.php</code> file or, preferrably, a custom plugin file.  You&#8217;ll want to use the following PHP code to create a function that registers shortcodes.</p>
<pre><code>add_action( 'init', 'my_add_shortcodes' );

function my_add_shortcodes() {

	add_shortcode( 'my-login-form', 'my_login_form_shortcode' );
}</code></pre>
<p>What the above code does is add your shortcodes registration function to the <code>init</code> hook.  It then calls the WordPress function <a href="http://codex.wordpress.org/Function_Reference/add_shortcode" title="WordPress Codex: add_shortcode()">add_shortcode()</a>, which creates a new shortcode called <code>&#091;my-login-form&#093;</code>.</p>
<p>Before the <code>&#091;my-login-form&#093;</code> shortcode will work, you need to create the callback function that outputs the login form.  The following code does this.</p>
<pre><code>function my_login_form_shortcode() {

	if ( is_user_logged_in() )
		return '';

	return wp_login_form( array( 'echo' => false ) );
}</code></pre>
<p>The above code checks if the current user is logged into the site.  If not, it calls <code>wp_login_form()</code>, which returns the WordPress login form for display on the page.</p>
<p>As far as most shortcodes go, this one is actually fairly simple.  That&#8217;s all you have to do to create a login form shortcode.</p>
<h2>Using the login form shortcode</h2>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/08/login-form.png" alt="Using the login form shortcode" title="Login form shortcode" width="600" height="365" class="aligncenter size-full wp-image-3461" /></p>
<p>You would use the shortcode just like you&#8217;d use any other shortcode.  You can put it within your post or page editor.  Or, if you have any other shortcode-aware areas, feel free to add it to one of those.</p>
<p>Add the following code to your page editor and save.</p>
<pre><code>&#091;my-login-form&#093;</code></pre>
<h2>Advanced tips and tricks</h2>
<p>The following part of the tutorial is only for people who want to take their login form shortcode to the next level.  None of these tips are required.</p>
<h3>Displaying a message for logged in users</h3>
<p>The shortcode function from earlier in this tutorial doesn&#8217;t display anything for users who are logged into the site.  To display a message such as &#8220;You are already logged in!&#8221;, you only need to tweak a single line.  Your shortcode function code would look like:</p>
<pre><code>function my_login_form_shortcode() {

	if ( is_user_logged_in() )
		return '&lt;p>You are already logged in!&lt;/p>';

	return wp_login_form( array( 'echo' => false ) );
}</code></pre>
<h3>Creating shortcode parameters</h3>
<p>Shortcode parameters are outside the scope of this tutorial, so I won&#8217;t cover them in complete detail.  This subject is covered in the <a href="http://codex.wordpress.org/Shortcode_API" title="WordPress Codex: Shortcode API">shortcode API</a> documentation.  However, I will show you an example of adding in customizable &#8220;Username&#8221; and &#8220;Password&#8221; labels.</p>
<p>Your shortcode function would look like the following code.</p>
<pre><code>function my_login_form_shortcode( $attr ) {

	if ( is_user_logged_in() )
		return '';

	/* Set up some defaults. */
	$defaults = array(
		'label_username' => 'Username',
		'label_password' => 'Password'
	);

	/* Merge the user input arguments with the defaults. */
	$attr = shortcode_atts( $defaults, $attr );

	/* Set 'echo' to 'false' because we want it to always return instead of print for shortcodes. */
	$attr['echo'] = false;

	return wp_login_form( $attr );
}</code></pre>
<p>Suppose you wanted to change the &#8220;Username&#8221; text to read &#8220;Enter Username&#8221; and the &#8220;Password&#8221; text to read &#8220;Enter Password.&#8221;  You&#8217;d use the following in your post editor.</p>
<pre><code>&#091;my-login-form label_username="Enter Username" label_password="Enter Password"&#093;</code></pre>
<h3>CSS classes</h3>
<p>In the screenshot of the shortcode in action earlier in the tutorial, you&#8217;ll notice that it doesn&#8217;t look too fancy.  WordPress generates a few CSS classes that you can use to customize the design of your login form.</p>
<pre><code>/* Username wrapper paragraph. */
.login-username {}

/* Username label. */
.login-username label {}

/* Username input. */
.login-username .input {}

/* Password wrapper paragraph. */
.login-password {}

/* Password label. */
.login-password label {}

/* Password input. */
.login-password .input {}

/* Remember me wrapper paragraph. */
.login-remember {}

/* Remember me label. */
.login-remember label {}

/* Remember me checkbox. */
.login-remember input[type="checkbox"] {}

/* Submit button wrapper paragraph. */
.login-submit {}

/* Submit button. */
.login-submit .button-primary {}</code></pre>
<p>You can also define custom IDs for use in your CSS.  These can be defined as <a href="http://codex.wordpress.org/Function_Reference/wp_login_form#Parameters" title="WordPress Codex: wp_login_form() parameters">arguments</a> for the <code>wp_login_form()</code> function.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/08/30/adding-a-login-form-to-a-page/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Conditional checks for custom post types</title>
		<link>http://justintadlock.com/archives/2011/07/20/conditional-checks-for-custom-post-types</link>
		<comments>http://justintadlock.com/archives/2011/07/20/conditional-checks-for-custom-post-types#comments</comments>
		<pubDate>Wed, 20 Jul 2011 17:41:29 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=2993</guid>
		<description><![CDATA[How to use WordPress' built-in functions to run conditional checks for custom post types.]]></description>
			<content:encoded><![CDATA[<p>I came across a tutorial the other day on a popular WordPress blog about checking the post type of a post in WordPress.  The tutorial used a [broken] custom function for something that already exists in WordPress.  Unfortunately, the correction I left in the comments was not used to amend to the tutorial, so I figured I&#8217;d share the correct way of doing this with others.</p>
<p>This tutorial will walk you through the steps of properly checking the post type of a post and in what situations to use the functions presented.</p>
<h2>Checking the post type within The Loop</h2>
<p>Sometimes, you may need to check a post type of a given post within <a href="http://codex.wordpress.org/The_Loop" title="WordPress Codex: The Loop">the posts loop</a>.  This would most commonly be used within a theme&#8217;s templates, but there are other applications for it.</p>
<p>For this, you need the <a href="http://codex.wordpress.org/Function_Reference/get_post_type" title="WordPress Codex: get_post_type()">get_post_type()</a> function, which returns the name of the post type.</p>
<p>The following code checks the post type of the current post in the loop and runs some code if the post type is either <code>movie</code> or <code>book</code>.</p>
<pre><code>&lt;?php

if ( 'movie' == get_post_type() ) {

	/* Custom code for 'movie' post type. */

} elseif ( 'book' == get_post_type() ) {

	/* Custom code for the 'book' post type. */
}

?></code></pre>
<p>Yes, it&#8217;s really that simple.  If you know how to use if/else statements in PHP, you&#8217;re good to go.</p>
<h2>Checking a post type outside of The Loop</h2>
<p>Checking a post type either inside or outside of The Loop is nearly the same.  You&#8217;d use the same function in this case:  <code>get_post_type()</code>.  However, this time, you&#8217;d need to either put in the post object or the post ID of the specific post you want to check the post type for.</p>
<p>Suppose you wanted to check if the post with the ID of <code>100</code> has the <code>product</code> post type.  You&#8217;d use the following code to do so.</p>
<pre><code>&lt;?php

if ( 'product' == get_post_type( 100 ) ) {

	/* Run some code if this post has a post type of 'product'. */
}

?></code></pre>
<h2>Checking a singular post&#8217;s post type</h2>
<p>If viewing a single/singular view of a post, WordPress has a nifty function that handles this check for you:  <a href="http://codex.wordpress.org/Function_Reference/is_singular" title="WordPress Codex: is_singular()">is_singular()</a>.  This function&#8217;s main purpose is to check if viewing a singular post.  However, it can also be used to check if viewing a singular post of a given post type by entering the <code>$post_type</code> parameter as shown in the following code snippet.</p>
<pre><code>is_singular( 'post' )</code></pre>
<p>You can also check for multiple post types by entering an array of post types as the <code>$post_type</code> parameter as shown in the following code.</p>
<pre><code>is_singular( array( 'post', 'page', 'attachment' ) )</code></pre>
<p>Suppose you wanted to check if a user was viewing a singular post with the post type of <code>testimonial</code>.  You can use the next code sample to perform this check.</p>
<pre><code>&lt;?php

if ( is_singular( 'testimonial' ) ) {

	/* Run some code if viewing a singular testimonial. */
}

?></code></pre>
<p>There you have it.  It&#8217;s fairly easy to run these types of checks, and the required functions are already built into WordPress for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/07/20/conditional-checks-for-custom-post-types/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>How to load JavaScript in the WordPress admin</title>
		<link>http://justintadlock.com/archives/2011/07/12/how-to-load-javascript-in-the-wordpress-admin</link>
		<comments>http://justintadlock.com/archives/2011/07/12/how-to-load-javascript-in-the-wordpress-admin#comments</comments>
		<pubDate>Tue, 12 Jul 2011 19:25:25 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=2859</guid>
		<description><![CDATA[A tutorial on how themes and plugins should load JavaScript only on their settings pages in the WordPress admin.]]></description>
			<content:encoded><![CDATA[<p>One of the things that often frustrates plugin and theme developers is other plugins and themes not properly loading JavaScript in the WordPress admin.  The majority of the plugins and themes (especially themes) that load JavaScript load it on every single page in the admin.</p>
<p>This is not good.</p>
<p>The problem with loading JavaScript like this is that it creates conflicts with other plugins and even WordPress itself.  And, quite frankly, I&#8217;m tired of my number one support question response being, &#8220;Please deactivate all your plugins to see if this corrects the issue.&#8221;</p>
<p>In this tutorial, I will walk you through the steps of loading your JavaScript only on the pages that are specific to your plugin.</p>
<h2>Do you need JavaScript?</h2>
<p>Before moving on, you should ask yourself if you plugin/theme actually needs JavaScript in the admin.  If you&#8217;re trying to create some fancy-schmancy tabbed interface that doesn&#8217;t use the WordPress standard <abbr title="User Interface">UI</abbr>, you&#8217;re <a href="http://wpcandy.com/thinks/custom-admin-screens-are-the-worst" title="Custom designed WordPress options screens need to go">doing it wrong</a>.</p>
<p>The only time you need to load JavaScript in the WordPress admin is when it&#8217;s absolutely necessary for what your plugin or theme is doing.  In most cases, you simply need to be using the standard functions already built for you in the <a href="http://codex.wordpress.org/Settings_API" title="WordPress Codex: Settings API">Settings API</a>.  This requires no JavaScript whatsoever.</p>
<p>There are cases when additional JavaScript is necessary.  That&#8217;s what this tutorial is about &mdash; appropriately loading JavaScript on your plugin pages when JavaScript is crucial to your plugin&#8217;s functionality.</p>
<h2>The proper hooks</h2>
<p>Forget every other bit of code you&#8217;ve seen that loads JavaScript in the admin.  There&#8217;s two hooks that you can use:</p>
<ul>
<li><code>admin_enqueue_scripts</code>:  For enqueuing JavaScript files.</li>
<li><code>admin_head-$pagename</code>:  For printing code directly to the header.</li>
</ul>
<p>Those are the only two hooks you need to worry yourself with.  Under no circumstances should you use <code>admin_init</code> or <code>admin_menu</code> (as many plugins/themes do) to load JavaScript.  You should also never load scripts without a hook, which is extremely common in themes.</p>
<h2>Loading JavaScript files</h2>
<p>First, let&#8217;s take a look at adding a standard <a href="http://codex.wordpress.org/Adding_Administration_Menus" title="WordPress Codex: Adding Administration Menus">options page</a> for a plugin.  Your code would look something like the following.</p>
<pre><code>add_action( 'admin_menu', 'my_example_settings_page' );

function my_example_settings_page() {
	add_options_page( 'DevPress Example', 'DevPress Example', 'manage_options', 'my-example-page-name', 'my_callback_function' );
}</code></pre>
<p>This is fairly standard for most developers.  The trick is to figure out how to load JavaScript only on that page.  </p>
<p>Let&#8217;s assume you need to load a JavaScript file using the <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script" title="WordPress Codex: wp_enqueue_script()">wp_enqueue_script()</a> function.  Your code would look like the following.</p>
<pre><code>add_action( 'admin_menu', 'my_example_settings_page' );

function my_example_settings_page() {
	global $my_settings_page;

	$my_settings_page = add_options_page( 'DevPress Example', 'DevPress Example', 'manage_options', 'my-example-page-name', 'my_callback_function' );

	add_action( 'admin_enqueue_scripts', 'my_admin_enqueue_scripts' );
}

function my_admin_enqueue_scripts( $hook_suffix ) {
	global $my_settings_page;

	if ( $my_settings_page == $hook_suffix )
		wp_enqueue_script( 'my-example' );
}</code></pre>
<p>When you add an action to the <code>admin_enqueue_scripts</code> hook, your action (function) gets passed the parameter of <code>$hook_suffix</code>.  What this allows you to do is check if <code>$hook_suffix</code> matches the name of the plugin&#8217;s settings page.  <code>$hook_suffix</code> will change depending on the page that&#8217;s currently being viewed in the admin.  Therefore, your script will only load when it&#8217;s needed.</p>
<h2>Printing JavaScript in the admin &lt;head></h2>
<p>Let&#8217;s suppose you&#8217;re just adding an extremely small snippet of code to the admin <code>&lt;head></code> area.  Again, you don&#8217;t want to load this on all pages in the admin, even if it&#8217;s just a couple of lines.  It can still conflict with other plugins.  So, let&#8217;s build off your original settings page function.  Your code would look like the following.</p>
<pre><code>add_action( 'admin_menu', 'my_example_settings_page' );

function my_example_settings_page() {

	$my_settings_page = add_options_page( 'DevPress Example', 'DevPress Example', 'manage_options', 'my-example-page-name', 'my_callback_function' );

	add_action( "admin_head-{$my_settings_page}", 'my_admin_head_script' );
}

function my_admin_head_script() { ?>

&lt;script type="text/javascript">&lt;/script>

&lt;?php }</code></pre>
<p>What we&#8217;ve done here is use the <code>admin_head-$pagename</code> hook to load a custom script only in the header for the plugin&#8217;s settings page.  <code>$pagename</code> is just the name of the page currently being viewed in the admin.</p>
<h2>Not just for scripts</h2>
<p>This isn&#8217;t too hard.  I&#8217;m not asking that you learn how to program nuclear missiles for launch.  If you&#8217;re knowledgeable enough to add a custom settings page and add JavaScript in the WordPress admin, it should take you all of 30 seconds to appropriately load your scripts so that they don&#8217;t load on other admin pages.</p>
<p>Don&#8217;t stop with JavaScript though.  The exact same rules apply for custom stylesheets too.  You should even use the same hooks.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/07/12/how-to-load-javascript-in-the-wordpress-admin/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Fixing WordPress 3.2&#8242;s HTML editor font</title>
		<link>http://justintadlock.com/archives/2011/07/06/fixing-wordpress-3-2s-html-editor-font</link>
		<comments>http://justintadlock.com/archives/2011/07/06/fixing-wordpress-3-2s-html-editor-font#comments</comments>
		<pubDate>Wed, 06 Jul 2011 17:11:36 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=2813</guid>
		<description><![CDATA[How to change WordPress 3.2's monospace font in the <abbr title="Hypertext Markup Language">HTML</abbr> editor to a more readable font.]]></description>
			<content:encoded><![CDATA[<p>One of the coolest things about WordPress 3.2 is its &#8220;distraction-free writing&#8221; mode. I&#8217;ve been eagerly awaiting using this feature on my own sites for months. Unfortunately, WordPress 3.2 also shipped with a font change for the <abbr title="Hypertext Markup Language">HTML</abbr> editor to a monospace font, which isn&#8217;t so distraction free when you&#8217;re trying to write.</p>
<p>Sure, I could switch over to the visual editor, but I hate the visual editor more than I hate people who kill kittens for fun. I haven&#8217;t used it in at least four years and will likely not be switching over any time soon.</p>
<p>There is a growing group of people who would like to <a title="Return the HTML editor back to a sans font" href="http://wordpress.org/extend/ideas/topic/return-the-html-editor-back-to-a-sans-font-instead-of-the-new-consolas-font">see the font reverted</a>. However, Matt Thomas does have a <a title="Monospace font in the HTML post editor" href="http://core.trac.wordpress.org/ticket/17640#comment:10">reasonable argument</a> for the change to a monospace font.</p>
<p>Let&#8217;s not focus on the argument over what fonts to use though. WordPress makes this extremely easy to change. It only takes a few lines of code.</p>
<h2>How to change the font</h2>
<p>In your theme&#8217;s <code>functions.php</code> file or in a plugin file, add the following lines of code to change the font stack.</p>
<pre><code>add_action( 'admin_head-post.php', 'my_fix_html_editor_font' );
add_action( 'admin_head-post-new.php', 'my_fix_html_editor_font' );

function my_fix_html_editor_font() { ?&gt;
&lt;style type="text/css"&gt;#editorcontainer #content, #wp_mce_fullscreen { font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; }&lt;/style&gt;
&lt;?php }</code></pre>
<p>This will give you a font stack of:</p>
<ul>
<li>Georgia</li>
<li>Times New Roman</li>
<li>Bitstream Charter</li>
<li>Times</li>
<li>serif</li>
</ul>
<p>You are, of course, free to change this font to whatever you want. I&#8217;m about to play around with my font size and line height a bit to make the writing experience even more enjoyable.</p>
<h2>What the change looks like</h2>
<p>The original font will look like the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/07/monospace-editor.png" alt="Monospace font in the HTML editor" title="Monospace font" width="601" height="495" class="aligncenter size-full wp-image-2814" /></p>
<p>The new look, using the code from above, will look like the next screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/07/serif-editor.png" alt="Serif font in the WordPress HTML editor" title="Serif font" width="601" height="495" class="aligncenter size-full wp-image-2815" /></p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/07/06/fixing-wordpress-3-2s-html-editor-font/feed</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Captions in WordPress</title>
		<link>http://justintadlock.com/archives/2011/07/01/captions-in-wordpress</link>
		<comments>http://justintadlock.com/archives/2011/07/01/captions-in-wordpress#comments</comments>
		<pubDate>Fri, 01 Jul 2011 18:17:33 +0000</pubDate>
		<dc:creator>Justin Tadlock</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress Tutorials]]></category>

		<guid isPermaLink="false">http://devpress.com/?p=2707</guid>
		<description><![CDATA[How to use, design, and customize the WordPress <code>&#091;caption&#093;</code> shortcode for images and other elements.]]></description>
			<content:encoded><![CDATA[<p>The <code>&#091;caption&#093;</code> shortcode in WordPress is a neat bit of functionality.  It allows you to add captions to images.  However, you are not limited to just adding captions to images.  You can add them to pretty much anything, and you&#8217;ll learn how to do it by following this tutorial.</p>
<p>In this tutorial, I will walk you through using, designing, and customizing the output of the <code>&#091;caption&#093;</code> shortcode.</p>
<h2>How to add images with captions</h2>
<p>Many of you might already be aware of how to do this, but let&#8217;s cover the basics for those WordPress users who don&#8217;t.</p>
<p>To add an image caption, you must first upload an image using the WordPress media uploader.  Once you&#8217;ve uploaded an image, you should see an input box labeled &#8220;Caption,&#8221; which is where you&#8217;d add your image caption, as shown in the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/07/add-image-caption.png" alt="Image captions in WordPress" title="Adding an image caption" width="600" height="453" class="aligncenter size-full wp-image-2708" /></p>
<p>To insert the image with a caption into your post, you&#8217;d simply click the &#8220;Insert into Post&#8221; button just like you would with any other image.</p>
<p>What this looks like on the front end of your site will depend entirely on your theme&#8217;s design, but it will look something like the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/07/image-caption-theme.png" alt="How image captions look on the front end" title="Image caption display" width="600" height="282" class="aligncenter size-full wp-image-2709" /></p>
<p>That&#8217;s pretty much everything you need to know about the most common use of captions in WordPress.  Keep reading though.  You might learn a few more neat tricks.</p>
<h2>How to add captions to other elements</h2>
<p>Many WordPress users are unaware that captions can be used for more than just images.  Yes, you can wrap <em>any</em> element with a caption.  You can even wrap other shortcodes with a caption.  In fact, let&#8217;s give that a try.</p>
<p>In this example, let&#8217;s wrap a Vimeo video using the <code>&#091;embed&#093;</code> shortcode with a custom caption.</p>
<p>When you normally embed a video using the <code>&#091;embed&#093;</code> shortcode, it would look like the following line of code in your post editor.</p>
<pre><code>&#091;embed&#093;http://vimeo.com/14580921&#091;/embed&#093;</code></pre>
<p>Let&#8217;s take one more step and add a custom caption.  There are two requirements for using the <code>&#091;caption&#093;</code> shortcode: you must input both the <code>width</code> and <code>caption</code> attributes.  Here&#8217;s what your new video/caption combo should look like in the the post editor:</p>
<pre><code>&#091;caption width="600" caption="A football video"&#093;&#091;embed&#093;http://vimeo.com/14580921&#091;/embed&#093;&#091;/caption&#093;</code></pre>
<p>When viewing the post on the front end of your site, you should see a caption for your video as shown in the following screenshot.</p>
<p><img src="http://justintadlock.com/blog/wp-content/uploads/2011/07/video-with-caption.jpg" alt="WordPress video embed with caption" title="Video embed with caption" width="600" height="371" class="aligncenter size-full wp-image-2711" /></p>
<p>One thing I do need to note is that not all themes were designed to handle anything other than images within captions.  This is simply because the most common use of captions is to wrap images.  So, don&#8217;t be too hard on your theme developer if the design is a little off when trying this out.</p>
<h2>&#091;caption&#093; attributes</h2>
<p>The <code>&#091;caption&#093;</code> shortcode has several attributes that you may customize:</p>
<ul>
<li><strong>id</strong>:  A unique <abbr title="Hypertext Markup Language">HTML</abbr> ID that you can change to use within your <abbr title="Cascading Style Sheets">CSS</abbr>.</li>
<li><strong>align</strong>: The alignment of the caption within the post.  Valid values are: <code>alignnone</code> (default), <code>aligncenter</code>, <code>alignright</code>, and <code>alignleft</code>.</li>
<li><strong>width</strong>: How wide the caption should be in pixels.  This attribute is required and must have a value greater than or equal to <code>1</code>.</li>
<li><strong>caption</strong>:  The actual text of your caption.  This attribute is required, of course.</li>
</ul>
<p>Let&#8217;s go back to the first example from this tutorial (adding an image caption) and look at the shortcode that WordPress added.</p>
<pre><code>&#091;caption id="attachment_6" align="alignright" width="300" caption="The Great Wave"&#093;&lt;img src="http://localhost/wp-content/uploads/2010/07/800px-Great_Wave_off_Kanagawa2-300x205.jpg" alt="Kanagawa" title="The Great Wave" width="300" height="205" class="size-medium wp-image-6" />&#091;/caption&#093;</code></pre>
<p>As you can see, each of the attributes are used in this example.  You can customize those attributes to your liking within the post editor.</p>
<h2>Designing image captions</h2>
<p>I&#8217;m not going to teach you how to design your captions (we might get <a href="http://devpress.com/community/ttsondo/" title="DevPress Community: Tung Do">Tung</a> to do that in a later post).  But, I am going to give you some basic <abbr title="Cascading Style Sheets">CSS</abbr> to start with.  Let your imagination run wild.</p>
<p>Use the following classes in your theme&#8217;s <code>style.css</code> file to customize the appearance of captions.</p>
<pre><code>/* The wrapper &lt;div> for the caption and captioned element. */
.wp-caption { }

/* The caption text. */
.wp-caption-text { }

/* An image within the caption (you might want to style other elements too). */
.wp-caption img { }</code></pre>
<p>One thing to keep in mind is that WordPress automatically adds an extra <code>10px</code> of width to the caption using an inline style.  You can either wrestle with styles for that or see the next section of this tutorial.</p>
<h2>Customizing the caption output</h2>
<p>WordPress allows you to modify the <abbr title="Hypertext Markup Language">HTML</abbr> output of the <code>&#091;caption&#093;</code> shortcode by using a custom filter on the <code>img_caption_shortcode</code> hook.  You can use it to change up things however you want.  In this particular example, you&#8217;ll learn how to fix a minor issue with captions.</p>
<p>If you&#8217;re a WordPress theme developer, you&#8217;ve likely had a headache or two from styling the <code>&#091;caption&#093;</code> shortcode in WordPress.  Well, if you&#8217;ve ever tried to do anything other than the generic box around an image thing, you&#8217;ve probably hit some snags.  WordPress adds <code>10px</code> of extra width to its caption wrapper.  I assume this was to make it easier to use the box-style captions.  However, not all captions are designed to have a basic border and look all boxy.</p>
<p>The following code removes the additional <code>10px</code> of width that WordPress would normally add.</p>
<pre><code>add_filter( 'img_caption_shortcode', 'cleaner_caption', 10, 3 );

function cleaner_caption( $output, $attr, $content ) {

	/* We're not worried abut captions in feeds, so just return the output here. */
	if ( is_feed() )
		return $output;

	/* Set up the default arguments. */
	$defaults = array(
		'id' => '',
		'align' => 'alignnone',
		'width' => '',
		'caption' => ''
	);

	/* Merge the defaults with user input. */
	$attr = shortcode_atts( $defaults, $attr );

	/* If the width is less than 1 or there is no caption, return the content wrapped between the &#091;caption&#093;&lt; tags. */
	if ( 1 > $attr['width'] || empty( $attr['caption'] ) )
		return $content;

	/* Set up the attributes for the caption &lt;div>. */
	$attributes = ( !empty( $attr['id'] ) ? ' id="' . esc_attr( $attr['id'] ) . '"' : '' );
	$attributes .= ' class="wp-caption ' . esc_attr( $attr['align'] ) . '"';
	$attributes .= ' style="width: ' . esc_attr( $attr['width'] ) . 'px"';

	/* Open the caption &lt;div>. */
	$output = '&lt;div' . $attributes .'>';

	/* Allow shortcodes for the content the caption was created for. */
	$output .= do_shortcode( $content );

	/* Append the caption text. */
	$output .= '&lt;p class="wp-caption-text">' . $attr['caption'] . '&lt;/p>';

	/* Close the caption &lt;/div>. */
	$output .= '&lt;/div>';

	/* Return the formatted, clean caption. */
	return $output;
}</code></pre>
<p>If you really want to try out something cool, try modifying the above code to use the <code>&lt;figure></code> and <code>&lt;figcaption></code> elements from <abbr title="Hypertext Markup Language">HTML5</abbr>.</p>
<h2>Play around with some captions</h2>
<p>Now that you&#8217;ve learned just about everything you need to know about captions, it&#8217;s time to go play around with them a bit.  </p>
<p>I highly encourage WordPress theme developers to test out captions with elements other than images.  I&#8217;m sure you could come up with some neat designs ideas.</p>
]]></content:encoded>
			<wfw:commentRss>http://justintadlock.com/archives/2011/07/01/captions-in-wordpress/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

