Pinterest Stumbleupon Whatsapp
Ads by Google

custom post typesOne of the advantages to using WordPress is its sheer flexibility. Version 3 introduced the concept of Custom Post Types to extend the built-in functionality.

Let’s take a look today at what you could do with them, as well as a quick practical example of how to create an events listing using a Custom Post Type called Event.

What Are Custom Post Types?

Typically, a WordPress blog consists of three types of content – blog posts, blogroll links, and static pages. Most of us are familiar with the fact that pages should be used for things like about me or contact information, whilst regular posts go to your blog. But beyond that, what if you want to add another special kind of content that doesn’t really fit into the chronological order of the blog and certainly isn’t static – like events? That’s where custom post types come in.

A fairly common request for club or group sites is to have some kind of events calendar. One solution that could be applied is to create a separate Events category, and just post everything in there. The problem with this is they’ll be displayed in the main blog timeline, and we really ought to separate the two concepts entirely.

For that purpose, let’s create a new post type called event, which will have it’s own separate section of the admin interface.

Create A Custom Post Type In WordPress

We’ll do this by adjusting your theme files directly. You could achieve the same effect through a plugin, but to demonstrate the concept and practice it’s just easier to write them directly.

Ads by Google

Open up your theme’s functions.php file, stored in the theme folder inside wp-content/themes. At the end of the file, add this code:

add_action('init', 'events_init');

function events_init() {
	$args = array(
		'labels' => array(
			'name' => __('Events'),
			'singular_name' => __('Event'),
		),
		'public' => true,
		'rewrite' => array("slug" => "events"), 
		'supports' => array('thumbnail','editor','title','custom-fields')
	);

	register_post_type( 'events' , $args );
}

Be sure to do this before the closing php tag. Take a while to read over the code, but essentially it’s just declaring some properties (like labels for the interface), how the URLs (rewrites) should be handled, and what particular features this post-type supports (in this case thumbnails, a content editor for the event description, an event title, and custom fields).

That’s it, now if you save your theme and reload your blog, assuming you don’t have any errors you should now see a new events section on your admin sidebar.

custom post types

Add some example events now, and create a custom field called ‘date’ to indicate when the event is.

custom post types wordpress

Note that we need to use custom fields to specify the actual date of the event rather than the date of the post, because the date of the post is when it will be published. Since you’d presumably be adding events that will occur in the future, setting the publishing date to the actual event date would be useless.

If you try to view the event at this point, you may get a 404 error. This is because WordPress needs to regenerate your Permalink structure to account for this new post type. Head over to the Permalinks settings page, make sure it’s set correctly as sometimes it can go back to defaults, and save. You should now be able to view the individual event post.

Create A Special ‘Events Listing’ Page, Ordered By Date

Now that you have all these fantastic events in your blog, it would be nice to actually list them somewhere. For that, we will create a special page template, so you can then add that page to your regular menu items alongside About or Contact.

First, make a copy of your page.php or index.php if you don’t have one. Rename it custom-events-template.php or something similar. Open it up and add this to the very start of the file. This tells WordPress it’s a special page template, and will let you select it in the templates drop down.

<?php

/**
* Template Name: Events Page
*/

?>

Next, find the line that’s similar to this:


<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

and just before it, add this:


<?php query_posts( 'post_type=events'); ?>

You should be able to see pretty simply what we’re doing here if you followed the last tutorial on making your own widgets – we’ve created a new query, and simply restricted it to be our new event post type.

To use this special page template, just create a new Page, name it whatever you like, and choose the template from the page attributes box. You needn’t add any content to this page, just publish and view it. With any luck, it will display your Events.

Let’s make one more adjustment to the query – to show events in order of the actual event date, rather than the date the event was published. To do this, replace the query with this:


<?php query_posts( 'post_type=events&meta_key=date&orderby=meta_value&order=ASC'); ?>

Also, it would be helpful to display the date for the event in the actual post. Add this just after the_content(); function in the template:


<?php								
$date = get_post_meta($post->ID, 'date', true);				
if ($date){					
echo 'This event will be held on: '.$date;				
}				
?>

That little snippet will attempt to grab the event date from the meta, and display it if it exists.

Here’s how the final product looks on my new events page, sorted by date and displaying the date of the event on the listing:

custom post types

Extra Homework

When we created the event post type, we added support for featured thumbnails. Use the tutorial I wrote last time to grab and display this image on the events listing.

Conclusion

I hope this shows you just how easy it is to extend WordPress functionality beyond the basic Posts and Pages. Can you think of any other post types that you might want to use? How about ‘asides’ for your sidebar when you have something to say but it doesn’t warrant a full post?

Anyway, let me know in the comments if you’re having problems or you’ve tried custom post types on your blog, and make sure you check out the rest of the WordPress tutorials on MakeUseOf.com.

  1. najboss
    February 8, 2015 at 8:50 pm

    thank you every thing it's working fine on my custom template and so happy to find your site in this big result of search

  2. James Bruce
    August 23, 2011 at 9:27 am

    so sorry for the late reply lisa, your comment got lost in my daily inbox deluge. Just remove the , so it looks like:

    'rewrite' => array("slug" => "events"),

    I'm not sure how that got in there, but looks like the code in my article got broken by WordPress when I posted. good catch, will fix now. 

  3. Gort
    July 24, 2011 at 8:54 pm

    Hello, getting the following error when I add your code to functions.php:  Parse error: syntax error, unexpected ';', expecting ')' in /wp-content/themes/xtort/functions.php on line 166

    Any ideas?

    • James Bruce
      July 27, 2011 at 8:27 am

      Can you post the full file at pastebin.com or something Gort? Difficult to tell without seeing the whole thing. 

  4. Mark Mulder
    July 22, 2011 at 6:42 am

    One thing  you forgot to mention which I found out the hard way, is in order for you to be able to create your own listing page for your CPT as described in this manner, you MUST set 'archive' to 'false' in your definition of the CPT inside functions.php. If it's set to 'true', this listing page will NOT be found, and WP will try to look for 'archive-cpt_name.php' instead, and fall back on 'archive.php' if that is missing.

    • James Bruce
      July 27, 2011 at 8:27 am

      Hmm, I didn't have that problem in the next custom post types tutorial I wrote - I'm not sure what you mean by listings page - surely you would want to be able to customize via archive-custom.php? If you set archive to false, what template does it then use?

  5. Matt
    July 12, 2011 at 8:44 am

    Hi James,

    I was wondering could you use this same methodology to build a products information database?  For example if I run a site about cameras,  would it be possible to create a detail pages with the specifications and such?  Perhaps a follow up post expanding the custom post type concept into other areas would be good :)

    • James Bruce
      July 12, 2011 at 12:34 pm

      That's a great idea matt. It sounds like you're talking about a non-eccommerce site - just wanting to store meta-information about the cameras, right? That should be easy. I'm not sure if it warrants another post though. I guess it could be a kind of tutorial on pulling it all together - custom posts, featured images, custom fields for meta-info, and how to present that all. Good idea, I'll add it the list!

    • Matt
      July 13, 2011 at 8:49 am

      Yes it's the putting it all together that will be interesting.  These kind of simple wordpress hacks are fantastic.  Doesnt have to be Cameras could be applied to anything- car parts, pc components, mobile phones, anything really! more uses than I can think of =D

    • James Bruce
      July 17, 2011 at 6:58 am

      Matt, just to let you know I've written a tutorial and it should be published next week, keep an eye out for it on Sunday. ;) 

    • Msrog
      July 19, 2011 at 7:02 am

      Why can't I see the code in your post, only in the comments?  Makes it hard for me to follow your tutorial, LOL.  Thanks.

    • James Bruce
      July 19, 2011 at 7:56 am

      Seems fine for everyone else. Maybe you have javascript disabled, or are using an incredibly outdated browser. 

    • Msrog
      July 20, 2011 at 9:10 pm

      That's so odd.  I still just see a thin gray bar where the code should be.  I'll see how it looks using Firefox...

      aha!  Now I see it.  Thank you.

    • Matt
      July 20, 2011 at 4:51 pm

      Woop! thanky ou kindly will be on the look out for it this weekend!  Thanks!

  6. BingMeUp Scotty
    July 10, 2011 at 12:40 pm

    lol, another awesome party?? good times

    • James Bruce
      July 11, 2011 at 6:55 am

      Ahh, the hectic life of an MUO writer, I know right?

  7. Soham Chowdhury
    July 9, 2011 at 11:21 am

    Awesome post. MUO rocks as usual!

  8. JohnnyBoy
    July 9, 2011 at 4:41 am

    Thanks for the good post, I have run into the need to create an event listing system a few times. I put your solution to work and it works for me.

    One question - how could we use this solution to set up a system for displaying future, upcoming events, and hiding events that are over? The way I've set up your solution, it shows events in order of oldest to newest. However, I would like to be able to show a number of future, upcoming events, and when an event has happened and is in the past, I would like it to no longer show.

    Thanks again for taking the time to write this helpful tutorial.

    • James Bruce
      July 11, 2011 at 6:50 am

      I dont think you can use the built in query system for this, however you could somewhat easily write a custom SQL function. This *should* work, but I'm afraid I dont have time to test and debug it. 

      global $wpdb;
      $sql = "SELECT * FROM wp_posts, wp_postmeta
      WHERE wp_posts.post_status = 'publish' AND
      wp_posts.post_type = 'event' AND
      wp_postmeta.meta_key = 'date' AND
      wp_postmeta.meta_value >= CURDATE()
      ORDER BY wp_postmeta.meta_value";

      $results = $wpdb->get_results($sql);
      foreach ($results as $result){

      // display logic in here 

      }

      Because you'll be using a custom DB query, most of the regular WP functions such the_permalink() etc wont work. Instead, access the variables directly from the $result object, like $result->post_title. Alternatively, you can pass the ID as an argument into the function if it allows, like get_permalink($result->ID)

      Hope you can do something with that, if not I'll endevour to make a part two showing the homework task and this ;)

    • JohnnyBoy
      July 11, 2011 at 4:54 pm

      Thanks for your helpful reply Bruce, I'll give that custom sql function a shot.

      From some other research I think I have found a way to do this with WP_Query, and by assigning today's date as a variable:

      $todaysDate = date('Y/m/d'); // Get today's date in the right format

      $eventsloop = new WP_Query('post_type=events&meta_key=event_date&meta_compare=>=&meta_value=' . $todaysDate . '&orderby=meta_value&order=ASC');

      have_posts()) : $eventsloop->the_post(); ?>

      So far this seems to work for me. Note that the custom field "event_date" is formatted the same as the date in the variable, Y/m/d .

    • James Bruce
      July 11, 2011 at 8:37 pm

      Oooh, good find. Yes, I didn't know there was a meta compare, but that'll do it!

    • Lisa
      August 31, 2011 at 9:41 pm

      Where would this go?  In the functions.php or in the loop?

    • James Bruce
      September 5, 2011 at 6:06 pm

      Sorry for the late reply Lisa, must have slipped through my inbox. The code Johnny posted is for the loop, so it would go just before the loop in order to customize the query. 

  9. pceasies
    July 9, 2011 at 2:08 am

    The first codebox is wrapping '&' in a span and leaving 'gt' out so it says '&gt' instead of '>'

    • James Bruce
      July 11, 2011 at 6:38 am

      thanks man, fixed

Leave a Reply

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