1

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:

  • 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?

  • 1
    3 questions: (1) all your urls start with 'blog', is WordPress installed in 'blog' subfolder or have you setted yoursite.com/blog as site url using constant or settings? (2) Have you a standard page with slug 'dictionary' and also a cpt called 'dictionary'? If so, the dictionary posts are shown using a custom query in the page template or using main query and the cpt archive template? You should also post the code used to register cpt and taxonomy, because it matters. (3) You say blog/dictionary/x/ show definitions with "x" letter, how this is done? Custom query in template? Rewrite rule? – gmazzap Oct 26 '13 at 23:12
  • @G.M. I'm going to reply ASAP, but can't now as I'm not at home. In short words - it's quite easy to reproduce my issue when you take any WP theme (I've checked with TwentyTen), then create standard CPT and taxonomy. Then create a "home page" for taxonomy and set children for that page. They always display 404. Any template files (page-id.php) etc. doesn't seem to work. – Wordpressor Oct 27 '13 at 20:56
  • No. They can display 404, depending on how you register cpt and taxonomy, what matter is the rewrite argument. (e.g. see the answer below). After that is not clear to me what do you intend for "home page" for taxonomy. Maybe a page template that contain a custom WP_Query? Same result can be reached using a rewrite rule or a function hooking pre_get_posts. Without these information is impossible answer you, is only possible propose you a working solution like @matthew-boynes did. – gmazzap Oct 27 '13 at 21:03
2
+50

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.
  • Unfortunately something went wrong @MatthewBoynes. The child page finally displays like it's supposed to, so I'm really happy about it! But taxonomy archive is under /dictionary_category/x/ and URLs for single post views look like /dictionary_category/x/xavier/xavier. What's even worse the last page displays empty page from index.php not Xavier's definition. Does it work for you? I won't lie everything worked perfectly fine (without any custom redirects etc.) UNTIL someone wanted to attach a page to my CPT/taxonomy. How to use custom query instead of taxonomy in my case? – Wordpressor Oct 27 '13 at 21:25
  • Yes, it works for me. It sounds like you maybe didn't follow step 1 properly. The "rewrite" param for register_post_type and register_taxonomy are very important for making this work properly. – Matthew Boynes Oct 27 '13 at 21:28
  • Rewrote everything from the scratch and it looks like it's going to work, although I have one additional problem, I'm not sure if I should ask here. My taxonomy used to be named "dictionary" (that's the part of the problem why it wasn't working previously). The point is I have to rename my taxonomy now, but the new taxonomy doesn't have any terms yet. When I add them, WP keeps adding -2 to their slugs (so A becomes a-2 etc.). I deleted the old terms, the old taxonomy doesn't even exist but it doesn't seem to help. Is it possible to fix somehow? Any ideas? Thank you! – Wordpressor Oct 27 '13 at 22:33
  • Okay, never mind, just deleted all records in wp_terms from the database. Thanks a lot, honestly I had no idea about rewrites before. Your code works like a charm. Congrats on 4k reputation :) – Wordpressor Oct 28 '13 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.