When you create a new post type in WordPress using register_post_type()
, WordPress does not automatically create a page for listing the archives of that post type. It’s possible to create one, though, without too much hassle.
For example, you can create an post type called article
, and set the permalink for that post type to articles
(i.e., an article will have a URL like http://example.com/articles/my-article-title
).
Where do you go for a list of all articles, though? You might assume http://example.com/articles/
, but you would be assuming erroneously. You could create a page with the slug articles
and use a custom template for that page, but that doesn’t work with paging (e.g., http://example.com/articles/page/2/
).
Instead, you need to fiddle with WordPress’s rewrite rules. (And thanks to Andrew Wilson for helping me understand this.)
Just after you call register_post_type()
to define your custom post type, you’ll call another function, which I’ll call register_post_type_archives
. It will take two arguments: the post type (i.e., the first argument to register_post_type
), and the base path you’ll be using. So to create an archives page for the articles example above, you would call:
register_post_type_archives('article', 'articles');
What does the register_post_type_archives()
function look like? Here you go:
function register_post_type_archives( $post_type, $base_path = '' ) { global $wp_rewrite; if ( !$base_path ) { $base_path = $post_type; } $rules = $wp_rewrite->generate_rewrite_rules($base_path); $rules[$base_path.'/?$'] = 'index.php?paged=1'; foreach ( $rules as $regex=>$redirect ) { if ( strpos($redirect, 'attachment=') == FALSE ) { $redirect .= '&post_type='.$post_type; if ( 0 < preg_match_all('@\$([0-9])@', $redirect, $matches) ) { for ( $i=0 ; $i < count($matches[0]) ; $i++ ) { $redirect = str_replace($matches[0][$i], '$matches['.$matches[1][$i].']', $redirect); } } } add_rewrite_rule($regex, $redirect, 'top'); } }
Here, we use $wp_rewrite->generate_rewrite_rules($base_path);
to create a default set of rules, and add the case where there are no arguments besides the base path. Then we append the post_type
query parameter to each rule. Finally, replace each reference in the redirect (e.g., $1
) with the string $matches[1]
(or the corresponding number).
Now you have a listing of articles at http://example.com/articles/
. You can add other query parameters after that, too. For example, http://example.com/articles/?s=penguin
to search articles.
Thanx! It is the first one code snippet which works on my blog perfect!
I’m having a problem with this code when the name of my custom post type is the same as the url I want for my archives. I have a custom post type ‘soccer-players’ with the permalink set to ‘soccer-players’.
When I call this function “register_post_type_archives(‘soccer-players’, ‘soccer-players’); nothing seems to happen.
When I call this function “register_post_type_archives(‘soccer-players’, ‘soccer-playersxx’); it works just as it is supposed to.
Am I having a conflict with rewrite rules? Why wouldn’t this be working?
cheap adobe software
buy cs5 adobe
oem software legal
office professional oem
windows oem version
adobe software
autodesk downloads
Very nice! This answered my exact question. Thank you!