Events List With Custom Post Types and Taxonomies
45A few weeks back, we put together a way of adding events to WordPress and displaying them in an easy-to-read list. It was simple to maintain and it worked well, but it didn’t take advantage of all WordPress offers.
In this 2-part tutorial, we are going to extend our events list script to set up a new post type purely for the events, and create a new taxonomy for tagging our events. We will then be able to:
- Organize our events easily (e.g. If we’re running WordPress classes, we could label them as Beginner, Intermediate, or Advanced)
- Create templates for event lists and individual events.
- Separate events out of the main post list (So they won’t automatically appear on the homepage anymore).
- Add new events more conveniently in the admin panel (Especially when we add metaboxes in a later post!)
Let’s take a look at the end result (Using the default 2010 theme).
1 – The overall Events page.
2 – Sorting by the “Beginner” tag.
3 – Viewing an individual event.
Look good? Cool, let’s build it (By the end of today’s post, you’ll have taken care of all of the WordPress backend stuff, and set up the automatic Date message on your individual events!)
Setting Up Our Post Type and Taxonomy
We’ll be working in the functions.php file. If your theme doesn’t have one, just make a file with that name and put at the bottom.
Our first step will be to give WordPress the info it needs to make our new post types. Before the closing ?> tag in your file, paste the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Sets up our Events custom post type. */ function pbd_events_init() { // Labels. $labels = array( 'name' => 'Events', 'singular_name' => 'Event', 'add_new' => 'Add New', 'add_new_item' => 'Add New Event', 'edit_item' => 'Edit Event', 'new_item' => 'New Event', 'view_item' => 'View Event', 'search_items' => 'Search Events', 'not_found' => 'No events found.', 'not_found_in_trash' => 'No events found in Trash.' ); // Register the post type. register_post_type('events', array( 'labels' => $labels, 'public' => true, 'supports' => array('title', 'editor', 'custom-fields', 'comments'), 'has_archive' => true )); |
The code above starts by creating a function called pbd_events_init(), which we will hook into place later on.
We then make an array called $labels, where we enter all of the strings that WordPress will use in the admin panel. This way, instead of it saying “Add New Post”, we get “Add New Event”.
The register_post_type() function is what tells WordPress to create our new post type, and as you can see, it’s incredibly simple to use. You can read up on all of the possible arguments it takes on the codex page), but the three (plus labels) we need are:
- public – Enables the Events admin panels in the dashboard, and allows our events to be viewable on the main site (So rather important!)
- supports – Choose which parts of the regular “Add Post” page you want to enable. We choose title and editor (i.e. event name and its description) and comments, as well as custom-fields (to enter the event date). Check out the other possible options on the codex page.
- has_archive – This is a great new addition from WordPress 3.1 meaning that WordPress will create pages that list all of our events in one place. Perfect for having a standalone Events page.
That’s all it took to set up our new post type. Now we just follow a similar process to set up our new taxonomy as well:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Event tag labels. $eventLabels = array( 'name' => 'Event Tags', 'singular_name' => 'Event Tag', 'search_items' => 'Search Event Tags', 'popular_items' => 'Popular Event Tags', 'all_items' => 'All Event Tags', 'edit_item' => 'Edit Event Tag', 'update_item' => 'Update Event Tag', 'add_new_item' => 'Add New Event Tag', 'new_item_name' => 'New Event Tag Name' ); // Event tags. register_taxonomy('event_tags', 'events', array( 'label' => 'Event Tags', 'labels' => $eventLabels )); } add_action('init', 'pbd_events_init'); |
The $eventLabels array does for our taxonomy exactly what the $labels array did for the post type.
We then use the register_taxonomy() function to tell WordPress to set it up. The first parameter (‘event_tags’) will be the name of our taxonomy, and the second (‘events’) is the name of our post type (i.e. tell WordPress that we only want these tags to apply to events, not to regular post and pages).
And again, this function can take a lot more arguments than we have used. All we specified were the labels, but there are a lot of other options available too (e.g. if you wanted it to function like categories, rather than tags).
Lastly, we close off the pbd_events_init(); function and hook it into place (These functions won’t work if you call them any sooner. That’s why we use the add_action() line to hold back on running this all until WordPress is loaded).
And that’s the core of our work done! If you save this, you’ll now see an “Events” section in your admin panel, and if you publish events, you’ll see them displayed using your site’s archive.php and single.php templates. Of course, you still aren’t sorting events by their date yet, and you want to make use of their own templates.
Adding Dates to Events
This will work identically to before, where we use the custom fields section to add new field named “Date” with a value of the event’s date, in the form: mm/dd/yy
For example, an event on the 4th of April:
Displaying the Date on Individual Events
We want to automatically insert the date of the event on the event’s page. There are two ways that we can do this:
- 1 – Create a new template file called single-events.php . This file would then be used in place of single.php to display any of our individual events.
- 2 – Add a filter to the content of the event to automatically insert our date for us.
If you wanted your events to appear drastically different to your regular posts (e.g. new formatting, listing all events in the sidebar, adding a list of our event tags etc.), you would definitely use the first option.
In our case though, we want them to appear the same but have the date highlighted at the top. For that, we can use a filter (Meaning we don’t need to recreate a whole template, and it makes things easy to maintain in the future).
Add the following to your code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * Add Event Date before the description on single post pages. */ function pbd_add_event_info($content) { if ( 'events' == get_post_type() ) : // Get the date of the event in a nicer-to-read format. global $post; $date = get_post_meta($post->ID, 'Date', true); $date = date_create($date); $date = date_format($date, 'jS F, Y'); // Add the message before the post. $content = '<p class="events-info"><strong>Event Date</strong>: '. $date .'</p>' . $content; endif; return $content; } add_filter('the_content', 'pbd_add_event_info'); |
Now let’s take a look at what this does. A filter in WordPress is a way of taking some content that WordPress is going to use, adapting it, and then giving it back for WordPress to carry on.
In our case, we’re letting WordPress prepare the content of the post (i.e. ‘the_content’, line 19), but before it prints it out, our pbd_add_event_info() filter pokes its head in.
In that function, we first check if this content is for an event post (If it’s for a regular post/page, we don’t want to do anything).
Assuming it is an event, we then want to get the event’s date. With lines 8 and 9, we can get the content of the Date custom field. Instead of printing out 04/04/11 though, it would be nicer to say 4th April 2011.
Line 10, date_create(), turns 04/04/11 into a DateTime object that PHP can use, and date_format() then turns that into a readable version for us.
Line 14 is where we adapt the content we were given. We create a new paragraph (With the class “events-info” so that we can style it later), insert the date inside of it, and then append the original content from WordPress (If we didn’t add that back on, the final result wouldn’t have the event’s actual content).
Lastly, we use return $content; to send the result back.
The final thing do is add some new styles to your style.css file to make this appear differently, e.g. (To steal WordPress’ “Updated” message styles!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .events-info { background: #FFFFE0; border: 1px solid #E6DB55; padding: 8px; } .events-info a:link, .events-info a:visited { color: #000; font-weight: bold; text-decoration: none; } .events-info a:hover, .events-info a:active { text-decoration: underline; } |
Now go check out your events. You’ll see the date clearly highlighted in yellow right at the top of the post. And that will happen automatically on every one of your events, without any extra work from you.
In the next post, we will look at the overall Events page. We’ll adapt the query from our original post to list events in order, and we’ll use our event_tags taxonomy to let users sort events into the ones they’re most interested in.
Stay tuned!
Enjoy this post? You should follow me on Twitter!
I knew that 3.1 had introduced archives, but I didn’t know about has_archive. Research time ;)
Thanks Michael!
It’s probably my favorite new feature. Custom post types are fantastic, but this was always a giant crutch on them that put me off using them. has_archive works ridiculously simply (The next post is all about the archives, but it’s exactly like what you’re used to with all WP templating :D )
After seeing this I immediately went and researched it and had to go write a simple post up myself for WP-Mods.
Ah that’s cool, looking forward to reading it! :D
I don’t know if I ever mentioned it, but I hacked together something similar—using custom post types—after you published your original event calendar post. It’s running over at Fantasy Folder: http://www.fantasyfolder.com/
Ah that’s awesome Matt! That’s the sort of thing I’ve been setting up with clients as well, though never got around to writing here. It looks great on Fantasy Folder! (So much easier to read than a calendar I think, love the list format :) )
It took a bit of thinking to get the sidebar list right. I eventually settled on having a “lag time” before an item would be taken out of the upcoming section and moved into the “recent events,” so an item would remain visible a little longer than immediately after its release. That was a bit of pain to implement…
One of my clients wanted that too, though that was back when I was still using the old (Now broken) code. Haven’t tried it with the new queries yet. Did you get it working in the end?
Michael,
Thanks for the post; I’ll be excited to see the others. It’s nice to have alternatives to many of the plugins that are out there. They have improved, but I don’t believe there are any calendar plugins that have reached the level of Gravity Forms for example.
No problem Bill, thanks for letting me know you liked it! I agree, the calendar plugins out there aren’t that great. I think too many go down the route of thinking that an actual calendar layout has great advantages for a blog. When you’re working with a small space (like a sidebar), it’s just a poor choice I think.
Michael,
Why are you still using custom fields instead of metaboxes?
Haha, are you reading my mind? One thing at a time in the posts though. Metaboxes will be the last step in this all. :)
Excellent explanation. Thanks for the great tuts.
This is a great series of posts. Although there is a fairly steep learning curve for web designers new to WordPress. However, I challenge anyone out there to say that setting up Events as a module in any content management system for any agency who’ve designed and built there own would be easier than this once you know your way around. WordPress makes it much easier to achieve this.
Definately agree that getting away from custom fileds is key for ease of use for the end client so look forward to seeing your solution for this.
That’s true, this is definitely a fairly complex topic for new users. The idea was to break down every step though, so going through something like this should help them get better.
Like you said though, still complicated (Things like the hooks would need an entire post to explain, which definitely makes this one harder to understand :( )
Awesome though. Should have the metabox post up next week! :)
Waooo nice share…
CTRL+D eheheheheh
Sincerely
From Indonesia
Thanks for covering this topic. I will implement it on one event WP theme I am working on.
Excellent post. Just this week I started making something like this! I’l gladly use the tips I learned from reading the post and the comments
Custom Post types are amazing :)
Using them with taxonomies and custom meta-boxes now.
Result later on!
wow,,,
nice share man,, :)
yeah very well said we should Create templates for event lists and individual events..thanks for the nice tip buddy,
Just this week I started making something like this! I’l gladly use the tips I learned from reading the post and the comments
Coo! Thanks for the tips!
Thanks. Been looking for some info on how to do this for ages :)
Recommended knowledge for me. Can you guide me what are the plug-ins to do on site optimization to a wordpress site?
Really Recommended Knowledge for me. I am not so familiar with PHP. But I would take a try as you guides
I’ve been using WordPress for a long time but I’ve only just started diving into using it more as a CMS and this really hit the nail on the head for a project I’m doing. Thanks SO much! Just one question though, if I wanted to have a list of events appear in the sidebar, say the upcoming 3 or 5, how would I go about doing that? I’d like to have the titles appear (linked to the full event posting) with the date and another link below those titled “All Events” that links to the events page. Any pointers in how to accomplish that?
Thank for tutorial. ^ ^
Anxiously awaiting the next installment :)
Thanks for covering this topic.
A really interesting post and for me and at the moment a relevant item for me to come across. This is something that I am wanting to create so will be perfect. I think that the post is so in depth and precise that I will be able to do this quite easily. Little details like event dates etc are really useful and I think that this is something I will be using quite a bit.
more more more!
Terrific series of posts. I’m working my through them for an association that I’m involved with. The one thing I haven’t grokked just yet is how get the events displayed on a single-events.php template in case I do want it to look much different than a usual post…unless that’s covered in the next part ….
Excellent explanation. Thanks for the great tuts.
Super helpful post! This is EXACTLY what I was looking for! I’m going to give the custom post type for events a shot, but this is working perfectly for me right now. Thank you!
Whoops! Actually meant to post that comment above to http://www.problogdesign.com/wordpress/an-updated-wordpress-events-list/
I am using your tuts for the custom page I am making..:)
Yea.. i think i’m the only idiot around here … i get something like this when i want to add that in functions..
Parse error: syntax error, unexpected T_FUNCTION in /home/public_html/mydomain/wp-content/themes/blue/functions.php on line 1
Maybe you can post full code from functions.php .. i want to add it to my blog but i’m so noob.
About this topic, I have been lately in your blog once or twice now. I just wanted to say hi and show my thanks for the information provided.
how to become a pilot
If you ever hear the particular label Dior christian dior sunglasses Dior totes can be a useful plus stunning add-on that will every wardrobe
This site is an extremely useful site – I just hate it when people abuse these sites with useless comments!!!!!
How can we not display past events?
I’ve tried implementing this. In order to get “Events” to show up on my Dashboard, I had to place it at the top of my functions.php file. Now it’s there, and I can create events. However, when I try to view the events, I get a 404 error. Any ideas?
Nevermind, I figured this out. I already had an Events page that I was leaving up, until I finished this. I was sitting there trying to figure out why my single event wouldn’t display, when I noticed something familiar in the URL. I deleted the existing Events page, and wallah… it works.
I am happy to find this post Very useful for me, as it contains lot of information. I Always prefer to read The Quality and glad I found this thing in you post. Thanks