I have a custom post type called product
. It is categorized with the two taxonomies product_category
(which is superior) and product_group
.
I want the permalinks for single products to appear like:
products/%product_category%/%product_group%/%postname/
and for the “archives”, in fact an overview of the products in a product category like:
products/%product_category%/
.
This is my approach:
add_filter('rewrite_rules_array', 'rewrite_rules');
function rewrite_rules($rules)
{
$newRules = array();
$newRules['products/(.+)/(.+)/(.+)/?$'] = 'index.php?product_category=$matches[1]&product_group=$matches[2]&product=$matches[3]';
$newRules['products/(.+)/(.+)/?$'] = 'index.php?product_category=$matches[1]&product_group=$matches[2]';
$newRules['products/(.+)/?$'] = 'index.php?product_category=$matches[1]';
return array_merge($newRules, $rules);
}
Two Problems seem to appear now:
1. Archives (solved):
No matter which of my product categories’ slugs I insert into the permalink, the query will get the posts of all categories. Why?
2. Single Post/Product:
This works “too good”: Even if a wrong category is in the permalink, the correct post is returned. I want WordPress to redirect these wrong permalinks to the correct ones.
Any ideas?
EDIT:
I solved the archive problem. I simply forgot to evaluate my query correctly. My function in taxonomy-product_category
now at first gets the terms for product_group
and for each term it gets all posts that belong to the current product group and to the current product category. If there are now posts, the loop is continued.
<?php $terms = get_terms( 'product_group', 'hide_empty=0' ); ?>
<?php foreach ($terms as $child) { ?>
<?php
$args = array(
'post_type' => 'product',
'status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'product_category',
'field' => 'slug',
'terms' => get_query_var('product_category')
),
array(
'taxonomy' => 'product_group',
'field' => 'term_id',
'terms' => $child->term_id
)
)
);
$current_issue_posts = get_posts($args);
if(is_wp_error($current_issue_posts) || count($current_issue_posts)<1){
continue; //will terminate the loop if posts found
}
/* Do stuff / output the term */
}
?>
Still I got that redirect problem.
I did a quick little search on what you are trying to do and maybe this will help you out some and how the rewrite is grabbing the querystrings.
https://stackoverflow.com/questions/3307352/wordpress-custom-url-rewrites