I’ve dug through every question here on custom post type permalinks, but most seem to be either problems with custom taxonomy rewrites, or the obvious missing of flush_rewrite_rules(). But in my case, I’m only using a custom post type (no taxonomy), set to be hierarchical (so I can assign parent-child relationships), with the proper “support” for the attributes metabox, etc, etc. I’ve flushed rewrite rules a thousand different ways. I’ve tried different permalink structures. But child URLs always result in 404!
I originally had independent custom post types for the “parent” and “child” elements (using p2p), and I probably would have had no trouble using a taxonomy for the “parental” grouping – I know those would be semantically more accurate. But for the client, it is easiest for them to visualize the hierarchy when the “posts” are displayed in the admin just like pages are: a simple tree where children appear underneath the parent, prefixed with a “–“, and in the proper order. Also, various methods for assigning order via drag-n-drop can be used. Grouping via taxonomy (or p2p) results in a flat list of “posts” in the admin listings, which is simply not as visually obvious.
So what I’m after is literally the exact same behavior as core “pages”, but with my custom post type. I’ve registered the post type just as expected, and in the admin it works perfectly – I can assign a parent and a menu_order for each newsletter “post”, they appear correctly in the edit listings:
Spring 2012
— First Article
— Second Article
And their permalinks appear to be constructed properly. In fact, if I change anything about the structure, or even alter the rewrite slug when registering the post type, they automatically update correctly, so I know something’s working:
http://mysite.com/parent-page/child-page/ /* works for pages! */
http://mysite.com/post-type/parent-post/child-post/ /* should work? */
http://mysite.com/newsletter/spring-2012/ /* works! */
http://mysite.com/newsletter/spring-2012/first-article/ /* 404 */
http://mysite.com/newsletter/spring-2012/second-article/ /* 404 */
I also have standard core “pages” with hierarchical relationships created, and they look just the same in the admin, but they actually work on the front-end too (both parent and child URLs work fine).
My permalink structure is set to:
http://mysite.com/%postname%/
I’ve also attempted this (just because so many other answers seemed to indicate it was needed, though it didn’t make sense in my case):
http://mysite.com/%category%/%postname%/
My register CPT args include:
$args = array(
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'has_archive' => 'newsletter',
'hierarchical' => true,
'query_var' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
'rewrite' => array( 'slug' => 'newsletter', 'with_front' => false ),
The only visible difference between my custom post type children and normal page children, is that my CPT has the slug at the beginning of the permalink structure, then followed by the parent/child slugs (where pages just begin with the parent/child slugs, no “prefix”). Why this would foul things up, I don’t know. Plenty of articles seem to indicate that this is exactly how such hierarchical CPT permalinks should behave – but mine, though nicely formed, don’t work.
What also baffles me is when I examine the query_vars for that 404 page – they seem to contain the correct values for WP to “find” my child pages, but something’s not working.
$wp_query object WP_Query {46}
public query_vars -> array (58)
'page' => integer 0
'newsletter' => string(25) "spring-2012/first-article"
'post_type' => string(10) "newsletter"
'name' => string(13) "first-article"
'error' => string(0) ""
'm' => integer 0
'p' => integer 0
'post_parent' => string(0) ""
'subpost' => string(0) ""
'subpost_id' => string(0) ""
'attachment' => string(0) ""
'attachment_id' => integer 0
'static' => string(0) ""
'pagename' => string(13) "first-article"
'page_id' => integer 0
[...]
I’ve tried this with various themes, including twentytwelve, just to be sure it’s not some missing template on my part.
Using Rewrite Rules Inspector, this is what shows up for the url:
http://mysite.com/newsletter/spring-2012/first-article/
newsletter/(.+?)(/[0-9]+)?/?$
newsletter: spring-2012/first-article
page:
(.?.+?)(/[0-9]+)?/?$
pagename: newsletter/spring-2012/first-article
page:
how its displayed on another inspector page:
RULE:
newsletter/(.+?)(/[0-9]+)?/?$
REWRITE:
index.php?newsletter=$matches[1]&page=$matches[2]
SOURCE:
newsletter
This rewrite output would lead me to believe that the following “non-pretty” permalink would work:
http://mysite.com/?newsletter=spring-2012&page=first-article
It doesn’t 404, but it shows the parent CPT item “newsletter”, not the child. The request looks like this:
Array
(
[page] => first-article
[newsletter] => spring-2012
[post_type] => newsletter
[name] => spring-2012
)