Normal pages as children of my Custom Post Type

This one is tricky, I’ve got Custom Post Type called “dictionary”, users add “definitions” there which are automagically put into right categories (so for example if user adds “Apple” it’s under “A”).

The URLs look like this:

Read More
  • blog/dictionary/ – dictionary welcome page
  • blog/dictionary/x/ – listing of definitions starting with “x” letter
  • blog/dictionary/x/Xavier – definition of word “Xavier”

Now, I want to add normal WordPress pages and somehow display them under:

  • blog/dictionary/rules
  • blog/dictionary/author

etc.

I’m creating new pages and setting “Dictionary” page (blog/dictionary) as their parent, so they’re where they supposed to be, but display NOTHING AT ALL, no content, nothing. I have absolutely no idea how to resolve it. I can’t add them to “dictionary” custom post type as it holds definitions only.

Any ideas? I’d rather avoid mod_rewrite (as I want my pages to be children of “dictionary” not hard-linked normal pages).

In short words: I need two types of elements under one Custom Post Type.

UPDATE

Looks like when my “dictionary” is a a child itself it works, for example:

  • blog/dictionary/authors – displays nothing
  • blog/page1/dictionary/authors – displays authors page

Why is that?

Related posts

1 comment

  1. 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 to add_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.

Comments are closed.