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'] ]);