How to Display Metaboxes According to the Current Post Format

Today I’d like to show you how to go further with custom metaboxes and specifically how to use them according to post formats.

We won’t cover how to build reusable custom metaboxes as it has already been covered in a previous topic, so please refer to this article if you have any trouble with this.


Introduction

First things first, if you’ve never heard of them before, post formats allow you to display a post in many ways, depending on which “format” of post you’ve set (image, link, gallery etc.).

To be sure that your theme is “post formats”-ready, check that it accepts different formats by looking for this function:

	add_theme_support( 'post-formats', array( 'link', 'quote' ) );

Now with this example, you’ll be able to use two post formats: ‘link’ and ‘quote’.

Two metaboxes with a simple text input inside

The idea is to display a metabox only if the right post format radio button is checked. For this, we are going to use hooks (PHP) and jQuery (JavaScript).


Step 1 Adding Custom Metaboxes

We’ll define an array of metaboxes applicable to posts only (you can write it inside the functions.php file of your theme). There are different default options (location, priority) we won’t focus on (again check the article on reusable custom metaboxes).

Define Metaboxes

Besides the fields we are defining, what is important to note in the code below is the display_condition variable that will be used to show/hide metaboxes according to the current post format. It matches the post format radio button’s ID.

$metaboxes = array(
	'link_url' => array(
		'title' => __('link information', 'twentyeleven'),
		'applicableto' => 'post',
		'location' => 'normal',
		'display_condition' => 'post-format-link',
		'priority' => 'low',
		'fields' => array(
			'l_url' => array(
				'title' => __('link url:', 'twentyeleven'),
				'type' => 'text',
				'description' => '',
				'size' => 60
			)
		)
	),
	'quote_author' => array(
		'title' => __('quote author', 'twentyeleven'),
		'applicableto' => 'post',
		'location' => 'normal',
		'display_condition' => 'post-format-quote',
		'priority' => 'low',
		'fields' => array(
			'q_author' => array(
				'title' => __('quote author:', 'twentyeleven'),
				'type' => 'text',
				'description' => '',
				'size' => 20
			)
		)
	)
);

For this tutorial, we’ll only add a basic text input for each metabox. Be sure to check the field key is unique or it won’t work properly.

Now we’ll create three functions to add, update/save, and show the metaboxes.

Create Metaboxes

add_action( 'admin_init', 'add_post_format_metabox' );
function add_post_format_metabox() {
	global $metaboxes;
	if ( ! empty( $metaboxes ) ) {
		foreach ( $metaboxes as $id => $metabox ) {
			add_meta_box( $id, $metabox['title'], 'show_metaboxes', $metabox['applicableto'], $metabox['location'], $metabox['priority'], $id );
		}
	}
}

Basicly, we’re just using our previously defined options to add these metaboxes.

Show Metaboxes

function show_metaboxes( $post, $args ) {
	global $metaboxes;
	$custom = get_post_custom( $post->ID );
	$fields = $tabs = $metaboxes[$args['id']]['fields'];
	/** Nonce **/
	$output = '<input type="hidden" name="post_format_meta_box_nonce" value="' . wp_create_nonce( basename( __FILE__ ) ) . '" />';
	if ( sizeof( $fields ) ) {
		foreach ( $fields as $id => $field ) {
			switch ( $field['type'] ) {
				default:
				case "text":
					$output .= '<label for="' . $id . '">' . $field['title'] . '</label><input id="' . $id . '" type="text" name="' . $id . '" value="' . $custom[$id][0] . '" size="' . $field['size'] . '" />';
					break;
			}
		}
	}
	echo $output;
}

So far, this is what we should have on a new post admin screen:

Two metaboxes with a simple text input inside

Save Metaboxes

add_action( 'save_post', 'save_metaboxes' );
function save_metaboxes( $post_id ) {
	global $metaboxes;
	// verify nonce
	if ( ! wp_verify_nonce( $_POST['post_format_meta_box_nonce'], basename( __FILE__ ) ) )
		return $post_id;
	// check autosave
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
		return $post_id;
	// check permissions
	if ( 'page' == $_POST['post_type'] ) {
		if ( ! current_user_can( 'edit_page', $post_id ) )
			return $post_id;
	} elseif ( ! current_user_can( 'edit_post', $post_id ) ) {
		return $post_id;
	}
	$post_type = get_post_type();
	// loop through fields and save the data
	foreach ( $metaboxes as $id => $metabox ) {
		// check if metabox is applicable for current post type
		if ( $metabox['applicableto'] == $post_type ) {
			$fields = $metaboxes[$id]['fields'];
			foreach ( $fields as $id => $field ) {
				$old = get_post_meta( $post_id, $id, true );
				$new = $_POST[$id];
				if ( $new && $new != $old ) {
					update_post_meta( $post_id, $id, $new );
				}
				elseif ( '' == $new && $old || ! isset( $_POST[$id] ) ) {
					delete_post_meta( $post_id, $id, $old );
				}
			}
		}
	}
}

Ok, now we’re all set and are able to add and update post metas to each and every article and display them inside metaboxes. We can now dig into our problem: display the correct metabox to match the current post format.


Step 2 Display the Correct Metabox at the Correct Time

For this, we will use jQuery to handle show, hide and radio change events.

To add inline JavaScript only in the admin section, we can use this action hook:

	add_action( 'admin_print_scripts', 'display_metaboxes', 1000 );

The priority is set to 1000 to ensure jQuery has been loaded first.

We could set a more precise hook such as admin_print_scripts-post or admin_print_scripts-post-new, but for some reason, if doing so, jQuery is called after our script is printed.

Plus, if we were to add post formats to custom post types, it wouldn’t be very convenient to add all possible configurations.

What we’ll do is build (via PHP) a JavaScript string containing a list of IDs (the field key seen above) separated with a comma. It will be used to hide all metaboxes but the one matching the current post format.

We are also going to build (still via PHP) a JavaScript object we’ll use to bind a post format radio button’s ID to a metabox’s ID.

function display_metaboxes() {
	global $metaboxes;
	if ( get_post_type() == "post" ) :
		?>
		<script type="text/javascript">// <![CDATA[
			$ = jQuery;
			<?php
			$formats = $ids = array();
			foreach ( $metaboxes as $id => $metabox ) {
				array_push( $formats, "'" . $metabox['display_condition'] . "': '" . $id . "'" );
				array_push( $ids, "#" . $id );
			}
			?>
			var formats = { <?php echo implode( ',', $formats );?> };
			var ids = "<?php echo implode( ',', $ids ); ?>";

Then we will display the right metabox after the page is loaded by selecting the current post format (checked radio button) and fading in the matching metabox (using the formats object).

For this, we’ll define a function that will also be triggered every time a change event happens on the post format radio buttons.

			function displayMetaboxes() {
				// Hide all post format metaboxes
				$(ids).hide();
				// Get current post format
				var selectedElt = $("input[name='post_format']:checked").attr("id");
				// If exists, fade in current post format metabox
				if ( formats[selectedElt] )
					$("#" + formats[selectedElt]).fadeIn();
			}
			$(function() {
				// Show/hide metaboxes on page load
				displayMetaboxes();
				// Show/hide metaboxes on change event
				$("input[name='post_format']").change(function() {
					displayMetaboxes();
				});
			});
		// ]]></script>
		<?php
	endif;
}

And voila! Now you can switch post formats back and forth and you’ll always have the right metabox displayed.


Conclusion

Post formats can be very handy to personalize the layout of any kind of post and displaying metaboxes accordingly is a great way to improve user-friendliness.

Plus it saves space on an already well cluttered admin screen. With a little more CSS and several fields, you can really improve the way you write posts and get a really intuitive interface.

from Wptuts+ http://wp.tutsplus.com/tutorials/theme-development/how-to-display-metaboxes-according-to-the-current-post-format/

About these ads

Kommentar verfassen

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ photo

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s