I'm rebuilding a site in which I am required to change the URL structure for archive pages to something that WordPress doesn't handle by default. I have a custom post type named product
, which has a custom taxonomy product-category
. I need to rewrite the /product-category/{term-slug}
archive pages for this taxonomy to just be /{term-slug}
.
So I am trying to make a rewrite rule that catches /{term-slug}
pages, and rewrites them to /product-category/{term-slug}
, ONLY if no other rules were matched.
I can do this to catch and rewrite these pages correctly:
function rewrite_product_archive() {
add_rewrite_tag('%product-category%', '([a-z0-9\-_]+)');
add_rewrite_rule(
'^([a-z0-9\-_]+)/?$',
'index.php?product-category=$matches[1]',
'top'
);
}
add_action('init', 'rewrite_product_archive');
With this, I can navigate to a /{term-slug}
page and it will show the archive /product-category/{term-slug}
page correctly. However, this now causes all actual pages to stop working and 404.
So I tried changing the third parameter in my rewrite from top
to bottom
, and doing a flush. This now makes my regular pages work again, but now the /{term-slug}
rewrites have stopped working and they 404 now.
So essentially, I just need to follow the rewrite ONLY if no other rules were matched. Is that possible?
I'm rebuilding a site in which I am required to change the URL structure for archive pages to something that WordPress doesn't handle by default. I have a custom post type named product
, which has a custom taxonomy product-category
. I need to rewrite the /product-category/{term-slug}
archive pages for this taxonomy to just be /{term-slug}
.
So I am trying to make a rewrite rule that catches /{term-slug}
pages, and rewrites them to /product-category/{term-slug}
, ONLY if no other rules were matched.
I can do this to catch and rewrite these pages correctly:
function rewrite_product_archive() {
add_rewrite_tag('%product-category%', '([a-z0-9\-_]+)');
add_rewrite_rule(
'^([a-z0-9\-_]+)/?$',
'index.php?product-category=$matches[1]',
'top'
);
}
add_action('init', 'rewrite_product_archive');
With this, I can navigate to a /{term-slug}
page and it will show the archive /product-category/{term-slug}
page correctly. However, this now causes all actual pages to stop working and 404.
So I tried changing the third parameter in my rewrite from top
to bottom
, and doing a flush. This now makes my regular pages work again, but now the /{term-slug}
rewrites have stopped working and they 404 now.
So essentially, I just need to follow the rewrite ONLY if no other rules were matched. Is that possible?
Share Improve this question asked Oct 1, 2020 at 15:33 chrispytoeschrispytoes 2243 silver badges8 bronze badges 2- That's what you get if the rule comes last in the list, are you sure your rule actually matches the URL though? Have you confirmed this with a debug plugiin such as monkeyman rewrite rule analyser? – Tom J Nowell ♦ Commented Oct 1, 2020 at 16:05
- @TomJNowell I figured it out. See my answer. – chrispytoes Commented Oct 1, 2020 at 17:40
1 Answer
Reset to default 0It turns out it was because the default category archive pages do not require the URL to start with /category
. WordPress already matches the path /{category-slug}
for the default category
taxonomy archive.
I fixed it by changing the default category archive rewrite to start with /category
.
function move_category_rule($rules) {
if(array_key_exists('(.+?)/?$', $rules)) {
$val = $rules['(.+?)/?$'];
unset($rules['(.+?)/?$']);
$rules['category/(.+?)/?$'] = $val;
}
return $rules;
}
add_filter('rewrite_rules_array', 'move_category_rule');