Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm working on a project with several custom post types, where one of the post types is naturally (but not actually in the WordPress sense) the 'parent' of the others. For example, say I have a custom post type called 'book' and another one called 'character', and say I want to have the following custom URL structure:

books/[book-name]/characters/[character-name]

Thus, the canonical URL for the post about the character Thing One in the book The Cat In the Hat would be:

 books/cat-in-the-hat/characters/thing-one

A character is associated with a book with a post meta row.

I've created custom rewrites to make it work...

add_rewrite_rule (
    '^books/([^\/]+)/characters/([^\/]+)/?$',
    'index.php?book=$matches[1]&character=$matches[2]&post_type=character'
);

...but I'd also need to make sure that the 'character post' in the URL belongs to the 'book'...

books/cat-in-the-hat/characters/thing-one     //good
books/anna-karenina/characters/count-vronsky  //good
books/anna-karenina/characters/thing-one      //bad

This can't happen automatically: I have to hook into a filter or an action to check whether the character matches the book, and if not, either redirect to the correct, canonical URL or force a 404.

Where's the best place to accomplish this check? My choices (so far) are:

  • The request filter -- i.e. checking before the main query is instantiated.
  • The various WP_Query filters -- i.e. make WP_Query do the checking for me by adding a post meta constraint.

I realize this is rather an open-ended question and probably a matter of taste, but any insight into the most code and database efficient way of doing things would be appreciated. Thanks.

share|improve this question
    
How do you link the charater to the book internally? via a taxonomy? –  Dan Ștefancu Sep 23 '13 at 17:03
    
It sounds like @ChrisCarson said post meta row which I can only assume when the user creates a new book, they somehow find / pick the character(s) attached to it, which is then saved as meta values attached to the book post ID. That being said, I am confused with OPs final example - the last url being bad assumes that 2 different books cannot have the same character names. –  Howdy_McGee Mar 20 at 22:01
add comment

1 Answer

I tackled subordinate post types with a similar vein but was not as strict on the canonical url aspect; however, I ran into a similar situation with deeplinking custom WooCommerce product type links. I leveraged the template_redirect hook to push a 404 if it didn't match the route and the post_type_link to ensure the meta tag for canonical link and all the_permalink() and get_permalink() references matched the intended link. A snippit of the way I would recommend handling this:

add_action( 'template_redirect', 'wp20140320_template_redirect' );
public function template_redirect(){
    global $wp_query, $post;

    // the character post type has the book id set as meta?
    // or could set as post_parent if you don't have characters heirarchical
    $book_id = get_post_meta( $post->ID, '_book_id', true );

    // compare_parent_slug_to_id to check required $book_id against set parent book slug
    if( $post->post_type == 'character' && ! compare_parent_slug_to_id( $book_id ) ){

        // set is_404 since post type is character and parent slug does not match set
        $wp_query->is_404 = true;
        status_header(404);
        include get_404_template();
        exit; // maybe a better way to gracefully exit?

    }
}

modified from source: https://github.com/codearachnid/woocommerce-product-permalink/blob/master/inc/product-type-permalinks.php

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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