WordPress How To: Monthly,Yearly and Daily Archives for Custom Post Types

Enable yearly and monthly archives for WordPress custom post types by unsetting old conflicting rewrite rules before adding new ones — the step most guides miss.

WordPress How To: Monthly,Yearly and Daily Archives for Custom Post Types

For a plugin I was creating I needed Yearly and Monthly archives with my own slug. Even after setting the rewrite rules it was not working. After much debugging and several hours later I finally figured it out. I’ll explain how you could do the same bellow.

Spoiler Alert: For the impatient, it was as simple as removing the old rules that are not setting the post type before adding the new rules :)

I’m going to assume that you have already familiar with Custom Post types. If you are not read http://codex.wordpress.org/Post_Types and then come back. Most important are Step 5 and Step 6. Other steps are typical for any plugin or theme using custom post types.

Step 1: Register the post type Read more about registering custom post types at register_post_type( ‘my_class’, array( ‘public’ => true, … ‘has_archive’ => true, ) ); Step 2: Add rewrite tags and permalink structure $event_structure = ‘/events/%year%/%monthnum%/%my_class%’; $wp_rewrite->add_rewrite_tag(“%my_class%”, ‘(.+?)’, “my_class=”); $wp_rewrite->add_permastruct(‘my_class’, $event_structure, false); Step 3: Add post_type_link and rewrite_rules_array filters add_filter(‘rewrite_rules_array’, ‘my_class_add_rewrite_rules’); add_filter(‘post_type_link’, ‘my_class_post_type_link’, 10, 3); Step 4: Return a proper permalink function my_class_post_type_link($permalink, $post_id, $leavename) { $post = get_post($post_id);

$rewritecode = array( ‘%my_class%’, ‘%year%’, ‘%monthnum%’ );

if ($post->post_type == ‘my_class’ && ‘’ != $permalink) {

$ptype = get_post_type_object($post->post_type);

$start = time(); $end = time();

$meta = get_post_custom($post->ID); // This is where I store when the class starts if (isset($meta[“my_class_start”]) && isset($meta[“my_class_start”])) { $start = strtotime($meta[“my_class_start”]); }

$year = date(‘Y’, $start); $month = date(‘m’, $end);

$rewritereplace = array( ($post->post_name == “”)?$post->id:$post->post_name, $year, $month, ); $permalink = str_replace($rewritecode, $rewritereplace, $permalink); } else { // if they’re not using the fancy permalink option }

return $permalink; } Step 5: Add rewrite rules function my_class_add_rewrite_rules($rules){ $new_rules = array();

// This is the important bit, unsetting the rules unset($rules[‘classes/({4})/({1,2})/?$’]); unset($rules[‘classes/({4})/?$’]);

$new_rules[‘classes/({4})/?$’] = ‘index.php?year=$matches&post_type=incsub_event’; $new_rules[‘classes/({4})/({1,2})/?$’] = ‘index.php?year=$matches&monthnum=$matches&post_type=incsub_event’; $new_rules[‘classes/({4})/({2})/(.+?)/?$’] = ‘index.php?year=$matches&monthnum=$matches&incsub_event=$matches’;

return array_merge($new_rules, $rules); } Step 6: Don’t forget to flush add_action(‘option_rewrite_rules’, ‘my_class_check_rewrite_rules’); function my_class_check_rewrite_rules($value) { global $wp_rewrite;

//prevent an infinite loop if ( ! post_type_exists( ‘incsub_event’ ) ) return;

if (!is_array($value)) $value = array();

$array_key = ‘events/({4})/?$’; if ( !array_key_exists($array_key, $value) ) { $wp_rewrite->flush_rules(); } $array_key = ‘events/({4})/({1,2})/?$’; if ( !array_key_exists($array_key, $value) ) { $wp_rewrite->flush_rules(); } $array_key = ‘events/({4})/({1,2})/(.+?)/?$’; if ( !array_key_exists($array_key, $value) ) { $wp_rewrite->flush_rules(); } } That’s it. Most important steps are Step 5 and Step 6

Cookies Contact Privacy Policy Terms