Question

If I have a custom post type named 'my_type', how can I get Wordpress to make date-based archives, for example:

mysite.com/my_type/2010/
mysite.com/my_type/2010/07/
mysite.com/my_type/2010/07/28/

I'm looking for tips both on creating the rewrite rules and on linking the urls to templates.

Thanks!


Update: I've tried the following in my functions.php (EVENT_TYPE_SLUG is a constant defined elsewhere):

function event_rewrite_rules() {
    global $wp_rewrite;
    $new_rules = array(
        EVENT_TYPE_SLUG."/([0-9]{4})/([0-9]{1,2})/$" => 'index.php?post_type=event&year='.$wp_rewrite->preg_index(1).'&monthnum='.$wp_rewrite->preg_index(2),
        EVENT_TYPE_SLUG."/([0-9]{4})/$" => 'index.php?post_type=event&year='.$wp_rewrite->preg_index(1),
    );
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'event_rewrite_rules');

the rewrite rules show up in $wp_rewrite-> rules, but when I navigate to those pages I get a 404 error. If I manually navigate to mysite.com/index.php?post_type=event&year=2010, I get redirected to mysite.com/2010?post_type=event

Was it helpful?

Solution 2

OK ... took some time but I figured this out (there may be more elegant solutions out there).

1) Create a standard wordpress page to serve as the archive page (and to give me access to the template). I defined the page's slug as a constant (EVENT_ARCHIVE_BASE) so that it's just hard-coded in one place and referenced everywhere else.

2) Make custom rewrite rules that catch that page's urls and redirect them to the page:

function event_date_queryvars($qvars) {
    array_push($qvars, 'eyear', 'emonth');
    return $qvars;
}
add_filter('query_vars', 'event_date_queryvars');

function event_date_rewrite_rules() {
    // Adds rewrite rules for date-based event archives
    global $wp_rewrite;
    $new_rules = array(
        EVENT_ARCHIVE_BASE."/([0-9]{4})/([0-9]{1,2})/?$" =>
            "index.php?pagename=".EVENT_ARCHIVE_BASE."&eyear=".$wp_rewrite->preg_index(1)."&emonth=".$wp_rewrite->preg_index(2),
        EVENT_ARCHIVE_BASE."/([0-9]{4})/?$" => "index.php?pagename=".EVENT_ARCHIVE_BASE."&eyear=".$wp_rewrite->preg_index(1),
    );
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'event_date_rewrite_rules');

3) At the top of my page template, I check for the custom query vars and build the page accordingly. (I should have been able to use the built-in year and monthnum, but couldn't get them to work properly. Future troubleshooting):

// Was the page called with a specific year, month, or just plain?
$year = get_query_var('eyear');
$monthnum = sprintf('%02d', get_query_var('emonth'));
if ($monthnum) {
    $list_type = 'Month';
    $monthname = $month[$monthnum];
    $heading = "Events from $monthname, $year";
} elseif ($year) {
    $list_type = 'Year';
    $heading = "Events from $year";
} else {
    $list_type = 'AllPast';
    $heading = get_the_title();
}

Thanks for the help, and hope this is useful for someone else! Let me know if you have a simpler/built-in way to do this.

OTHER TIPS

Benj I think WordPress automatically creates archives for custom post type

I managed to find a more elegant/built-in solution.

The trick is in the "post_type=article" parameter. If you create a rewrite like so:

'(articles)/([0-9]{4})' => 'index.php?post_type=article&eyear=' . $wp_rewrite->preg_index(2)

This will then keep your URL structure, but go through the default 'archive' template. Then you steal the template away from the default to your own archive template. (for instance 'archive-articles.php')

This function accomplishes this (works for me):

add_action("template_redirect", 'my_template_redirect');

// Template selection
function my_template_redirect()
{
    global $wp;
    global $wp_query;
    if ($wp->query_vars["post_type"] == "article")
    {
        if (have_posts())
        {
            include(TEMPLATEPATH . '/archive-articles.php');
            die();
        }
        else
        {
            $wp_query->is_404 = true;
        }
    }
}

You'll still need to create your own methods to handle the get_query_var()'s for the year/month/day, but at least you don't need to create a custom page template.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top