Getting hierarchical custom post type permalinks to work just like pages

This is my first time participating here on Stack Exchange, but I’ll give this a go and see if I can help point you in the right direction.

By default, hierarchical CPTs behave exactly the way you’ve described. The unique slug prefix, “newsletter” in this case, is to let the rewrite engine know how to tell requests for different post types apart.

Those CPT registration args look fine, but when a CPT is requested, the pagename query var should not have a value and the name query var should be the same as newsletter here, so it appears that there’s a conflict somewhere in your setup.

To help debug, install and activate the Rewrite Rules Inspector Plugin, then visit the screen at “Tools -> Rewrite Rules.”

  1. While looking at the list, all of your rules for the newsletter CPT should be listed before any page rewrite rules. Verify this is the case by scanning the “Source” column.
  2. If that checks out, input the URL for your “first-article” CPT in the “Match URL” field and click the “Filter” button to see which rule is matched. It should match a newsletter rule and a page rule, but the newsletter rule should be first.

If that doesn’t reveal any issues, search the post_name column in wp_posts to find other posts with the “first-article” slug to see if there might be a collision. Do a search for “newsletter” as well, just to be sure.

Add the following snippet to inspect your query vars early in the request to check and see which ones are being set by the rewrite rule match (visit the child CPT on the front end). If the pagename var doesn’t appear here, then it’s being set by something later in the request:

add_filter( 'request', 'se77513_display_query_vars', 1 );

function se77513_display_query_vars( $query_vars ) {
    echo '<pre>' . print_r( $query_vars, true ) . '</pre>';

    return $query_vars;
}

Any plugins/functions that modify the query vars could be causing a conflict, so disable them if you still see issues. Also flush your rewrite rules after each step, especially if the request was matching a wrong rule in the second step above (keep the “Permalinks” screen open in a separate tab and just refresh it).

Leave a Comment