I am using woocommerce and have some ‘product attributes’ which are just a taxonomies.
I have the following taxonomies:
- pa_color
- pa_material
- pa_style
the pa_ stands for product attribute and it is built-in to WooCommerce handles these taxonomies, so I can’t change that.
WooCommerce also comes with product categories (product_cat) and product tags (product_tag) taxonomies.
the following query gets me all the Red, Vinyl products in the Fabrics product category
?product_cat=fabrics&pa_material=vinyl&pa_color=red
I’d like to turn this into a pretty permalink, something like:
product-category/fabrics/material/vinyl/color/red
This answer gets me pretty close to what I am trying to achieve:
URL rewrite rules for multiple taxonomies query
in that I can get my URL to handle 2 taxonomies (product_cat + 1 attribute taxonomy), but I am stuck on how to get 3 (or more) parameters.
So I can get:
/products-category/fabrics/color/red
or
/product-category/fabrics/material/vinyl
but not all 3 together
/product-category/fabrics/material/vinyl/color/red
edit /
though i think it’d be ideal to have the URL be
/fabrics/vinyl/red
i’m not sure that is possible?
end edit/
WooCommerce also has some settings for modifying the permalinks (like prepending the URL with ‘shop’ or changing the product-category slug) so i’ll need to account for that eventually, but right now I need to get this first step down.
for simplicity’s sake, this is a stripped down version of my code. I’m actually getting the taxonomies from built-in woocommerce functions, but the question isn’t limited to woocommerce… as it pertains to any site w/ a lot of taxonomies.
add_action( 'init', 'wpa_init' );
function wpa_init() {
$taxonomies = array(
'pa_color' => 'Color',
'pa_material' => 'Material',
'pa_style' => 'Style',
);
$base="product-category";
foreach ( $taxonomies as $taxonomy => $mask ):
$attribute = strtolower( sanitize_title( $mask ) );
add_rewrite_rule(
$base.'/(.+?)/' . $attribute . '/([^/]+)(/page/(\d+))?/?$',
'index.php?product_cat=$matches[1]&' . $taxonomy . '=$matches[2]&paged=$matches[4]',
'top'
);
endforeach;
}
this was the best resource i’ve found on taxonomy query permalinks:
http://thereforei.am/2011/10/28/advanced-taxonomy-queries-with-pretty-urls/
but it, too, seems stuck at 2 taxonomies.
2 Answers
You could try something like this:
function custom_rewrite( $wp_rewrite ) {
$feed_rules = array(
'product-category/(.+)/material/(.+)/color/(.+)' => 'index.php?product_cat=". $wp_rewrite->preg_index(1)."&pa_material=". $wp_rewrite->preg_index(2)."&pa_color=". $wp_rewrite->preg_index(3)
"product-category/(.+)/color/(.+)' => 'index.php?product_cat=". $wp_rewrite->preg_index(1)."&pa_color=". $wp_rewrite->preg_index(2)
"product-category/(.+)/material/(.+)' => 'index.php?product_cat=". $wp_rewrite->preg_index(1)."&pa_material=". $wp_rewrite->preg_index(2)
);
$wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
// refresh/flush permalinks in the dashboard if this is changed in any way
add_filter( "generate_rewrite_rules', 'custom_rewrite' );
It may not work exactly as advertised, and you might need to do some regex modifications, but that’s the general gist of what needs to be done (90% of the work).
You will need to flush the permalinks if you add/edit/remove this code, put it in functions.php or a custom plugin. You can flush permalinks by simply going into the admin area and re-saving the permalinks
As a sidenote, you may run into clashing issues if you start using heirarchies,
e.g. if you have a tshirts/small and a dresses/small category, and you use a URL such as /products-category/small/color/red you might not get the results you expected, e.g. small tshirts? or did you mean small dresses?
So beware of ambiguity