Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Need help with CPT/Taxonomy set up WordPress


I have a post type called Events. Each Event is going to be broken up into a year/month structure.

The archive (or template) page will have two levels of navigation. The year and Month.

Clicking on the Month will show all of the events happening in that month.

A few things that need to happen:

- Past events should not be displayed and should be removed form the list automatically.
- The first page that loads will display the most recent upcoming events. So if there are no events in December 2012, then the Events in January 2013 will display first.

What would be the best structure for me to set this up?

I have attached an image of what the pages will essentially look like

Please let me know if you need any clarification.

Answers (2)


phppoet answers:

Only way to do this is by setting up a category hierarchy or tag hierarchy if you want to this with custom post type . You can add category support to your custom post type in this way .

class my_events_type {

public function __construct()




public function register_post_type() {







'hierarchical' => false,

'labels' => array


'name' => _x( 'events Tags', 'taxonomy general name' ),

'singular_name' => _x( 'events Tag', 'taxonomy singular name' ),

'search_items' => __( 'Search events Tags' ),

'all_items' => __( 'All events Tags' ),

'edit_item' => __( 'Edit events Tag' ),

'update_item' => __( 'Update events Tag' ),

'add_new_item' => __( 'Add New events Tag' ),

'new_item_name' => __( 'New events Tag Name' ),

'menu_name' => __( 'events Tags' ),


'show_ui' => true,

'query_var' => true,

'rewrite' => array('slug' => 'events-tag', 'with_front' => true),



register_taxonomy('events_cat','events', array(

'hierarchical' => true,

'show_ui' => true,

'query_var' => true,

)); // add unique categories to portfolio section

$args = array (

'labels'=> array (

'name' => 'eventss',

'singular_name' => 'events',

'add_new' => 'Add New events',

'add_new_item' => 'Add New events',

'edit_item' => 'Edit events',

'new_item' => 'Add new events ',

'view_item' => 'View events',

'search_items' => 'Search events',

'not_found' => 'no events found ',

'not_found_in_trash' => 'no events found in trash'


'query_var' => 'eventss',

'public' => true,

'supports'=> array( 'title', 'editor', 'thumbnail','excerpt'),

'taxonomies' => array('events'),





add_action('init', function() {

new my_events_type();

} );

then you need to css/restructure your themes category.php and tag.php files .

Anthony Moore comments:

Would it work if I had a category for Month instead of having tags?

I guess my question would be how to get the navigation to filter the posts correctly.

phppoet comments:

i have updated code with errors . add this to your themes functions.php file . after putting this you will see category and tags tab for your custom post type. Now you need to structure and css your category.php so that it can display in this manner.

phppoet comments:

yes it will work . just create categories like 2012,2013,2014 and then create subcategory like january , february ........... for each category and post your events with that subcategories .

Anthony Moore comments:

Sorry I guess my question was not as clear as I would have hoped.

I know how to set up a post type and taxonomies.

I am more concerned about how to set up that navigation for Year and Month to display the right events.

So lets say I have a taxonomies called "event-year" and "event-month". The "event-month" taxonomy will never change as it will always be January to December.

So when I create a new event post I select the year and the month.

How would I set up the navigation for Year and Month to display the correct posts?

phppoet comments:

I don't know any other way to do this . Wordpress do have certain limitations. if you publish all your events under 2012/january then you just need to edit your category.php on how it outputs it . you can edit in a way you want it . you must need to implement some basic menu style css in you category.php .


Dbranes answers:

Hi, you can also use fx:

$sql = "SELECT DATE_FORMAT(post_date, '%Y') as post_year
FROM {$wpdb->posts}
WHERE post_type = 'events' AND post_status = 'publish' AND post_date >= CURRENT_DATE
GROUP BY post_year
ORDER BY post_year ASC";

$years = $wpdb->get_results($sql,ARRAY_A);


to get the array of all the years that are greater or equal to current date.


$sql = "SELECT DATE_FORMAT(post_date, '%m') as post_month, DATE_FORMAT(post_date, '%Y') as post_year, ID as post_id
FROM $wpdb->posts
WHERE post_type = 'events' AND post_status = 'publish' post_date >= CURRENT_DATE
GROUP BY post_year, post_month
ORDER BY post_year ASC, post_month ASC";

$data = $wpdb->get_results($sql,ARRAY_A);


to get the archive array with year/month/post_id.

Then you can loop this arrays to fetch the corresponding post data from the post_id.

Anthony Moore comments:

If I was to take this route, would I still need to create taxonomies? or I simply just change the post date to the date of the actual event?

Dbranes comments:

this method assumes the post_date is the actual event date ;-)

So if you wanted an url like this:

then you could fx. create a page with the slug "celebrities" and a corresponding page template and add fx this code:

add_filter( 'query_vars', 'my_events_query_vars' );
function my_events_query_vars( $query_vars ){
$query_vars[] = 'theyear';
$query_vars[] = 'themonth';
return $query_vars;
function my_events_rewrite_rules( $rules ) {
$newrules = array();
$newrules['^celebrities/archive/([0-9]{4})/([0-9]{1,2})$'] = 'index.php?pagename=celebrities&theyear=$matches[1]&themonth=$matches[2]';
$newrules['^celebrities/archive/([0-9]{4})$'] = 'index.php?pagename=celebrities&theyear=$matches[1]';
/* debug:
echo "<pre>";
print_r($newrules + $rules);
echo "</pre>";
return $newrules + $rules;

in the file functions.php, in your current theme directory.

Then in the page template you can catch the year/month variables with

echo "theyear: ". get_query_var('theyear');
echo "themonth: ".get_query_var('themonth');


is actually in our case:

Dbranes comments:

ps: and you have to "save the permalinks" to activate these new rewrite rules.