Custom Post Type date archive links in WordPress

Custom Post Type date archive links are not supported out-of-box within WordPress (as of 3.6 beta). Nor are CPT date archives, but that’s another post (coming soon). The built-in date archive link functions (get_year_link, get_month_link, get_day_link) only work for Post archives.

Here is a function that will create your date archive links for you. I had a fallback of giving you get_post_type_archive{}, but took it out. If there is ever the case of not having the year, you should just use get_post_type_archive{} directly.

This function also automatically handles any rewrites you have for custom post types. I often use prefixes at work as best practice, and nobody wants eh-events in their URL string!

Let me know if you find a more efficient way of doing this. I’d love to direct to your source, or at least update mine! :)

The Function

/**
 * This allows us to generate any archive link - plain, yearly, monthly, daily
 * 
 * @param string $post_type
 * @param int $year
 * @param int $month (optional)
 * @param int $day (optional)
 * @return string
 */
function EH_get_post_type_date_link( $post_type, $year, $month = 0, $day = 0 ) {
    global $wp_rewrite;
    $post_type_obj = get_post_type_object( $post_type );
    $post_type_slug = $post_type_obj->rewrite['slug'] ? $post_type_obj->rewrite['slug'] : $post_type_obj->name;
    if( $day ) { // day archive link
        // set to today's values if not provided
        if ( !$year )
            $year = gmdate('Y', current_time('timestamp'));
        if ( !$month )
            $month = gmdate('m', current_time('timestamp'));
        $link = $wp_rewrite->get_day_permastruct();
    } else if ( $month ) { // month archive link
        if ( !$year )
            $year = gmdate('Y', current_time('timestamp'));
        $link = $wp_rewrite->get_month_permastruct();
    } else { // year archive link
        $link = $wp_rewrite->get_year_permastruct();
    }
    if ( !empty($link) ) {
        $link = str_replace('%year%', $year, $link);
        $link = str_replace('%monthnum%', zeroise(intval($month), 2), $link );
        $link = str_replace('%day%', zeroise(intval($day), 2), $link );
        return home_url( "$post_type_slug$link" );
    }
    return home_url( "$post_type_slug" );
}

4 thoughts on “Custom Post Type date archive links in WordPress”

  1. Hello, thanks for the post! So, I am guessing you put this in functions.php…I am unclear on what I would put in the sidebar file for my custom post…something like “get_post_type_archive{}”? I tried , but that didn’t work.

  2. This looks really interesting and thank you for sharing! How to do you actually call it? Something like:

    [a href=[?php echo eh_get_post_type_date_link(‘custom-post-type-slug’, ‘yearly’); ?]”]your linked text here[/a]

    Square brackets subbed for angled ones so the comment shows up.

    1. Close! the function call would specify the year, like this: eh_get_post_type_date_link( ‘post-type-slug’, 2014 ). If the month and day are also specified, it will add them in as well.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>