I am working on the design of a blog with the below(just a sample) category hierarchy.

                   Food                                           Fashion
                     |                                                |
          |---------------------|                       |---------------------|
      European                Asian                  European               Asian
          |                     |                       |                     |
    |---------|           |-----------|             |--------|           |--------|
Italian    French      Chinese    Japanese       Italian  French     Chinese   Japanese

The client will blog on Food and Fashion with posts categorised by country. Meaning that a post about Italian Pizza will go under PARENT > Food > European > Italian

My problem is with permalinks as the client wants the below structure for categories:

  1. http://www.mydomain.com = the homepage of the blog, bits and pieces from ALL categories
  2. http://www.mydomain.com/food = the food sub homepage, bits and pieces from all sub-categories under Food
  3. http://www.mydomain.com/fashion = the fashion sub homepage, bits and pieces from all sub-categories under Fashion
  4. http://www.mydomain.com/european = the european sub homepage, bits and pieces from all European sub-categories under both Food and Fashion
  5. http://www.mydomain.com/european/food = the european food sub homepage, bits and pieces from the Food>European sub category
  6. http://www.mydomain.com/european/italian/food = the italian food sub homepage, bits and pieces from the Food>European>Italian sub category


And this structure for posts:

  1. http://www.mydomain.com/european/italian/food/25115886/how-to-bake-the-right-pizza

  2. http://www.mydomain.com/european/italian/fashion/25175191/milan-fashion-show-in-june

My main problem with Wordpress' native way of managing permalinks is course the category base /category/ added by Wordpress. Also a headache is the fact that /european/italian/food is NOT in the order the category is saved, which is /food/european/italian.

I therefore tried testing around with the below code in my template's functions.php file:

add_filter( 'category_link', 'bloglinks', 10, 2 );

function bloglinks( $catlink, $category_id )

I was thinking of carrying out a check against the category IDs(which will never change) inside the function and build the permalink I want.

But is that the right place to do all the coding? Will I break anything, like plugins, etc.?

  • If you want I can show you how use Cortex to solve your problems, please before say yes, look at requirements. – gmazzap Jul 9 '14 at 17:14

WP allows you to add custom rewrite rules via WP_Rewrite - using them you can achieve pretty much anything you want - and if you like RegEx it will be a breeze.

WordPress needs triggers by which it will recognize the type of page you are requesting, hence it's default /category/ match rule along with many others.

You can see all the current rewrite rules if you print out the following:

global $wp_rewrite;
echo '<pre>';
echo '</pre>';

What you would do is match your food, fashion, european and asian slugs to act as if it was the category trigger word.

I have done something similar before and once you start playing with it, you will see its fairly easy to match up the link structure to the right query since all parameters about the type of a page you are requesting are passed via the index.php?key=value pairs. Best to see it for yourself printing out the $wp_rewrite.

This below is a simplified example that I have used before, add it to your functions.php:

if ( !function_exists('client_rewrite_rules') ) {
    function client_rewrite_rules() {
        global $wp_rewrite;
        $new_rules = array(
        // add all your rules here, mine below, store|restaurant|bar were my custom taxonomies
        '(store|restaurant|bar)/(.+?)/(store|restaurant|bar)/(.+?)/?$' => 'index.php?' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2) . '&' . $wp_rewrite->preg_index(3) . '=' . $wp_rewrite->preg_index(4),
        '(store|restaurant|bar)/(.+?)/?$' => 'index.php?' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2)
        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
    add_action('generate_rewrite_rules', 'client_rewrite_rules');

Your category rule would be something like this:

'(food|fashion|european|asian)/?$' => 'index.php?category_name=' . $wp_rewrite->preg_index(1)

One thing to remember is that every time you change the rules, you have to flush them for them to take effect. While you are testing, leave the code below in functions but take it out after you finish:


Another way of flushing rewrite rules is by visiting the Settings/Permalinks admin page.

Once the permalinks return the results you want, you will need to create a custom function that outputs your link structures. I had a bunch of taxonomies so category links required me to pass the taxonomy and the slug.

if ( !function_exists('client_category_permalink') ) {
    function client_category_permalink( $linkTax = null, $linkTerm = null ) {
        // Bunch of functionality constructing your pretty $url
        return trailingslashit($url);

Then wherever you have links, you add:

<a href"<?php client_category_permalink('restaurant', 'heston-blumenthal'); ?>">Heston Blumenthal</a>

Best of luck,

PS: I would be interested if anyone else had an alternative solution without using any plugins.

  • Hello Katrina. I took a very similar approach only that in my case I used add_action('init', 'my_rewrite_rules'); for the action and in the function I have a lot of: add_rewrite_rule('european/([^/]*)/food', 'index.php?category_name=food%2Ffood-european%2Ffood-$matches[1]', 'top'); ... This would be for the "italian food sub homepage", point 6. in my original post. Your approach looks cleaner though, I'll definitely check it out. – WPRookie82 Aug 4 '14 at 14:58

This is what I would do.

I think the problem is with the data organization. I think you need at least 2 taxonomies and not only one (Categories). One for Country/Zone, and another for Topic (fashion and food). So you'll get:

  1. An archive for every topic, like http://www.example.com/food
  2. An archive for every zone, like http://www.example.com/europe or even http://www.example.com/europe/italian.

And if you want a mixed archive you should make a search form, that gets you to something like http://www.example.com/search/?country=italia&topic=food.

For the second taxonomy you can use the Tags or a Custom Taxonomy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.