How to create a side blog with WordPress 3.0

by Jean. 63 Comments -

Finally! WordPress 3.0 was released last week. Among other exiting features, custom post types are bringing lots of new possibilities to bloggers. In this tutorial, I’ll show you how to create a side blog listing products using the WordPress 3.0 custom post type feature.

Getting ready

So, what are custom post types? That’s simple, custom post types are like a blog post or page, but of a custom defined type.
As an example, I decided to list some promo codes on my other blog CatsWhoBlog. I could have used a good old static page, but updating it and adding new promo codes would have been a pain.

So I created a custom post type, named coupon and a page template to list all coupons. It’s as simple as that, and now managing coupons & promo codes is extremely easy:

Creating the post type

Ok, let’s code. The first thing to do is to create a custom post type. To do so, pick up your theme functions.php file, and add the following:

function create_my_post_types() {
            'label' => __('Coupons'),
            'singular_label' => __('Coupon'),
            'public' => true,
            'supports' => array(
	    'rewrite' => array(
	        'slug' => 'coupons',
	        'with_front' => false
add_action( 'init', 'create_my_post_types' );

Once you saved functions.php, you should notice that a new tab appeared in your WordPress dashboard, as shown in the picture below:

So what does this code do?
First, I have created a function which registers a new post type, named coupons. I gave the following parameters to the register_post_type() function:

  • label: Nicename of your post type.
  • singular_label: Pretty self explanatory, the singular label of your post type.
  • public: Allows post type to be seen publicly.
  • supports: Array of data of what the post type supports (editor, excerpt, comments, custom fields, etc…)
  • rewrite: Parameters for url rewriting and general post type display.

The complete parameter list can be found on WordPress Codex.

Then, I “hooked” this function to WordPress init() function using add_action().

Adding data

Now that the post type has been created, you can add data by clicking on the “Add Coupon” (Or whatever you named it) link in WordPress dashboard menu.

You should see the following:

Creating a page template to list custom post types

Now that we have created a custom post type and added some custom posts, we still have to display it. To do so, I have used a page template. You can easily reuse the following code, or adapt it to display in your blog sidebar, for example.
If you want to see a demo of the page template, just click here.

Template Name: Promo codes Page
<?php get_header() ?>

	<div id="container">
		<div id="content" class="coupons">
			<h1 class="entry-title"><?php the_title(); ?></h1>
			<?php the_content(); ?>

			<?php global $wp_query;
			$page_num = $paged;
			if($pagenum='') $pagenum=1;

			$wp_query = new WP_Query("showposts=20&post_type=coupons&post_status=publish&paged=".$page_num);

			while ($wp_query->have_posts()) : $wp_query->the_post(); ?>

				<div class="post" id="post-<?php the_ID(); ?>">
					<h2><?php the_title(); ?></h2>
					<div class="exerpt"><?php the_excerpt(); ?></div>
				</div><!-- .post -->

			<?php endwhile; ?>

			<div class="navigation"><p><?php posts_nav_link(); ?></p></div>

		</div><!-- #content -->
	</div><!-- #container -->

<?php get_sidebar() ?>
<?php get_footer() ?>

As you can see, the code I’ve used is definitely easy and self-explanatory. In order to fetch a specific post type, you have to specify the parameter post_type=coupons.

That’s all for today, hope you enjoyed this tutorial!

Comments (63) - Leave yours

  1. wesley said:

    Thanks, this is really useful! I cant wait to adapt this into upcoming clients websites.
    This would make it a lot easier for them to update their own website/blog!

  2. loige said:

    I think that’s the most interesting new feature of wordpress. It makes wordpress really more flexible and really much closer to a full cms engine than just a simple blog managing platform.

    Thanks for this really article Jean-Baptiste! I was just wondering how this new feature should be used.

    • loige said:

      “Thanks for this really article Jean-Baptiste!”

      Lol! I meant:

      “Thanks for this really INTERESTING article Jean-Baptiste!” :P

  3. Adub said:

    Just out of curiosity, how do you enable the “stolen post” feature that you have (I presume accidentally) at the top of this post?

  4. weston deboer said:

    I came here from your feed. The first image from this post that said, I didn’t write this post, i stole it from

    The rest of the images displayed fine.

    Just letting you know

    • Boba said:

      $post_meta = get_post_custom();

      It goes inside the while loop of course.

      Call print_r($post_meta) after that line so you can understand the array a bit better.

  5. Chad said:

    Amazing. I was just looking in to this the other day but didn’t find much but this solves everything. Now to implement it on 6 sites….

  6. emmanuel said:

    Hi, im a beginner in wordpress, i was just wondering about “the_content();” that you used there, becuz from what i’ve read in the wordpress codex, it must be inside the Loop?

  7. Johan de Jong said:

    I think I’m doing something wrong, since it’s not working for me…

    I did the following:
    1) copied the create_my_post_types() function and saved it as a plugin (and activated).
    2) created a new page template ‘coupons.php’, c&p-ed the loop and saved it at my theme.
    3) made a new page called ‘Coupons’ (slug ‘/coupons’), without content but with page template.
    4) created a new coupon with the new post type and published it.

    When I go directly to the coupon (eg /coupons/lorem-ipsum) it works, but it won’t be shown in the loop at /coupons

  8. teebee said:

    I’ve been looking into this since RC2 but I’ve been trying to use taxonomies instead of custom fields. Should I be using custom fields or is it possible (better?) to use taxonomies? Can you show an example, especially the coding of the template. I’m just starting with WP and I copied the page.php to template-store.php and was trying to tweak that instead. Also, I was using the “Custom Post Type UI” instead of altering my functions.php and wanted your opinion on that plugin. TIA!

  9. Dick Raney said:

    How is the custom post type different than just creating a custom template for posts in the category ‘coupons’ and using code on the single.php template like shown below to call in the custom template? I hope this doesn’t seem like a stupid question. I just want to get a better understanding of what the custom post type accomplishes. Maybe it does the same thing, but makes it easier to do without hacking a template. Thanks for any reply and here is the code I have used before to accomplish the same thing (I think):

  10. Maan said:

    Good post, although I fail to see how this new feature in 3.0 is better than what the “magic fields” plugin already does. Not only has it been around pre 3.0 but its alot easier to use.
    No need for all that code – making new post types and managing them is done through the admin panel.

  11. Naoise said:

    Thanks for the post! It really is a very neat feature of WP3.

    What you don’t quite mention is the convention to name the template file and where to put it. I guess you named it “coupons.php” and put it in the theme root folder?


  12. Randy said:

    Hey, thanks for getting us all rolling on 3.0!
    Is there a file naming convention like category-coupons.php (for custom category templates) or page-coupons.php for these custom post type template files?

    I am assuming since this is not “technically” a post OR a page that we need to create a custom “page” template to be treated as a archive-like listing.

    IMO I wish they wouldn’t have called it “custom POST types”. That makes you think you would need to create a category for it. Could have been “Custom content types” or something.

  13. Kim Vo said:

    Thanks for sharing the entire creating side blog process. I’ve always been confused/had trouble with the codes because sometimes they just get really complicated and confusing so the one you used is pretty straight forward and easily applicable. WordPress 3.0 is way better. I love the upgrades!

  14. Madden11 said:

    Wow… great post now this task become very easy & after reading your post carefully any one can design & develop side blog with wordpress 3.0. I like your way for explaining all the things like your step by step snap shots etc.

  15. Robin Parduez said:

    This is a really nice pracitcal example. I’ve been deliberating as to whether I should set up a sepearate sub-blog or run a seperate RSS feed for a specific category which doesn’t fit with the main blog content. But I think I’m going to use the method you’ve shown. Thanks

  16. Aj said:

    WP 3.0 is nice!

    I am still using the following in my Functions file to create post templates:

    ‘term_id}.php”) ) return TEMPLATEPATH . “/single-{$cat->term_id}.php”; } return $t;’ )); ?>’

    Maybe its time I switch over, should be fun and your post will help me get it done much quicker, thanks!

  17. Hendrik Jacob said:

    Wow the custom post type feature rocks … WordPress keeps on raising the bar for CMS-Systems. I would definitely prefer WordPress over typo3 for customers with basic web-knowledge.

  18. Mark Stoecker said:

    Another great post. I have yet to delve into the new features of WP 3.0 but what I have been finding, I’m liking. Thank you for detailing this new feature. I’m looking forward to using it. Thanks agian.

  19. Patrick said:

    Thanks a lot !! I was wondering whether this was possible or not till I found your post.I am going to adopt this on one of my websites.Thanks again Jean.

  20. Brian said:

    I had a lot of trouble with this one but I think I’ve sorted it out now..
    1) The template needs to be saved as single-yourcustomposttypename.php and it will be used as the default template for this post type.

    2) Refresh your permalinks structure and enable ‘rewrite’ => true, in the register post type settings if you are getting 404 errors.

    It would also be nice to have Customised update messages when you have edited a page so use the following snippet for this.

    Then to get custom messages you need to add this filter to your functions.php file
    Replace yourcustomposttype and Custom with appropriate values for your theme.
    add_filter(‘post_updated_messages’, ‘yourcustomposttype_updated_messages’);
    function yourcustomposttype_updated_messages( $messages ) {

    $messages['yourcustomposttype'] = array(
    0 => ”, // Unused. Messages start at index 1.
    1 => sprintf( __(‘Custom updated. View Custom‘), esc_url( get_permalink($post_ID) ) ),
    2 => __(‘Custom field updated.’),
    3 => __(‘Custom field deleted.’),
    4 => __(‘Custom updated.’),
    /* translators: %s: date and time of the revision */
    5 => isset($_GET['revision']) ? sprintf( __(‘Custom restored to revision from %s’), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    6 => sprintf( __(‘Custom published. View Custom‘), esc_url( get_permalink($post_ID) ) ),
    7 => __(‘Custom saved.’),
    8 => sprintf( __(‘Custom submitted. Preview Custom‘), esc_url( add_query_arg( ‘preview’, ‘true’, get_permalink($post_ID) ) ) ),
    9 => sprintf( __(‘Custom scheduled for: %1$s. Preview Custom‘),
    // translators: Publish box date format, see
    date_i18n( __( ‘M j, Y @ G:i’ ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
    10 => sprintf( __(‘Custom draft updated. Preview Custom‘), esc_url( add_query_arg( ‘preview’, ‘true’, get_permalink($post_ID) ) ) ),

    return $messages;

  21. Daniel McClure said:

    Thanks for sharing this, after seeing what you have done with this I have some really exciting ideas for my future skin releases. I’ve already rolled out limited solutions on some clients sites but my guess is we are going to see some really interesting things being built with WordPress in the coming months!

  22. John said:

    I love version 3.0 of WordPress, I feel it’s almost too good to be true that’s it’s still free. Your post ads more possibilities which I appreciate greatly.

    Many thanks.

  23. Igor Matos said:

    Thanks for the great tutorial!
    but i think i’ve found one problem.. the search is including these coupons on the search.

    How can i exclude this custom post from the results page?

    Thanks again and keep up the good work!

  24. Charles said:

    Jean, good post.
    I like the idea of the side blog as I was searching the forums looking for this very thing.
    My question is how do I use that space to insert a banner ad?
    Also I followed your instructions and was able to add it to wordpress but not real sure how to apply it. If your saying this guy must be a newbie your right.And I would love your help. Thanks.

  25. The art of cross-promotion said:

    [...] your new blog by using it as an example. This is what I’ve done on this CWC post named How to create a side blog with WordPress 3.0. The post is an useful tutorial which use my coupons page as an example. Result: 288 Retweets as I [...]

  26. Mark said:

    Wow, I’m usually totally lost when it comes to tutorials that use programming, but this one was very clear and extremely useful. Maybe a follow-up post could be something like “10 custom templates to add to your blog”

  27. mark rushworth said:

    I’d always wondered what the practical reasons for having this new feature in wordpress and here you are. Im still struggling with seeing how i personally can impliment it to great effect but it looks solid enough to add galeries and stuff to client websites.

  28. andreas Bengter said:

    You still didn’t explain how you recieved the indata to the template. Like say the images.. But I guess as this is a recourceful site there is a tutorial on that somewhere else.. coul have linked it though,, 8)

  29. andreas Bengter said:

    (hmm the filter took away the start of the function..) – But do u have any ideas what coould have caused the error above? I think I will start on a new theme instead of continuing on an altered theme.. Guess that theme could smash together with code that should work on a new “clean-slate-theme” so to speak.

  30. andreas Bengter said:

    K took away some of the clutter from the previous theme.. And it works fine now atleast in the admin view.. But for some reason when I press a category to view it, it’s just the titles being showed not the entries’s text..

  31. chatougri said:

    Ba merde alors ! Je tombe souvent sur Catswhocode quand je fais des recherches sur WordPress, et j’avais loupé cet article ! (rolalala c’est quoi ce titre sans “custom post type” dedans ? lol)

    Pourtant c’est un des plus clairs que j’ai lus pour les custom post type :-P les autres que j’ai pu trouver n’évoquent jamais l’alliance custom post type + custom field ! J’aurais du faire ça depuis longtemps au lieu de m’embourber dans l’intégration de custom meta box et tout le tintouin

    Merci JBJ :-P

  32. xavierx said:

    I need some help.
    I follow the first step without problems but in the time to add the custom fields I have this error

    Warning: Cannot modify header information – headers already sent by (output started at /home/buyspeci/public_html/wp-content/themes/jq/functions.php:43) in /home/buyspeci/public_html/wp-includes/classes.php on line 1601

    Any idea about how to fix them?

  33. steve said:

    Hey guys. this is a great post and awesome website for wp. I implemented this with success, the only stumbling block is how can I insert the content of the page I created to display the custom types

    I created the page template and created 2 coupons. I created a page called coupons, the title is “my coupons” and put some content and chose the coupon page template

    When I go to this page I can see the title “My coupons” and the 2 coupons I created but unfortunately I cannot see the content of my page.

    Has anybody been able to find a solution to this?

    Thanks a lot for your help

Leave a Reply

Your email address will not be published. Required fields are marked *

Please respect the following rules: No advertising, no spam, no keyword in name field. Thank you!