custom post types, wp_get_archives and add_rewrite_rule

I’ve searched to see if anyone came up with a solution to a peculiar problem I’m having but did not find anything that was close to what was happening in my case.

I have two custom post types – let’s call them Diary and Journal. Both have been setup correctly with has_archive to true, rewrite with a same named slug and with_front to false.

Read More

My permalink structure is set with year/month/post-name. I’ve setup place holder pages, with the slugs ‘diary’ and ‘journal’ for each so any posts I make to either types load up fine with archive.php – so if I go to domain/diary/ or domain/journal they load up accordingly. I’m not making any additional templates here – just creating a child theme of twentyeleven and using archive.php.

I needed to use the wp_get_archives to work with the custom post types and got that to work with the added option post_type, I took it a step further and created a custom_wp_get_archives function so that I can customize it’s output as I will need that later on.

Now here is where the problem begins, either with the default wp_get_archive with the added *post_type* option, or using custom_wp_get_archives – the url that gets output by either is domain/year/month which returns a 404 when I go to it. Fair enough, but if I add ‘?post_type=POST_TYPE’ to that/any url generated I get results accordingly – fair enough again.

So I used my custom_wp_get_archives to insert ‘?post_type=POST_TYPE’ into the output url and that worked.

My question is – is there a way to get wp_get_archives to output the correct urls with the conditions stated above?

Also I have looked into add_rewrite_rule as well as generate_rewrite_rules as a fix – ie: domain/post_type_slug/year/month – and followed almost any example I have found here and other places and it’s simply not working. I have flushed the permalinks also – no go.

The code that I have found that seems to be close to what I want it to do with rewriting the rules doesn’t work either here it is:

function register_post_type_rewrite_rules($wp_rewrite) {

$args = array('public' => true, '_builtin' => false);   //get all public custom post types
$output = 'names';
$operator = 'and';
$post_types = get_post_types($args,$output,$operator);

$url_base = ($url_base == '') ? $url_base : $url_base . '/';
$custom_rules = array();

$post_types = implode('|', $post_types);
    $custom_rules = array( "$url_base($post_types)/([0-9]+)/([0-9]{1,2})/([0-9]{1,2})/?$" =>
            'index.php?post_type_index=1&post_type=' . $wp_rewrite->preg_index(1) . '&year=' . $wp_rewrite->preg_index(2) . '&monthnum=' . $wp_rewrite->preg_index(3) . '&day=' . $wp_rewrite->preg_index(4),       //year month day

                            "$url_base($post_types)/([0-9]+)/([0-9]{1,2})/?$"  =>
            'index.php?post_type_index=1&post_type=' . $wp_rewrite->preg_index(1) . '&year=' . $wp_rewrite->preg_index(2) . '&monthnum=' . $wp_rewrite->preg_index(3),          //year month
                            "$url_base($post_types)/([0-9]+)/?$" =>
            'index.php?post_type_index=1&post_type=' . $wp_rewrite->preg_index(1) . '&year=' . $wp_rewrite->preg_index(2)   //year
                        );

$wp_rewrite->rules = array_merge($custom_rules, $wp_rewrite->rules); // merge existing rules with custom ones

return $wp_rewrite;
}

add_filter('generate_rewrite_rules', 'register_post_type_rewrite_rules', 100);

Any clue on any of this will be great.

Related posts

Leave a Reply

1 comment

  1. Custom post types do not have date-based archives by default (by which I really mean they don’t have permalink structures for their date archives). For example:

    www.example.com?post_type=journal&year=2012&monthnum=4
    

    should give you the archive of journals published in April 2012. However,

    www.example.com/journal/2012/04
    

    will probably give you 404 because it doesn’t exist as a re-write rule. You need to add them:

    add_action('init', 'wpse50530_journal_archive_rewrite');
    function wpse50530_journal_archive_rewrite(){
       add_rewrite_rule('^journal/([0-9]{4})/([0-9]{2})/?','index.php?post_type=journal&year=$matches[1]&monthnum=$matches[2]','top');
       add_rewrite_rule('^journal/([0-9]{4})/?','index.php?post_type=journal&year=$matches[1]','top');
    }
    

    will give you the month and year archives. (Please note the above is completely untested). You will need to flush the rewrite rules once after adding this (visiting Settings > Permalink).