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" );

5 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.

  3. This totally saved the day. Put the function in your functions.php or whatever partial. Then, call it where you would usually call get_month_link().

    Probably something like this:

    echo '<a href="' . eh_get_post_type_date_link( 'post_type_here', 2014, 2 ) .'" rel="nofollow">' . 'February '. '</a>';

Leave a Reply

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