Custom Post Type Permalink For Parent/Child, 404 Page Not Found Error

Here we have a snippet from a functions.php file…

add_action('init', 'create_recipes');
function create_recipes() {
   $recipes_args = array(
       ...some properies...,
       'hierarchical' => false,
       'rewrite' => array('slug' => 'recipes')
       ...maybe more properties...
   }
   register_post_type('recipes',$recipes_args);
}

add_action( 'init', 'recipes_rewrites_init' );
function recipes_rewrites_init(){
    global $wp_rewrite;
    $gallery_structure="recipes/%post_id%/%recipe%";
    $wp_rewrite->add_rewrite_tag("%recipe%", '([^/]+)', "recipe=");
    $wp_rewrite->add_permastruct('recipe', $gallery_structure, false);
}

This registers a custom post type ‘recipes’ and sets up the permalink structure so that we can achieve, for example:

(1) example.com/recipes/394/lunch/

On the ‘lunch’ page I’ll extol the virtues of a good lunch. So far, so good.

However, what if I want to sub-categorise ‘lunch’ into ‘sandwich’, ‘burger’, ‘salad’ (e.g. on the ‘sandwich’ page I will talk about lunch – specifically sandwiches). First I create these extra pages under the ‘recipe’ custom post type section, and choose the ‘lunch’ page as their parent. Now I might hope/presume the following will work, for example:

(2) example.com/recipes/513/lunch/sandwich/

Oh dear, this does not work as presumed – we receive a 404 error. Ok, how do we get to the ‘sandwich’ page? Let’s see…

(3) example.com/recipes/513/sandwich/

Great, that works – but I wanted the ‘sandwich’ page parent slug (‘lunch’) to precede it in the URL (see (2)). How to solve this? Let’s start somewhere…

Step 1

What I do know is that if I change 'hierarchical' => false to 'hierarchical' => true then the the_permalink() function will (as is desired) construct the permalink as in (2). Great, but this will result in a 404 error with (2). I’m guessing I’ve either made a mistake in the create_recipes function, or perhaps I haven’t done enough in the recipes_rewrites_init function.

Step 2

I suppose I could (in theory) hook into the WP permalink functionality to intercept the request/permalink, retrieve the post’s parent slug (if it has one), and drop it in just before the post’s slug. However, that presumably only modifies the resulting permalink, which I’ve already done in Step 1. What I really need is to ensure the request is routed correctly.

Questions

How do I go about doing this? Is there a known WP way (i.e. existing functionality/options in the initial custom type setup)?

Other thoughts

I’m also aware that Custom Taxonomies can be used (at least in part) to solve the problem of categorising posts – and that there exists a plugin(s) to help. However, I would like to initially stick with Custom Post Types if possible.

Thanks.


Update 1

I’m now aware of a plugin called “Posts 2 Posts” which, among other things, enables connections between custom post types – specifically, between different custom post types. However, for my example I am using just one custom post type, and trying to have a natural parent-child hierarchy (which seems like a fairly standard WP thing) rather than forcing a relationship between disparate custom post types.


Update 2

Some further information and a solution of sorts. Here are two important things:

  1. Adding custom permalink structures to custom post types can be tricky.
  2. Adding custom permalink structures to custom post types may be unnecessary.

I realised I was fighting WordPress’s excellent out-of-the-box permalink functionality by creating an [unnecessary] custom permalink structure (e.g. example.com/recipes/513/lunch/sandwich/) which in retrospect is convoluted; my reasoning was that the post ID should be present in the URL for performance reasons (as opposed to just slugs, which might be slower for WP to match). I imagined this might be possible, but may not be worth the trouble. Instead, I ripped out my custom permalink stuff and just let WP resolve, for example, example.com/recipes/lunch/sandwich/ – which now works exactly as expected. Remember to set 'hierarchical' => true, and the world is your permalink.

Conclusion

If you insist on doing what I was trying to do, it may be possible but will require properly setting up a custom permalink structure to avoid the 404 errors (my original problem). For now I’m going to stick with the standard WP hierarchical permalink functionality.

1 Answer
1

In answer to my own question:

It turns out the WordPress permalink structure works perfectly well for custom types, e.g. example.com/recipes/lunch/sandwich/. This works exactly as expected if you set ‘hierarchical’ => true.

What I was originally trying to do was unnecessarily difficult to execute, and requires properly setting up a custom permalink structure to avoid 404 errors. I advise you stick with the standard WordPress hierarchical permalink functionality.

Leave a Comment