If it were me, here’s how I’d achieve this.
Preface
Assuming the following data structures:
- Post type: “dictionary”
- Taxonomy: “dictionary_category”, terms limited to single letters
And the desired URLs:
- /dictionary/ => page (this should work out-of-the-box)
- /dictionary/rules/ => page
- /dictionary/x/ => Taxonomy archive
- /dictionary/x/xavier/ => Single post view
1. Set the post type and taxonomy urls
When registering your post type, the rewrite
param should be,
'rewrite' => array( 'slug' => 'dictionary/%dictionary_category%' )
When registering your taxonomy, the rewrite
param should be,
'rewrite' => array( 'slug' => 'dictionary' )
You need to filter post_type_link
because of the rewrite tag (%dictionary_category%
) in the rewrite slug. Here’s what that would look like:
function wpse_119806_post_type_link( $post_link, $post, $leavename, $sample ) {
if ( 'dictionary' == $post->post_type ) {
if ( $categories = get_the_terms( $post->ID, 'dictionary_category' ) ) {
return str_replace( '%dictionary_category%', array_pop( $categories )->slug, $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'wpse_119806_post_type_link', 10, 4 );
Now, /dictionary/x/ works and /dictionary/x/xavier/ works.
2. Set the page URLs
Here, we’re going to take advantage of the fact that the dictionary_category terms won’t ever be more than 1 character. Anything after /dictionary/ and more than one character will be assumed to be a page.
add_action( 'init', 'wpse_119806_rewrite_rules' );
function wpse_119806_rewrite_rules() {
add_rewrite_rule( '(dictionary/[^/]{2,}?)/?$', 'index.php?pagename=$matches[1]', 'top' );
}
Flush your rewrite rules (Go to Settings → Permalinks and click “Save Changes”), and everything should work as desired.
Notes
- This disregards the /blog/; I’m assuming you have that piece figured out, so change this code if necessary to add that in.
- You can add more rules for pages to have deeper page hierarchies. This only supports the second level. This also doesn’t add rules for the feed, pagination, etc. for the pages. To add any of these, simply add them to
wpse_119806_rewrite_rules
with additional calls toadd_rewrite_rule()
. - Personally, I wouldn’t use a taxonomy for the dictionary letters, but it sounds like that’s what you are doing, so I went with it. If it were me, I’d use a custom query for those.