Multiple permalinks for a single post with multiple categories in WordPress

Ever had more than one category assigned to a post? Did you get stuck with a single permalink where you might have wanted a dynamic permalink based on the current category? Read on and find out how to ‘hack’ your WordPress theme to make this happen.

First of all, change your permalink structure to /%category%/%postname%/ Also, may I suggest you install the WP No Category Base plugin? This makes your permalinks very pretty and very readable like so: www.yourwebsite.com/parent-category-name/child-category-name/post-name.

Guess what? The last part of the URL is the slug of your post name, the part before the slash is the slug of the current category! We’re going to use this to write our own permalinks. Trust me .. they’ll work even if WordPress suggest otherwise. You can try this right now if you want to. Go to your website (after installing the plug-in and changing your permalink structure of-course) and type www.yourwebsite.com/that-other-category-you-assigned-to-your-post/the-slug-of-your-post into the address bar. Does it work?

Now on the coding part. I assume you are familiar with coding in PHP and now where your functions.php file is? It’s in the folder of your current theme. Go and and open it. We need to add the following lines of code to this file:

function multiple_category_post_link($url = '')
{  
  // check permalink structure for the required construct; /%category%/%postname%/ 
  if (strrpos(get_option('permalink_structure'), '%category%/%postname%') !== false)
  {
    // get the current post
    global $post, $wp_query;
    
    // prepare variables for use below
    $post_id = $cat_id = 0;
    $new_url = '';
      
    // for categories
    if (is_category()) 
    {
      // remember current category and post
      $cat_id = get_query_var('cat'); 
      $post_id = $post->ID;
      
      // add the post slug to the current url
      $new_url = $_SERVER['REQUEST_URI'] . $post->post_name;   
    }
    
    // for single posts 
    else if (is_single()) 
    {
      // last part in the 'category_name' should be the slug for the current category
      $cat_slug = array_pop(explode('/', get_query_var('category_name')));
      $cat = get_category_by_slug($cat_slug);
      
      // remember current category and post
      $post_id = $wp_query->post->ID;     
      if ($cat) $cat_id = $cat->cat_ID;
      
      // replace the slug of the post being viewed by the slug of $post
      $new_url = str_replace('/' . get_query_var('name'), '', $_SERVER['REQUEST_URI']) . $post->post_name;
    } 
    
    if ($post_id > 0 && $cat_id > 0 && !empty($new_url))
    {
      // make sure categories match!
      foreach(get_the_category($post_id) as $cat)
      {
        if ($cat->cat_ID == $cat_id)
        {
          $url = $new_url;
          break;
        } 
      }  
    }    
  }   
    
  // always return an url!
  return $url;
} 
add_filter('post_link', 'multiple_category_post_link');

Save and upload your new functions.php file to your webserver and check out the changes on your website. You can also download the text file with all the code; multiple_category_post_link.txt. Let us know if it worked in the comments below.

Reageer!

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

De volgende HTML-tags en -attributen zijn toegestaan: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

23 januari 2014, 13:49

Pim zegt:

Hey,

first of all thanks for the hack, it works just fine. Even though it works, I do have a small problem with the website I’m currently working on.

On the home page I can select een certain number of categories. When a category is selected the category page will be opened showing a certain number of posts in that category. When selecting a post the permalink on single.php does show the category where the post was selected from. So your code works just fine!

Now the problem. On the category page I have multiple sort options, that can sort the posts in different ways. This is achieved by $_GET. Now when I use the sort options and afterwards select a post, the post slug will be placed after the $_GET values in the permalink on the category page, thus the permalink to the selected post is wrong.

Example:
www.website.com/category-2?orderby=meta_value_num&order=DESC/artiest-1

“/artiest-1″, the post slug is placed after the GET values instead of after the category slug.

How can I solve this?

Thanks in advance!

Greetz from The Netherlands!

1 december 2013, 21:30

mike zegt:

This is exactly what I am looking for, but it changes the URL to the first category every time!

if I go to something like:

/sales/city3/bob

it loads the right content, but changes the category, so something like

/sales/city1/bob

6 november 2013, 07:29

vijai zegt:

Hi It’s Working Fine..i have one dubt i want to cahnge the permalink extra contents ..

example : www.mysite.com/category_name/product_name/ to
www.mysite.com/category_name/product_name_review.html

how to do this help me

11 september 2013, 06:38

Liem zegt:

It’s work. Thanks you very much.

2 juni 2013, 06:49

Christian Sisson zegt:

Hey man, danke je very much. You really saved my ass with this lovely piece of code :)

Cheers!

9 augustus 2012, 18:44

Bastien zegt:

I may transfer all my taxonomies as categories and it will work but I’ll come with a huge amount of categories and by the way, these taxonomies were specific to a custom post type… so now i would have the whole categories for both (posts and custom post types) which would be confusing, no ?
please any help or advice ?
B.

7 augustus 2012, 14:43

Bastien zegt:

Hello,

It is working very well on categories : based on the current category template, the post permalink is updated. But is there a way to adapt it to taxonomies with (is_tax) ? I have posts which have multiple taxonomies and i’d like to change permalink based on the current taxonomy template? I hope my request is clear enough. thanks