Multiple taxonomies in URL
How does one append multiple taxonomies to the URL having the following:
- Post Type: products
- Taxonomy: product_type
- Taxonomy: product_brand
Adding new product and selecting type and brand for this product:
When adding a new product, there are two taxonomy boxes (product_type and product_brand). Let’s call this new post Test Product 1. The first thing we want to do is tick what type of product I’m dealing with, let’s say cell-phones. Next, I want to tick what brand the product belongs to, let’s say samsung.
Now “Test Product 1” is associated with the type “cell-phones” and the brand “samsung”.
The desired end result is:
/products
» View all custom posts/products/cell-phones
» View all custom posts with the taxonomy cell-phones/product/cell-phones/samsung/
» View all custom posts where the taxonomy is cell-phones AND samsung/products/cell-phones/samsung/test-product-1
» View the product (single custom post)
The question
How would one make this possible? My initial thought was using one taxonomy, having “cell-phones” as the parent term of “samsung”. Actually appending the taxonomy and its terms was not so tough. But it led to a lot of other issues, some well known, some not so much. Anyway it doesn’t work like that as it gives 404 issues and WP won’t allow certain things.
WP.org » taxonomy-archive-template
This lead me to having rethought the structure, having to leave taxonomies and its terms and I thought; why not create a 2nd taxonomy, and associate the post type with it and append that to the url?
Good question indeed, but how?
4 s
This is certainly possible by utilizing some rewrite rules of your own to some extent. The WP_Rewrite API exposes functions that allow you to add rewrite rules (or ‘maps’) to convert a request to a query.
There are prerequisites to writing good rewrite rules, and the most important one is basic regular expression comprehension. The WordPress Rewrite engine uses regular expressions to translate parts of a URL to queries to get posts with.
This is a short and good tutorial on PHP PCRE (Perl compatible regular expressions).
So, you’ve added two taxonomies, let’s assume their names are:
- product_type
- product_brand
We can use these in queries like so:
get_posts( array(
'product_type' => 'cell-phones',
'product_brand' => 'samsung'
) );
The query would be ?product_type=cell-phones&product_brand=samsung
. If you type that as your query you will get a list of Samsung phones. To rewrite /cell-phones/samsung
into that query a rewrite rule must be added.
add_rewrite_rule()
will do this for you. Here’s an example of what your rewrite rule might look like for the above case:
add_rewrite_rule( '^products/([^/]*)/([^/]*)/?',
'index.php?product_type=$matches[1]&product_brand=$matches[2]',
'top' );
You will need to flush_rewrite_rules()
as soon as you’ve added the rewrite rule to save it to the database. This is done only once, there is no need to do this with every request, once a rule is flushed its there. To remove it simply flush without the added rewrite rule.
If you want to add pagination you can do so by doing something like:
add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
'top' );