Custom Post Type Yearly/ Monthly Archive

Custom post type yearly/ monthly archive

In order to do what you require, you need to modify Wordpress rewrites to be able to capture the year/month/etc post data for a custom post type.

You may do this with the following code:

/**
* Custom post type date archives
*/

/**
* Custom post type specific rewrite rules
* @return wp_rewrite Rewrite rules handled by Wordpress
*/
function cpt_rewrite_rules($wp_rewrite) {
$rules = cpt_generate_date_archives('news', $wp_rewrite);
$wp_rewrite->rules = $rules + $wp_rewrite->rules;
return $wp_rewrite;
}
add_action('generate_rewrite_rules', 'cpt_rewrite_rules');

/**
* Generate date archive rewrite rules for a given custom post type
* @param string $cpt slug of the custom post type
* @return rules returns a set of rewrite rules for Wordpress to handle
*/
function cpt_generate_date_archives($cpt, $wp_rewrite) {
$rules = array();

$post_type = get_post_type_object($cpt);
$slug_archive = $post_type->has_archive;
if ($slug_archive === false) return $rules;
if ($slug_archive === true) {
$slug_archive = $post_type->name;
}

$dates = array(
array(
'rule' => "([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})",
'vars' => array('year', 'monthnum', 'day')),
array(
'rule' => "([0-9]{4})/([0-9]{1,2})",
'vars' => array('year', 'monthnum')),
array(
'rule' => "([0-9]{4})",
'vars' => array('year'))
);

foreach ($dates as $data) {
$query = 'index.php?post_type='.$cpt;
$rule = $slug_archive.'/'.$data['rule'];

$i = 1;
foreach ($data['vars'] as $var) {
$query.= '&'.$var.'='.$wp_rewrite->preg_index($i);
$i++;
}

$rules[$rule."/?$"] = $query;
$rules[$rule."/feed/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$rule."/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$rule."/page/([0-9]{1,})/?$"] = $query."&paged=".$wp_rewrite->preg_index($i);
}
return $rules;
}

You will notice that I have hard-coded news in to the $rules = cpt_generate_date_archives('news', $wp_rewrite); portion of the code. You can change this as needed.

With this code, you should be able to navigate to http://yoursite.com/news/2013/02/ and receive an archive listing for that specific post type for that specific time.

For completeness, I will include how to generate a monthly archive widget in order to utilize this.

/**
* Get a montlhy archive list for a custom post type
* @param string $cpt Slug of the custom post type
* @param boolean $echo Whether to echo the output
* @return array Return the output as an array to be parsed on the template level
*/
function get_cpt_archives( $cpt, $echo = false )
{
global $wpdb;
$sql = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_type = %s AND post_status = 'publish' GROUP BY YEAR($wpdb->posts.post_date), MONTH($wpdb->posts.post_date) ORDER BY $wpdb->posts.post_date DESC", $cpt);
$results = $wpdb->get_results($sql);

if ( $results )
{
$archive = array();
foreach ($results as $r)
{
$year = date('Y', strtotime( $r->post_date ) );
$month = date('F', strtotime( $r->post_date ) );
$month_num = date('m', strtotime( $r->post_date ) );
$link = get_bloginfo('siteurl') . '/' . $cpt . '/' . $year . '/' . $month_num;
$this_archive = array( 'month' => $month, 'year' => $year, 'link' => $link );
array_push( $archive, $this_archive );
}

if( !$echo )
return $archive;
foreach( $archive as $a )
{
echo '<li><a href="' . $a['link'] . '">' . $a['month'] . ' ' . $a['year'] . '</a></li>';
}
}
return false;
}

To use this function just supply the slug of the custom post type, ie: get_cpt_archives( 'news' ). This will return an array of unique Year/Dates/Links, ie:

Array
(
[0] => Array
(
[month] => February
[year] => 2013
[link] => http://yoursite.com/news/2013/02
)

[1] => Array
(
[month] => January
[year] => 2013
[link] => http://yoursite.com/news/2013/01
)

)

You can loop through these with a foreach and output them however you want.

Alternatively, you can use get_cpt_archives( 'news', true ) which will automatically echo each item wrapped in an <li> linking to its specific archive.

The formatting of the output is not exactly what you wanted, so you will have to tweak it a bit to get it to display in the

Year
Month
Month
Year
Month

format that you require.

I hope this helps.

Date archives for custom post type

There are many examples on the Internet similar as your, but the problem is that although wp_get_archive() will create a list of custom post type archives, the links still points to the default post type. This is because Wordpress do not generate rewrite rules for the archives of the custom post type, you will have to manually create them. Here is an example of how to generate rules for yearly, monthly, and daily archives. It also shows how to convert links with get_archives_link filter. Be sure to add 'has_archive' => true to register_post_type() array of arguments and to flush the rewrite rules by visiting the settings->permalinks page in admin.

functions.php

add_filter( 'getarchives_where', 'getarchives_where_filter', 10, 2 );
add_filter( 'generate_rewrite_rules', 'generate_events_rewrite_rules' );

function getarchives_where_filter( $where, $args ) {

if ( isset($args['post_type']) ) {
$where = "WHERE post_type = '$args[post_type]' AND post_status = 'publish'";
}

return $where;
}

function generate_events_rewrite_rules( $wp_rewrite ) {

$event_rules = array(
'events/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$' => 'index.php?post_type=events&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]',
'events/([0-9]{4})/([0-9]{1,2})/?$' => 'index.php?post_type=events&year=$matches[1]&monthnum=$matches[2]',
'events/([0-9]{4})/?$' => 'index.php?post_type=events&year=$matches[1]'
);

$wp_rewrite->rules = $event_rules + $wp_rewrite->rules;
}

function get_archives_events_link( $link ) {

return str_replace( get_site_url(), get_site_url() . '/events', $link );

};

sidebar.php examples

add_filter( 'get_archives_link', 'get_archives_events_link', 10, 2 );

wp_get_archives( array( 'post_type' => 'events' ) );
wp_get_archives( array( 'post_type' => 'events', 'type' => 'yearly' ) );
wp_get_archives( array( 'post_type' => 'events', 'type' => 'monthly' ) );
wp_get_archives( array( 'post_type' => 'events', 'type' => 'daily' ) );

remove_filter( 'get_archives_link', 'get_archives_events_link', 10, 2 );

How to add year and month under Custom Post Type Archive (site.com/post_type/2013/07)?

I did this in past with help of plugin, Look at the screenshot first, You will get exact idea how to implement it :)

Custom Post Type Permlinks



Related Topics



Leave a reply



Submit