Explanation about register_taxonomy and register_post_type and how this is reflected in the URL structure.
register_taxonomy(
'my_newscat',
['post'],
[
'labels' => ['name' => 'News category'],
'public' => true,
'hierarchical' => true,
'show_admin_column' => true,
'rewrite' => [
'slug' => 'newscategories'
],
'query_var' => 'newscategories'
]
);
If we didn't specify a rewrite slug, we had to use:
/my_newscat/[term]
After setting the rewrite slug to "newscategories", we can do:
/newscategories/[term]
After setting the query_var to "newscategories" we can do:
?newscategories=[term]
or if we want to filter for multiple newscategories:
?newscategories[]=[term1]&newscategories[]=[term2]
register_post_type(
'my_news',
[
'label' => 'News',
'public' => true,
'has_archive' => 'news-archive',
'rewrite' => [
'slug' => 'news'
],
'taxonomies' => ['my_newscat'],
'query_var' => 'news-query-var'
]
);
By setting the has_archive to 'news-archive', we have the archive at:
/news-archive
By setting the rewrite slug to 'news' we have a single item at:
/news/[item]
By setting the 'query_var' to 'news-query-var' we can get a single item at:
?news-query-var=[item]
Stop automatic redirect
WordPress does some magic behind the scenes if it finds an invalid URL. For example if we have a post at /2017/01/02/my-post we can get to this post also at /my-post or /sdf/sdf/sdf/sdf/sdf/my-post. If this is not what you want, you can alter the redirect_canonical filter:
function my_redirect_canonical($redirect_url, $requested_url) {
if (is_404()) {
return false;
}
return $redirect_url;
}
add_filter('redirect_canonical', 'my_redirect_canonical', 10, 2);
Filter custom post type with custom taxonomies
This only works if your custom taxonomy is unique for this custom post type. You register a custom post type with a specific archive slug and then you register a custom taxonomy with the slug of the post type as a prefix. For example if the slug of your custom post type archive is "/music", you can specify "/music/styles" as the slug of the custom taxonomy. This way you can have the music items available at "/music/my-music-post-item" and all classical music items at "/music/styles/classical":
register_post_type('my_music', [
'public' => true,
'has_archive' => 'music',
'rewrite' => ['slug' => 'music']
]);
register_taxonomy('my_music_styles', ['my_music'], [
'public' => true,
'rewrite' => ['slug' => 'music/styles']
]);