WordPress: How To Create Custom Permalinks To Use In Your Plugins The Easy Way

Hi guys, in this tutorial I will be teaching you how you can create custom permalinks. We are going to write a simple plugin to demonstrate how to do this.

The first thing to do is add to filters and one action for our functions that we will be creating.

add_action( 'wp_loaded','my_flush_rules' );
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_filter( 'query_vars','my_insert_query_vars' );

The only action we use is the wp_loaded action for our function called my_flush_rules.

The first filter will be for our function called my_insert_rewrite_rules which will add new rules to our rules options in the database.

The second filter is our query_vars filter for our function called my_insert_query_vars.

Our first function is to add new rules to the database and flush the permalinks if the rules are not set.

function my_flush_rules() {
$rules = get_option( 'rewrite_rules' );

if ( ! isset( $rules['(teaching-you)/(.+)$'] ) ) {
global $wp_rewrite;


In the function above we have set our new rules to be able to handle url’s like http://yourdomain.com/teaching-you/whatever-name-you-want-here where the “whatever-name-you-want-here” part will be the value you are passing on like a $_GET variable. You will see in the “$rules['(teaching-you)/(.+)$']” part we use regex to handle any name after teaching-you.

Here we create our rules URL to be handled when it comes from the browser.

function my_insert_rewrite_rules( $rules ) {
$newrules = array();
$newrules['(teaching-you)/(.+)$'] = 'index.php?pagename=$matches[1]&friendly=$matches[2]';

return $newrules + $rules;

The above function adds the URL type to be handled when the browser sends data to the page. We have two $matches that we target. The first one is for our page name which which is the slug “teaching-you”. The second $matches we use as our $_GET value that we need to capture.

Adding our friendly id so that WordPress recognizes it.

function my_insert_query_vars( $vars ) {

array_push($vars, 'friendly');

return $vars;

In the above function we add an array_push method to add all our pretty permalink variables  for WordPress to recognize and use.

Add a custom function to call our new custom permalink structure

function custom_permalink() {

$friendlyurl = get_query_var( 'friendly' );

if( isset($friendlyurl) ) {

echo '<h2>Yay! My friendly url seems to work, here is the $friendlyurl value: '.$friendlyurl.'</h2>';


echo "<h2>Aaah! No friendly url here something is wrong!</h2>";


In the function above we are calling our $_GET using the get_query_var method as a normal $_GET won’t work so we have to do it this way to get our value from the browser.

Next we check if our variable $friendlyurl has a value set, if it does we echo a message to see that it’s working.

If it does not work add a message telling us that it’s not set.

The last thing we do is add a shortcode to make things a bit easier for us to setup.

Now that our code is done

Our code is done, now we need to create a page called Teaching You with a permalink slug “teaching-you”

Next add our shortcode to the page “[permalink]” and click publish. Before you view your page you need make sure that you have set the correct permalink structure under Settings->Permalinks to Post name

Now you can view your page, go to your page you created called http://yourdomain.com/teaching-you and you will get a message telling you that your value is not set.

If you type a name or number after the teaching-you part like so http://yourdomain.com/teaching-you/your-name-or-number-here You will get a totally different message telling you that it worked and gives the value you have entered in the url.

That’s it hope you liked this tutorial, PLEASE COMMENT and ASK QUESTIONS if you don’t understand something.

Download the plugin we have written HERE.

Related Posts:

  • rss
  • email
  • rss
  • email
I'm a full time PHP developer and I just love all things web related. If you need help I'm your guy.

18 Responses to WordPress: How To Create Custom Permalinks To Use In Your Plugins The Easy Way

  1. Stefano says:

    Very useful, thank you so much!

  2. G.H. says:

    Excellent! This got me up and running in no time.

  3. Morné says:

    Glad you liked it :) Thanks

  4. Kahlero says:


    Nice tutorial!

    I have a question, I have created e-commerce Json plugin for my WordPress and all works good, which get products from my php e-commerce site to WordPress.

    I have created a single link for the product using your tutorial sir which is (teaching-you) link and works good, but when I change the WordPress permalink to default which use id then I get page not found ):

    Could you please tell me how to register my Json products to WordPress or how to integrate json e-commerce products to the WordPress permalink just for the single link?

    I’m new in WordPress and sorry about my bad English :)

    Please help me, one month I have searched for that question but I did not found anything :(

  5. Morné says:

    Hi Kahlero,

    What you need to keep in mind is that the part in the friendly URL that is /teaching-you/ is sort of a $_GET variable.

    So what needs to happen when you switch back to normal default wordpress permalinks is that you need to have a fallback functionality to use the $_GET variables instead when the friendly url’s are switched off.

    As for the json part, I highly recommend you store all your data that you get from your json url in to it’s own database table. As this will save you from disaster when your other site goes down, then you still have all the data available freely without a loss in connection.

    If your data is then in the database it’s easier to call it from mysql then just use GET variables to show data or do it the friendly way. You are able to create multiple friendly names like yourdomain.com/products/tops/hoodie/

    If you want me to help you out with code you could always hire me 😉

  6. Kahlero says:

    thank you so much Morné! Here is my JSON php file to get the JSON contents.

    products = json_decode($json_contents, true);


    // Product return
    public function get_the_wpfq_products() {

    return $this->products;


    // Product return line
    public function wpfq_product($line) {

    return $this->products[$line];


    // Product count
    public function wpfq_products_count() {

    return count($this->products);



    I don’t know how to use better php because i’m new in php language also, please check this code, and if you could tell me how to insert JSON products to WP database :)

    your message was a surprise to me! :) you answered very quickly and THANK YOU AGAIN!


  7. Morné says:

    Hi Kahlero,

    I’m a bit busy, but will get back to you as soon as I get a chance. Busy launching a new service on teachingyou.net and a new site which will benefit all WP users.

    You can mail me through my contact form so that I can get in touch with you.


  8. Kahlero says:

    Hi Morné,

    I have contacted on http://teachingyou.net/, I dont know do you got my contact?


  9. Morné says:

    Hi Kahlero,

    I mailed you just now :) please reply when you get some time.

  10. Hi,

    Thanks for this post.

    I have an issue I can’t fix, maybe you could help me :)

    My slug is like that :


    Without ‘language’ slug, your plugin works. But i if add this slug and edit the code like this :


    It doesn’t work..

    Any idea ?

    Thanks for your time.

  11. Morné says:

    Hi Guillaume,

    Are you sure you need the teaching-you part :)

    That first slug part, needs to be a page name. the second part is the variables being sent through. So you need to have a page setup called language, so create one first.

    See if that helps but remove the (teaching-you) part.

    Let me know if that works for you.

  12. Thanks for your quick answer !

    I’ve put ‘teaching-you’ to compare to yout post.

    In my case, it works for mysiteweb.com/nos-vins/variable :


    but I can’t make this working with mysiteweb.com/en/our-wines/variable


    The pages “nos-vins” and “our-wines” exists and are accessible like this :



  13. Morné says:

    Hi Guillaume,

    By the looks of it your page is a sub page of another page. So don’t think you actually need to add the first (en) part. Just try it with $rules[‘(our-wines)/(.+)$’] and see if that works.

    Also are you remembering to do it in the flush part of the code too? If it does not work also try to visit the permalinks settings page this also resets the permalink structure.

    You could also try this rules[‘en/our-wines/(.+)$’] by taking away the ( and ) brackets.

  14. Hi Morné,

    Its not a subpage create with wordpress page but a slug added by polylang plugin which permit to translate my site (http://wordpress.org/extend/plugins/polylang/)

    I just tested your tricks but nothing works… Each time I flush the rules in permalink settings and in the code, I make the change in the flush part and in the new rules part.

  15. Morné says:

    Hi Guillaume,

    I had a brief look at the plugin code. You would need to modify the plugin it self as it’s implementing the url rewriting already. I think that’s probably why you can’t get yours to work.

  16. Dylan says:


    I really like this – how simple it is to integrate with what I am doing …

    Just one question:
    Like others on here I want to be able to have domain.com/page1/variable1/variable2

    Is it possible to just add other variables to the permalink, like this :

    3 | $newrules[‘(teaching-you)/(.+)$’] = ‘index.php?pagename=$matches[1]&friendly=$matches[2]&new-val=$matches[3]&another=$matches[4]';

    would this be retrievable like:


    Any help would be greatly appreciated :)

  17. Morné says:

    Hi Dylan,

    Yes you can extend it with as many as you want. It looks to me like you have it correct there. I think you would need to extend this part $newrules[‘(teaching-you)/(.+)$’] too. something like $newrules[‘(teaching-you)/(.+)/(.+)/(.+)$’] and so on. The only way you will know for sure is to actually play with the code and test it.

  18. Andhi Irawan says:

    Nice tutorial
    I have question, example I have a blog http://blog123.com
    and product web http://productABC.com
    In blog123 has post same name with productABC, like Gadget and Travel
    I want to create a link automatically in blog123.
    In blog123, for post Travel (http://blog123.com/travel), I create Show Product button link that link to http://productABC.com/travel.
    I want that button link automatically via code something like http://productABC base url]/[title from blog123 post title or attribute or post permalink]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>