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?
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' );