Create a “featured article” admin panel in WordPress

I’ve seen several premium WordPress themes that used different kinds of featured sliders for home page. Is nothing wrong here, it’s a good way of putting important thing first. What it bother me is this silly thing: to add an article to the feature slider you have to use a certain tag. Or worse, a certain category! That’s SILLY and very not user friendly (don’t forget that many editors are very non-technics!).

I developed several WP theme over the last two years and I used to make things in the very same way. Until I had few complains from final clients (sometimes I work for the middle man) that the „tag” way is very user-not-too-friendly. So I had to find another way of doing this.

Custom Fields way

The most easy way of having a way to sort things up is the use of custom fields. So you can add a custom field, named let’s say… featured with the value true. Or something similar. This way you can add some description too, a different title and other goodies.

Custom fields issues

Even if custom fields sounds the right choice, there might be a small problem. Let’s say your awesome blog has only one featured post per month (or even week). As a very busy man, you will probably forget if the custom field was feature or featured. And the value was true, yes or just 1 ? Hmmm…

The solution is…

Custom Fields with Write Panels!

How about this: a very neat panel with a checkbox? That’s all you will need. The whole thing is just one click away!

Is a very easy way of doing the whole thing and very easy to implement.

The whole code is here:

<?php 
$ntz_featured_fields = array(
	array(
		"name"			=> "_ntz_is_featured",
		"label"			=> "Featured?",
		"type"			=> "checkbox"
	),	// checkbox
	array(
		"name"			=> "_ntz_featured_title",
		"label"			=> "Featured Title (leave empty for post title)",
		"type"			=> "text"
	), // text
	array(
		"name"			=> "_ntz_featured_description",
		"label"			=> "Featured description (leave emtpy for post excerpt)",
		"type"			=> "textarea"
	), // text
);

function ntz_featured_meta( $post_data, $meta_info ) {
	global $post, $ntz_featured_fields;
	echo '<div class="ntz_panel"><input type="hidden" name="ntz_featured_metaes_nonce" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';
	foreach( $ntz_featured_fields as $o ){
		$val = get_post_meta( $post->ID, $o['name'], true );
		echo '<p>';

		switch ( $o['type'] ){
			case "checkbox":
				$isChecked = ( $val == 1 ? 'checked="checked"' : '' ); // we store checked checkboxes as 1
				echo '<label>' . $o['label'] . ' <input type="checkbox" name="' . $o['name'] . '" id="' . $o['name'] . '" ' . $isChecked . ' /></label>';
			break; // checkbox

			case "textarea":
				echo '<textarea name="' . $o['name'] . '" id="' . $o['name'] . '" cols="10" rows="5" placeholder="' . $o['label'] . '">' . $val . '</textarea>';
			break; // textarea

			case "text":
			default:
				echo '<input type="text" name="' . $o['name'] . '" id="' . $o['name'] . '" value="' . $val . '" placeholder="' . $o['label'] . '" />';
			break; // text & default
		}// swtich

	}// foreach
	echo '</div>';
?>

<style type="text/css" media="screen">
	.ntz_panel input[type="text"],
	.ntz_panel textarea {
		width:100%;
	}
	.ntz_panel .desc {
		text-align:right;
	}
	
</style>
	<?php 
}

function ntz_create_featured_meta() {
	if ( function_exists( 'add_meta_box' ) ) {
		add_meta_box( 'ntz_featured_meta', 'This post is featured?', 'ntz_featured_meta', 'post', 'side', 'high' );
	}
}

function ntz_save_featured_meta( $post_id ) {

	global $post, $post_id, $ntz_featured_fields;
	if ( in_array( $_REQUEST['post_type'], array('page') ) ) {
		if ( !current_user_can( 'edit_page', $post_id ) ) {return $post_id;}
	} else {
		if ( !current_user_can( 'edit_post', $post_id ) ) {return $post_id;}
	}

	foreach($ntz_featured_fields as $o){
		if ( !wp_verify_nonce( $_REQUEST['ntz_featured_metaes_nonce'], plugin_basename(__FILE__) )) {
			return $post_id;
		}
		switch ($o['type']){
			case "checkbox":
				update_post_meta( $post_id, $o['name'], isset( $_REQUEST[$o['name']] ) );
			break;
			default:
				update_post_meta($post_id, $o['name'], $_REQUEST[$o['name']]);
			break;
		}
	}
}
add_action( 'admin_menu', 'ntz_create_featured_meta' );  
add_action( 'save_post', 'ntz_save_featured_meta' );

I like to think that my code is pretty easy to follow so doesn’t need too many explanations. Even so, there are some things to consider:

  • I have no idea how custom fields works for huge sites. I had around 5000 unique users / days and i had no visible performance drops.
  • You must place the content of the gist above on functions.php or into wp-content/mu-plugins/featured_panel.php. Either way, the code will just work. You don’t have to do anything else on admin. I recommend the second way if you change your themes a lot.
  • You can remove title/description fields from the $ntz_featured_fields array. You can also add more fields (eg: custom image).
  • You still need to do some other changes on your theme files! Keep reading!

Done with the admin. What’s next?

Well… After we did the admin part, we need a way of displaying the whole thing for regular users, no?

The not-so-awesome way of doing it

Believe it or not, there is a not-so-awesome way of doing this. And a LOT of guys do this! The „regular” versions (that uses tags or categories to display the featured articles) are doing the job this way:

query_posts( 'posts_per_page=3&amp;amp;tag=featured' );
while (have_posts()){ the_post();
	// put your awesome-wanna-be code here
}
wp_reset_query();

Why I consider this wa a bad way of doing the job? Because you can easily forget about wp_reset_query() and you featured code may interfere with your other parts of your code.

The awesome way of doing it

Did you ever heard about custom query? How about this:

$featured_posts = new WP_Query();
$featured_posts-&gt;query( 'posts_per_page=3&amp;amp;tag=featured' );
while ($featured_posts-&gt;have_posts()){ $featured_posts-&gt;the_post();
	// put your awesome code here
}
The awesome way of custom fields

So, instead of using the tag-thing, we can do it like this:

$featured_posts = new WP_Query();
$featured_posts-&gt;query( 'posts_per_page=3&amp;amp;meta_key=_ntz_is_featured&amp;amp;meta_value=1' );
while ($featured_posts-&gt;have_posts()){ $featured_posts-&gt;the_post();
	global $post;
	// you have two variables to play with: the title and the description; 
	// If you added more fields, this is how you can use them
	$featured_title = get_post_meta( $post-&gt;ID, '_ntz_featured_title', 1);

		$featured_title = !empty( $featured_title ) ? $featured_title : get_the_title();
	$featured_description = get_post_meta( $post-&gt;ID, '_ntz_featured_description', 1);
		$featured_description = !empty( $featured_description ) ? $featured_description : get_the_excerpt();

	// put your awesome code here
}

That’s all! I didn’t cover the js-related part of the slider. You can use any script available out there.

So… Enjoy & start writting quality code!

BTW: if you want to know how to add a featured slider totally independent of your blog posts, very easy to manage & reorder, please let me know!

4 Comentarii to “Create a “featured article” admin panel in WordPress”

  1. Great article! I would like to see the other version of the slider. ( the one with independent slider )

    Also, there is a way of excluding the featured posts from the main loop? Thanks.

  2. Staicu Ionuț-Bogdan

    @michael: I’m glad you are like the article.

    To exclude posts from the loop based on custom fields you can try this:

    $featured_posts->query( array(
     posts_per_page => 3,
     meta_key => "_ntz_is_featured",
     meta_value => 1,
     meta_compare => '!=',
    ) );
    

    More details here.

  3. Ok. An interesting way but what if you want to retrieve all the featured posts in the dashboard? Is there such an easy way to do so? Because when using tags you can just click on the tag and it’ll show all the posts under that tag via the dashboard. You know what I’m saying? So before I can use this, I’d wait for an answer on that.

  4. Staicu Ionuț-Bogdan

    Uhm.. Yeah, this can be done pretty easily by adding a dashboard widget (with the same query used above). API is here. There are like 10-15 lines of code :)

Show trackbacks

Leave a comment!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter