Skip to content

Instantly share code, notes, and snippets.

@kingkool68
Created December 16, 2015 00:11
Show Gist options
  • Save kingkool68/e68ca64eea9abd2e021a to your computer and use it in GitHub Desktop.
Save kingkool68/e68ca64eea9abd2e021a to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Pew Archive Filters
Description: Adds re-write rules and helper functions that make filtering archives by year and/or a taxonomy possible.
Version: 0.2
Author: Russell Heimlich
Author URI: http://www.russellheimlich.com
*/
function pew_archive_filter_rewrite_rules( $wp_rewrite ) {
$taxonomy_by_year_rewrite_rules = array();
$args = array(
'public' => true,
'_builtin' => false
);
$taxonomies = get_taxonomies($args);
$taxonomies['category'] = 'category_name';
$taxonomies['author'] = 'author_name';
//Only PewResearch.org uses projects and needs these rewrite rules created. For the other projects we can skip the extra rewrite rules.
$include_projects = false;
if( get_template() == 'pewresearch' ) {
$include_projects = true;
}
//Project taxonomy archives don't apply.
unset($taxonomies['projects']);
$feed_regex = '(' . implode('|', $wp_rewrite->feeds) . ')';
$pages_regex = '?([\d\-]+|all)';
foreach( $taxonomies as $tax => $query_var ):
$taxonomy_by_year_rewrite_rules = array_merge( array(
//Just Year
$tax . "/(.+?)/(\d\d\d\d)/pages/" . $pages_regex . "/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/(\d\d\d\d)/page/?([0-9]{1,})/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/(\d\d\d\d)/page/?([0-9]{1,})/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/(\d\d\d\d)/pages/" . $pages_regex . "/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/(\d\d\d\d)/page/?([0-9]{1,})/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/(\d\d\d\d)/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/(\d\d\d\d)/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/(\d\d\d\d)/pages/" . $pages_regex . "/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/(\d\d\d\d)/page/?([0-9]{1,})/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/(\d\d\d\d)/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2),
//Add /pages/ and /feed/ support to archive URLs.
$tax . "/(.+?)/pages/" . $pages_regex . '/' . $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&pages=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/pages/" . $pages_regex . "/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&pages=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3)
), $taxonomy_by_year_rewrite_rules);
if( $include_projects ) {
$taxonomy_by_year_rewrite_rules = array_merge( array(
//Project and Year
$tax . "/(.+?)/project/(.+?)/(\d\d\d\d)/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&year=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/(\d\d\d\d)/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&year=" . $wp_rewrite->preg_index(3) . "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/(\d\d\d\d)/pages/" . $pages_regex . "/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&year=" . $wp_rewrite->preg_index(3) . "&pages=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/(\d\d\d\d)/page/?([0-9]{1,})/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&year=" . $wp_rewrite->preg_index(3) . "&paged=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/(\d\d\d\d)/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&year=" . $wp_rewrite->preg_index(3),
//Just Project
$tax . "/(.+?)/project/(.+?)/pages/" . $pages_regex . "/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3). "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/pages/" . $pages_regex . "/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3). "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/page/?([0-9]{1,})/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3). "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/pages/" . $pages_regex . "/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3). "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/page/?([0-9]{1,})/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3). "&feed=" . $wp_rewrite->preg_index(4),
$tax . "/(.+?)/project/(.+?)/feed/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/project/(.+?)/". $feed_regex ."/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&feed=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/project/(.+?)/pages/" . $pages_regex . "/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&pages=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/project/(.+?)/page/?([0-9]{1,})/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2) . "&paged=" . $wp_rewrite->preg_index(3),
$tax . "/(.+?)/project/(.+?)/?$" => "index.php?" . $query_var . "=" . $wp_rewrite->preg_index(1) . "&projects=" . $wp_rewrite->preg_index(2)
), $taxonomy_by_year_rewrite_rules);
}
endforeach;
$wp_rewrite->rules = $taxonomy_by_year_rewrite_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'pew_archive_filter_rewrite_rules');
function pew_archive_no_results_redirect() {
global $wp_query;
if( $wp_query->post_count > 0 || !is_archive() ) {
return;
}
$year = get_query_var('year');
$project = get_query_var('projects');
$base_url = get_term_link( $wp_query->queried_object );
$redirect_url = '';
if( $year && $project ) {
$redirect_url = $base_url . 'project/' . $project . '/';
}
if( $year && !$project ) {
$redirect_url = $base_url;
}
if( $redirect_url ) {
wp_redirect( $redirect_url, 301 );
}
}
add_action('template_redirect', 'pew_archive_no_results_redirect');
function pew_archive_rejigger_the_loop() {
global $wp_query;
$year = get_query_var('year');
$project = get_query_var('projects');
if( $wp_query->post_count > 0 || !is_archive() ) {
return;
}
if( $year || $project ) {
$wp_query->found_posts = 1;
$wp_query->is_404 = false;
}
}
add_action( 'posts_selection', 'pew_archive_rejigger_the_loop' );
/***
* Helper Functions
***/
function pew_get_archive_years() {
global $wp_query, $wpdb;
// Grab the main query WordPress used.
$query = str_replace("\n", '', $wp_query->request);
$query = preg_replace('/\s+/', ' ', $query);
// Change a few things to get the distinct years found for the main query.
$query = preg_replace('/SELECT .+ FROM/i', 'SELECT SQL_CALC_FOUND_ROWS DISTINCT YEAR(' . $wpdb->posts . '.post_date) FROM', $query);
$query = preg_replace('/LIMIT \d+, \d+$/i', '', $query);
// If there is a YEAR parameter in the main query, we need to take it out since it limits the number of years returned.
$query = preg_replace('/AND \( YEAR\(.+\) = \d\d\d\d\)/im', '', $query);
//$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts INNER JOIN $wpdb->term_relationships ON object_id = ID WHERE post_status = 'publish' AND post_type = 'post' " . implode('', $term_taxonomy_clause) . " ORDER BY post_date DESC");
$years = $wpdb->get_col($query);
$years = array_map('intval', $years);
return $years;
}
function pew_archive_years( $base_url = FALSE ) {
global $wp_query;
if( !$base_url ) {
$base_url = get_term_link( $wp_query->queried_object );
if( $proj = get_query_var('projects') ) {
$base_url .= 'project/' . $proj . '/';
}
}
$years = pew_get_archive_years();
// No point in showing the year filter if there is only one year to choose from.
if( count( $years ) > 1 ):
$current_year = get_query_var('year');
$label = 'Filter by Year';
// If a year is already set, show the filtered year and provide an option to remove the year filter completely (Show All Years).
if( $current_year ) {
?>
<a href="<?=$base_url;?>" class="filtered-to" title="Show all years">Filtered to <?= $current_year; ?></a>
<?php
$label = 'Change Year Filter';
}
?>
<h3><?=$label;?></h3>
<ul class="years grid-filter">
<?php
foreach( $years as $year ):
$classes = array();
//If this is the first year in the list, we'll add a class of first for styling purposes.
if( $year == $years[0] ) {
$classes[] = 'first';
}
//If this year is the current year we'll add a class of active for styling and use an <a> element without an href attribute. Helps keep styling consistent but it's not clickable.
if( $year == $current_year ) {
$classes[] = 'active';
?>
<li class="<?=implode(' ', $classes);?>"><a><?=$year;?></a></li>
<?php } else { ?>
<li class="<?=implode(' ', $classes);?>"><a href="<?=$base_url . $year . '/'?>"><?=$year;?></a></li>
<?php
}
endforeach;
?>
</ul>
<?php
endif;
}
function pew_archive_projects() {
global $wp_query;
$current_project = get_query_var('projects');
$base_url = get_term_link( $wp_query->queried_object );
$year = get_query_var( 'year' );
$label = 'Filter by Research Area';
// If aproject is already set, show the filtered project and provide an option to remove the project filter completely (Show All Projects).
if( $current_project ) {
$current_project_obj = get_term_by( 'slug', $current_project, 'projects');
$filtered_url = $base_url;
if( $year ) {
$filtered_url .= $year . '/';
}
?>
<a href="<?=$filtered_url;?>" title="Show all projects" class="filtered-to">Filtered to <?= $current_project_obj->name; ?></a>
<?php
$label = 'Change Research Area Filter';
}
$args = array(
'orderby' => 'count',
'order' => 'DESC'
);
$projects = get_terms( 'projects', $args );
if( $projects ) :
?>
<h3><?=$label;?></h3>
<ul class="projects">
<?php
foreach( $projects as $project ):
if( $project->slug == $current_project ) { ?>
<li class="active"><a><?=$project->name;?></a></li>
<?php } else {
$url = $base_url . 'project/' . $project->slug . '/';
if( $year ) {
$url .= $year . '/';
}
?>
<li><a href="<?=$url;?>"><?=$project->name;?></a></li>
<?php }
endforeach;
?>
</ul>
<?php
endif;
}
function pew_archive_categories( $args = NULL ) {
$defaults = array(
// for get_terms
'term_ids' => false,
'term_id' => false,
'taxonomy' => 'category',
'label' => 'Publication Type',
'orderby' => 'count',
'order' => 'DESC',
// Just for this function
'show_all' => false
);
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
if( !is_taxonomy($taxonomy) ) {
return false;
}
$query_var_key = $taxonomy;
if( $query_var_key == 'category' ) {
$query_var_key .= '_name';
}
$current_term_slug = get_query_var($query_var_key);
$current_term_obj = get_term_by( 'slug', $current_term_slug, $taxonomy );
$top_level_term_obj = $current_term_obj;
if( !$top_level_term_obj ) {
return false;
}
if ($show_all == false) {
$count = 0;
// Find a top-level category; display that and its children
while( $top_level_term_obj->parent != "0" ) {
$top_level_term_obj = get_term_by( 'id', $top_level_term_obj->parent, $taxonomy );
$count++;
if( $count > 10 ) {
//Something has gone wrong, let's bail and not create an infinite loop...
return false;
}
}
$args['child_of'] = $top_level_term_obj->term_id;
}
$terms = get_terms( $taxonomy, $args );
$year = get_query_var( 'year' );
$base_url = get_term_link( $current_term_obj, $taxonomy );
if( $top_level_term_obj->slug == 'interactives') {
$label = 'Interactive Type';
}
$full_label = 'Filter By ' . $label;
// If a category is already set, show the filtered category and provide an option to remove filter (Show All Categories).
if( $current_term_slug != $top_level_term_obj->slug ) {
$filtered_url = get_term_link( $top_level_term_obj, $taxonomy );
if( $year ) {
$filtered_url .= $year . '/';
}
?>
<a href="<?=$filtered_url;?>" title="Show all types" class="filtered-to">Filtered to <?= $current_term_obj->name; ?></a>
<? $full_label = 'Change ' . $label . ' Filter';
}
if( $terms ):
$project = '';
if( $project = get_query_var('projects') ) {
$project = 'project/' . $project . '/';
}
?>
<h3><?=$full_label;?></h3>
<ul class="types">
<?php
foreach( $terms as $term ):
$url = get_term_link($term, $taxonomy) . $project;
if( $year ) {
$url .= $year . '/';
}
if( $term->slug == $current_term_slug ) { ?>
<li class="active"><a><?=$term->name;?></a></li>
<? } else { ?>
<li><a href="<?= $url; ?>"><?=$term->name;?></a></li>
<?php }
endforeach; ?>
</ul>
<?php endif;
}
@kingkool68
Copy link
Author

Helpful plugin https://wordpress.org/plugins/rewrite-rules-inspector/ Use it to inspect rewrite rules for basic built-in taxonomies and use that to build your own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment