I Doubled my Income in a Year

WordPress allowed me to get a better job & better projects in just a Year. I will give you tips, tricks and guide you into WordPress development so you can get more income. Sign up to my 7-day email course!

Custom WordPress Rewrite Rule to Combine Taxonomy and Post Type

WordPress permalinks are great for having friendly urls that your visitors can also remember and that benefit your SEO optimization. Some solutions will require you to have an url made of a combination of different content. In this tutorial we will look how to have a custom taxonomy and also append the custom post type slug to the end of it.

Reason for a Custom WordPress Rewrite Rule

Let’s look at a scenario to better understand the reason for this. We have a custom post type Resources that also needs a custom taxonomy Type so that we can categorize them under different types of resource. We will display the resources under their category. When our visitors visit an url www.yoursite.com/resources, they will get a list of resources that are categorized as Featured.

If our visitor visits another url such as www.yoursite.com/resources/e-books they will get a list of all our resources of type e-books.

So, you do get it right? Our main slug in the url is actually a slug for the taxonomy and not our post type. But, when our visitor clicks on an e-book, they will get to an url such as www.yoursite.com/resources/e-books/my-new-book.

The my-new-book is a slug for our Resource.

Let’s learn now how to accomplish that.

The Custom Post Type

Our custom post type will be a resource_post_type. This ensures that the WordPress does not look for the post type when on url /resources/. We will create our own custom WordPress rewrite rule to handle our resources.

The only part that interests us here is the taxonomies key that defined a relationship with a taxonomy. Let’s make that taxonomy now.

The Custom Taxonomy

The taxonomy will be registered for our post type Resource. We will also add a rewrite rule immediately when registering it. This will ensure that the WordPress does look for the taxonomy Resource Type when visiting the url /resources/.

The WordPress rewrite rule is created under the parameter rewrite. Now we have the url structure set for our taxonomies to be displayed when visiting resources/ and any sub page such as resources/e-books.

The Custom WordPress Rewrite Rule

Now we need to get on the business and create the WordPress rewrite rule to handle third level slugs such as resources/e-books/my-new-book.

We are hooking our function resources_cpt_generating_rule to the filter generate_rewrite_rules. This filter will be called when flushing rewrite rules. I recommend you go to Settings > Permalinks and just save them once again to flush the rewrite rules.

When our WordPress rewrite rule is being generated, we are getting all our terms from the Resource Type taxonomy. Even those that do not contain any resource relationship. Do take note that you will have to save the permalinks when creating a new taxonomy term, just in case.

Once we get all the terms, we iterate through all of them and create a WordPress rewrite rule for each. The rewrite rule will say something like this:

When you visit resources/e-books/my-new-book, get the third level slug my-new-book and set the query string to look for a post type resources_post_type with the slug (name) my-new-book.

The Custom Post Type Link

So now we have the url structure all set with our new WordPress rewrite rule. But what happens when you save that Resource? The link that is generated once we save our new Resource will be something like resources_post_type/my-new-book. This is not right.

It should be resources/e-books/my-new-book. This can be done using the filter post_type_link.

Here we are checking if the post is of type resources_post_type. This will ensure that we create a different post link only for our Resources. We get all the terms from our custom taxonomy, but only for the current Resource.

While we iterate through all of them, we escape the slug featured because this is just a secondary type. You don’t have to do that, but if you have a secondary type, don’t include them for the link. Use only the main one.

When we set a term slug, we break out of the loop. We then create a permalink structure that follows our custom WordPress rewrite rule and return it from that filter.

Now you also have a good structured link when saving your Resource.

Conclusion

In this tutorial we have learned how to create custom WordPress rewrite rules and also make a relationship between different content in the url structure. This could benefit the SEO also but more importantly, your visitors will have a really friendly url for the resources they want to see or read.

About the Author Igor Benic

Web Developer who mainly uses WordPress for projects. Working on various project through Codeable & Toptal. Author of several ebooks at https://leanpub.com/u/igorbenic.

follow me on:

Leave a Comment:

8 comments
Iñigo N. says March 21, 2017

Good post, it’s very interesting

I have a problem with this from the permalink. How can I make the permalinks show me this route: resources/e-books/history/my-new-book and this other route: resources/e-books/history/modern/my-new-book
I’ve been looking for the solution for a few days but I still have not found anything, I would appreciate your help.

Thanks.

Reply
    Igor Benic says March 22, 2017

    Hi Iñigo, I am glad you like the article!

    You could use the similar code I have written there, but you would need to have some more loops. You can loop through the terms (parent) and then also get the children terms from each parent. Then you can loop through them and set them like this in the code.

    You could try something like this: https://gist.github.com/igorbenic/3ba41de1db69bf028651e98b4615cfee

    Reply
Iñigo N. says March 22, 2017

Hi Igor,

Thank you very much for your answer

I have tried the new code and it does not work for me, it still does the same thing as before but now the single- {resources_post_type} .php gives 404 error, I have updated the permalinks but nothing.

My structure is:
– Category 1
– Category 1.1
– Category 1.1.1
– Resource 1
– Resource 2
– Resource 3
– Category 1.1.2
– Resource 4
– Resource 5
– Resource 6
– Category 1.1.3
– Resource 7
– Resource 8
– Resource 9
– Category 1.1.4
– Resource 10
– Resource 11
– Resource 12
– Category 1.2
– Resource 13
– Resource 14
– Resource 15
– Category 1.3
……
– Category 2
– Category 2.1
……
– Category 2.2
……
– Category 2.3
……

With your code when i go to:
category 1 -> resources/categoria-1/ OK
category 1.1 -> resources/categoria-1-1/ ERROR should be resources/categoria-1/categoria-1-1/ and projects of category 1.1.1
resource 1 -> resources/categoria-1-1-1/resource-1/ ERROR should be resources/categoria-1/categoria-1-1/categoria-1-1-1/resource-1/ and return error 404

Any ideas?
Thank you very much for your help.

Reply
    Igor Benic says March 22, 2017

    I have changed the post type into ‘resources’ instead of ‘resources_post_type’. If you change the $post_type back to resources_post_type, would that work? What post type slug are you using?

    Reply
Iñigo N. says March 22, 2017

I have this code in functions.php:

https://gist.github.com/igorbenic/3ba41de1db69bf028651e98b4615cfee#file-request-php

Reply
    Igor Benic says March 22, 2017

    I have edited your comment with the link to the code so that we don’t waste space here if other readers want to read the comments.

    I will have to get back to you later today or tomorrow on this since this is something I have to create and test.:)

    Reply
      Iñigo N. says March 22, 2017

      Thanks a lot.
      In github it is much cleaner

      Reply
        Igor Benic says March 27, 2017

        I have wrapped it a little: https://gist.github.com/igorbenic/3ba41de1db69bf028651e98b4615cfee#file-solution-php

        This will work for the category/resource-content

        For something like category/category-2/resource-content, I would need a little more time on this to check. This is a little harder to achieve because WordPress then won’t know if category/category-2 is a resource or a resource_type since category/resource-content is also possible.

        That is why even core WordPress won’t give you the ability to have category-1/category-2

        Reply
Add Your Reply

Custom WordPress Rewrite Rule to Combine Taxonomy and Post Type

by Igor Benic time to read: 3 min
8