I am currently looking at creating a new type of site archive within WordPress that allows users to filter by category AND by year rather than the default category OR year.
I am hoping to build a sidebar widget that creates the interface but I am looking for ideas and advice on creating the custom permalink setup. Ideally the archive will work with URLs along the lines of:
/category/year/
/category-1/year/
etc.
I have no requirement to filter any deeper than year. I have discovered this snippet of code but it does not work as expected.
Thanks
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
What you’re looking for is an endpoint. There are already several of these built in: /feed/some-feed/ for feeds or /trackback/ on posts. Those are both endpoints.
Fortunately, WordPress provides a handy function makes adding your own endpionts really easy. add_rewrite_endpoint
This is all the code you need to make your yearly category archives work:
<?php
add_action( 'init', 'wpse31422_init' );
function wpse31422_init()
{
add_rewrite_endpoint( 'year', EP_CATEGORIES );
}
As a plugin: https://gist.github.com/1296860
It works exactly like Stephen Harris’ answer, and you can reach a yearly, category archive by visiting yoursite.com/category/some-cat-slug/year/2011/.
Adding an endpoint creates a query variable with the same name as the first argument of the add_rewrite_endpoint function. In this case, year. Because this query var already exists in WP (to take care of the data-based archives), we don’t really have to do anything special here.
Method 2
This isn’t tested, but try (after you added the code you’ll need to go to settings> Permalinks and click save for it to take effect):
add_action('generate_rewrite_rules', 'my_rewrite_rules');
function my_rewrite_rules( $wp_rewrite ) {
$new_rules = array(
'(.+)/year/(.+)' => '?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2),
);
// Add the new rewrite rule into the top of the global rules array
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
That should take: http://yourwebsite.com/foobar/year/2011 and return results in category foobar, in 2011.
I’m not sure that structure is the the best way to go about it. To avoid unwanted issues, I would suggest using: http://yourwebsite.com/category/foobar/year/2011 and use instead:
'category/(.+)/year/(.+)' => '?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2)
Hope this helps!
Method 3
Following the suggestions of @StephenHarris I have developed the code a little further and come up with the following:
add_action('generate_rewrite_rules', 'my_rewrite_rules');
function my_rewrite_rules( $wp_rewrite ) {
// handles paged/pagination requests
$new_rules = array('news/(.+)/year/(.+)/page/?([2-9][0-9]*)' => '?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2).'&paged='.$wp_rewrite->preg_index(3));
// handles standard requests
$new_rules1 = array('news/(.+)/year/(.+)' => '?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2));
// Add the new rewrite rule into the top of the global rules array
$wp_rewrite->rules = $new_rules + $new_rules1 + $wp_rewrite->rules;
}
This allows a site to support URLS that look like:
/news/my-category/year/2011/page/2
as well as
/news/my-category/year/2011
The posts/blog part of my site is prefixed by “news” so you may wish to tweak the first part of the regular expressions and remove the word “news”.
If your going to use it make sure you flush your rewrite rules by visiting the permalinks settings page.
Method 4
I managed to make it work by using the solution by StephenHarris and Scott with a little modification:
function add_events_by_year_rewrite_rules($wp_rewrite){
// handles paged/pagination requests
$new_rules_with_pagination = array('c/(.+)/year/(.+)/page/?([2-9][0-9]*)' => 'index.php?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2).'&paged='.$wp_rewrite->preg_index(3));
// handles standard requests
$new_rules_without_pagination = array('c/(.+)/year/(.+)' => 'index.php?category_name='.$wp_rewrite->preg_index(1).'&year='.$wp_rewrite->preg_index(2));
// Add the new rewrite rule into the top of the global rules array
$wp_rewrite->rules = $new_rules_with_pagination + $new_rules_without_pagination + $wp_rewrite->rules;
return $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules', 'add_events_by_year_rewrite_rules');
Notice the index.php added in the rewrite rules definition.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0