–
I have been researching on how to create a date archive for a custom post which has a taxonomy and various terms…
I have had great success with this Stackoverflow answer from walltea however I need some help with modifying it to also take into account taxonomies and its terms…
Is this possible?
–EDIT–
Ok I managed to do this after LOADS of time on it, If you know if a better solution to this then please do share as the way I found is a little bit cumbersome: (again original code curtosy of walltea’s Stackoverflow answer)
1.
In your functions.php place this code: (changing the custom posts types that you have for ‘$cptPart’)
/**
* Custom post type date archives
*/
/**
* Custom post type specific rewrite rules
* @return wp_rewrite Rewrite rules handled by WordPress
*/
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_rewrite_rules($wp_rewrite) {
$rules = array();
$cptPart = "(news_events|live_reports|book_review|readers_digest|publications|jobs)";
$taxonomyPart = "([a-zA-Z_-]+)";
$termPart = "([a-zA-Z_-]+)";
$patterns = array(
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/$taxonomyPart/$termPart",
'vars' => array('post_type', 'year', 'monthnum', 'day', 'taxonomy', 'term')
),
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})/$taxonomyPart/$termPart",
'vars' => array('post_type', 'year', 'monthnum', 'taxonomy', 'term')
),
array(
'rule' => "$cptPart/([0-9]{4})/$taxonomyPart/$termPart",
'vars' => array('post_type', 'year', 'taxonomy', 'term')
),
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/$taxonomyPart",
'vars' => array('post_type', 'year', 'monthnum', 'day', 'taxonomy')
),
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})/$taxonomyPart",
'vars' => array('post_type', 'year', 'monthnum', 'taxonomy')
),
array(
'rule' => "$cptPart/([0-9]{4})/$taxonomyPart",
'vars' => array('post_type', 'year', 'taxonomy')
),
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})",
'vars' => array('post_type', 'year', 'monthnum', 'day')
),
array(
'rule' => "$cptPart/([0-9]{4})/([0-9]{1,2})",
'vars' => array('post_type', 'year', 'monthnum')
),
array(
'rule' => "$cptPart/([0-9]{4})",
'vars' => array('post_type', 'year')
),
);
foreach ($patterns as $pattern) {
$i = 1;
$params = array();
foreach ($pattern['vars'] as $var) {
$params[] = $var . '=' . $wp_rewrite->preg_index($i);
$i++;
}
$query = 'index.php?' . implode('&', $params);
$rules[$pattern['rule']."/?$"] = $query;
$rules[$pattern['rule']."/feed/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$pattern['rule']."/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
$rules[$pattern['rule']."/page/([0-9]{1,})/?$"] = $query."&paged=".$wp_rewrite->preg_index($i);
}
$wp_rewrite->rules = $rules + $wp_rewrite->rules;
return $wp_rewrite;
}
/**
* 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, $taxomony = null, $term = null)
{
global $wpdb;
$conditions = "";
if ($taxomony) {
$conditions .= " AND wtt.taxonomy LIKE %s";
if ($term) {
$conditions .= " AND wt.slug LIKE %s";
}
}
$sql = $wpdb->prepare("
SELECT *
FROM wp_posts p
LEFT JOIN wp_term_relationships wtr ON wtr.object_id = p.ID
LEFT JOIN wp_term_taxonomy wtt ON wtr.term_taxonomy_id = wtt.term_taxonomy_id
LEFT JOIN wp_terms wt ON wtt.term_id = wt.term_id
WHERE post_type = %s
AND post_status = 'publish'
$conditions
GROUP BY YEAR(p.post_date),
MONTH(p.post_date)
ORDER BY p.post_date DESC
", $cpt, $taxomony, $term);
$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;
if ($taxomony) {
$link .= "/" . $r->taxonomy;
if ($term) {
$link .= "/" . $r->slug;
}
}
$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;
}
–
2. In your custom archive file (for example one of mine was archive-publications.php) place this code above the loop:
<?php
function lr_posts_join($join) {
global $taxonomy_global_join;
global $term_global_join;
if ($taxonomy_global_join) $join .= " $taxonomy_global_join";
if ($term_global_join) $join .= " $term_global_join";
return $join;
}
function lr_posts_where($where) {
global $taxonomy_global_where;
global $term_global_where;
if ($taxonomy_global_where) $where .= " $taxonomy_global_where";
if ($term_global_where) $where .= " $term_global_where";
return $where;
}
add_filter('posts_join', 'lr_posts_join');
add_filter('posts_where', 'lr_posts_where');
$extraArgs = "";
if (get_query_var('taxonomy')) {
$taxonomy_global_join = "
LEFT JOIN $wpdb->term_relationships wtr ON wtr.object_id = $wpdb->posts.ID
LEFT JOIN $wpdb->term_taxonomy wtt ON wtr.term_taxonomy_id = wtt.term_taxonomy_id ";
$taxonomy_global_where = " AND wtt.taxonomy LIKE '" . esc_sql(like_escape(get_query_var('taxonomy'))) . "'";
$extraArgs .= "&taxonomy=" . get_query_var('taxonomy');
if (get_query_var('term')) {
$term_global_join = "
LEFT JOIN $wpdb->terms wt ON wtt.term_id = wt.term_id ";
$term_global_where = " AND wt.slug LIKE '" . esc_sql(like_escape(get_query_var('term'))) . "'";
$extraArgs .= "&term=" . get_query_var('term');
}
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$posts = query_posts("post_type=publications&paged=$paged$extraArgs");
$taxonomy_global_join = $taxonomy_global_where = '';
$term_global_join = $term_global_where = '';
while (have_posts()) : the_post(); ?>
-- loop code here --
<?php endwhile; ?>
3. The above code lets our archive page understand our filtering for taxonomies and terms. Save your files and re-save your permalinks in the admin area. Next lets use this puppy! I used this in my custom sidebar (sidebar-publications.php):
<ul>
<?php echo get_cpt_archives( 'publications', true, 'publication_category', 'articles' ) ?>
</ul>
Our function gets the custom post (Publications) and ‘true’ is set so we want the normal list layout. Next it calls the taxonomy we want… I just have one for this custom post ( publication_category ) and finally the term I want in that taxonomy ( articles ). This should spit out a link like this: www.website/custom_post/year/month/taxonomy/term
I hope this code serves you well! My client is very happy 😉
Very Best,
Chris