#16323 closed defect (bug) (fixed)
Hierarchical CPTs without a custom query_var 404
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 3.7 | Priority: | normal |
| Severity: | normal | Version: | 3.0.4 |
| Component: | Query | Keywords: | has-patch needs-testing |
| Focuses: | Cc: |
Description
When starting off with the post type set to non-hierarchical and then setting the hierarchical parameter in register_post_type() to true Wordpress will generate an invalid name query var (see attached files). If a generate a new rewrite rule in my functions file (e.g. service/(.*?)/(.*?)/?$' => 'index.php?post_type=service&name=$matches[2]) this appears to fix the problem. Removing the custom rewrite rule will cause the error to reappear.
Attachments (5)
Change History (16)
#2
in reply to:
↑ 1
@
15 years ago
Replying to nacin:
Were rewrite rules flushed at any point?
Yes, quite a few times via Settings -> Permalinks -> Save Changes
#4
in reply to:
↑ 3
@
15 years ago
Replying to scribu:
Please paste the full code you're using to register the post type.
function post_type_service() {
register_post_type(
'service', array(
'labels' => array(
'name' => 'Services',
'singular_name' => 'Service',
'add_new' => 'Add new',
'add_new_item' => 'Add new service',
'edit_item' => 'Edit service',
'search_items' => 'Search services',
'not_found' => 'No services found',
'not_found_in_trash' => 'No services found in trash',
),
'menu_position' => 20,
'public' => true,
'show_ui' => true,
'hierarchical' => true,
'query_var' => false,
'exclude_from_search' => false,
'supports' => array(
'title',
'editor',
'page-attributes'
)
));
register_taxonomy(
'service-cats', 'service', array(
'hierarchical' => true, // Category or Tag functionality
'labels' => array(
'name' => 'Categories',
'singular_name' => 'Category',
'search_items' => 'Search categories',
'popular_items' => 'Popular categories',
'all_items' => 'All categories',
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => 'Edit category',
'update_item' => 'Update category',
'add_new_item' => 'Add new category',
'new_item_name' => 'New category',
'separate_items_with_commas' => 'Separate categories with commas',
'add_or_remove_items' => 'Add or remove categories',
'choose_from_most_used' => 'Choose from most used categories'
)
)
);
}
add_action('init', 'post_type_service');
#5
@
12 years ago
- Keywords needs-patch added
I can verify the reporters bug. Using the pasted code provided by the reporter I obtained the following results:
The name query_var is wrong.
Request:
service/treatments-therapeautic/diagnostics-bulger
Query String:
name=treatments-therapeautic%2Fdiagnostics-bulger&post_type=service
Matched Rewrite Rule:
service/(.+?)(/[0-9]+)?/?$
Matched Rewrite Query:
post_type=service&name=treatments-therapeautic%2Fdiagnostics-bulger&page=
In the var_dump of the query_vars 'name' => 'treatments-therapeauticdiagnostics-bulger
Adding this rewrite rule fixes the problem:
$rule['service/(.*?)/(.*?)/?$'] = 'index.php?post_type=service&name=$matches[2]';
After the new rule
Request:
service/treatments-therapeautic/diagnostics-bulger
Query String:
name=diagnostics-bulger&post_type=service
Matched Rewrite Rule:
service/(.*?)/(.*?)/?$
Matched Rewrite Query:
post_type=service&name=diagnostics-bulger
#6
@
12 years ago
- Component changed from Permalinks to Query
- Summary changed from Hierarchical Custom Post Type Bug - invalid name query var generated to Hierarchical CPTs without a custom query_var 404
The problem here is that hierarchical post types that have been registered without a query_var will 404 when requesting child items. This occurs because the name query var is not mapped to pagename if the post type query_var doesn't exist. Simplified from WP_Query:
foreach ( (array)$q['post_type'] as $_post_type ) {
$ptype_obj = get_post_type_object($_post_type);
if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
continue;
if ( $ptype_obj->hierarchical && strpos($q[ $ptype_obj->query_var ], '/') !== false ) {
$q['pagename'] = $q[ $ptype_obj->query_var ];
$q['name'] = '';
}
}
With pagename not set the path is not sent through get_page_by_path(), but directly queried as the post_name after sanitisation.
#7
@
12 years ago
- Keywords has-patch needs-testing added; needs-patch removed
16323.diff shoehorns in a mapping from 'name' to 'pagename'. If a cleaner approach could be found that would be good.
#8
@
12 years ago
- Milestone changed from Awaiting Review to 3.7
changed the inline comment from postname to pagename
#9
@
12 years ago
We can also fix the rewrite rules so that a hierarchical rewrite tag will use the pagename variable, see 16323.hierarchical-rewrite-tag.diff. The 'drawback' is that get_page_by_path() would be used for all queries (though this is the same behaviour as pages).
Also, I think that the mapping should be done as well anyway.
#10
@
12 years ago
- Owner set to duck_
- Resolution set to fixed
- Status changed from new to closed
In 25182:
#11
@
12 years ago
Discussed this with Dion in IRC. We decided that it would be best to fix the rewrite rules for this ticket and open a new one to improve the query variable mapping (see #25190).
Were rewrite rules flushed at any point?