How to achieve a clean custom permalink solution?

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

                                          PARENT
                                             |
                     |------------------------------------------------|
                   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

etc.

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.?

2 Answers
2

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>';
print_r($wp_rewrite);
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:

$wp_rewrite->flush_rules();

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,
Kat

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

Leave a Comment