WordPress permalinks and custom $_GET Variables

Well once again I had to do something in wordpress that I wasn’t sure off. I bit of googling and reading a few blogs I got the solutions.
At first you would think that it isn’t possible buuut it is. WordPress is just a little stingy of unknown variables being passed without it knowing.. anyway… here is how it is done. first the code:

function add_query_vars($aVars) {
    $aVars[] = "sid";    // represents the name of the product category as shown in the URL
    return $aVars;
}

add_filter('query_vars', 'add_query_vars');

function add_rewrite_rules($aRules) {
    $aNewRules = array('societies/([^/]+)/?$' => 'index.php?pagename=societies&sid=$matches[1]');
    $aRules = $aNewRules + $aRules;
    return $aRules;
}

add_filter('rewrite_rules_array', 'add_rewrite_rules');

Explained:

function add_query_vars($aVars) {
    $aVars[] = "myvar";    // represents the name of the variable as shown in the URL
    return $aVars;
}

add_filter('query_vars', 'add_query_vars');

The function part tells wordpress that you are going to pass a variable through to it via the url. “myvar” will be the name of you variable so basicly you url will be : “http://www.wordpresssite.com?page_id=3&myvar=myvalue”. add_cation just initializes the function for wordpress to see it.

function add_rewrite_rules($aRules) {
    $aNewRules = array('mypage/([^/]+)/?$' => 'index.php?pagename=mypage&myvar=$matches[1]');
    $aRules = $aNewRules + $aRules;
    return $aRules;
}

add_filter('rewrite_rules_array', 'add_rewrite_rules');

This function basicly tells wordpress the following:
1. It will check for the page name. So you have to specify what page it will be on. So if you install your plugin on the page called mypage. the permalink will be http://www.wordpressite.com/mypage/
2. It tells wordpress that everything after that pagename will be the VALUE of the variable NAME set in the previous function.

TAKE NOTE:
You must go to settings->permalinks and save changes before changes will be applied.

To Implement this you dump that code into your function.php (if you are going to use this in a template) or you plugin file (if you will use it in your plugin). Then in your code you can reference a link called http://www.wordpresssite.com/mypage/myvarValue/.

If you set the “add_query_vars” function to myvar your query string would normally look like:

http://www.wordpressite.com/?page_id=3&myvar=myvalue.

But now it will look like:

http://www.wordpresssite.com/mypage/myvalue.

I hope this is explained properly. If you have any questions. Please ask.

Update:

The filter “rewrite_rules_array” is to rewrite the vars to look better. To be able to see all the rules currently set add the following function to you file:

function getRewriteRules() {
    global $wp_rewrite; // Global WP_Rewrite class object
    return $wp_rewrite->rewrite_rules();
}

then you can just add:

 print_r(getRewriterules()) 

anywhere to display the rules.

 

  • http://www.vertaxe.com Jake Broughton

    Thanks for this, just what I need – however I’m having trouble getting it working, possibly because the URL I’m trying to convert has 2 or more $_GET vars.

    Could you elaborate on working with multiple vars?

    Many thanks

    • Janes Oosthuizen

      Hi Jake

      The easiest way is as follows, instead of

      function add_query_vars($aVars) {
          $aVars[] = "sid";    // represents the name of the product category as shown in the URL
          return $aVars;
      }
      

      use the following

      function add_query_vars($aVars) {
          array_push($aVars, 'sid', 'var2', 'var3');
          return $aVars;
      }
      

      With that you will be able to use a url like http://www.mysite.com/mypage/?var1=value1&var2=value2.

      Lemme know if that helps.

  • http://www.vertaxe.com Jake Broughton

    Got it working, thanks!

  • http://www.albertojm.com/ Alberto

    Thanks so much for posting this. But i cant get to pass 2 vars or more :-\ What I have is something like these:

    functions.php

    function add_query_vars($aVars) {
    array_push($aVars, ‘op’, ‘search’, ‘country’, ‘city’); // represents the name of the product category as shown in the URL
    return $aVars;
    }

    add_filter(‘query_vars’, ‘add_query_vars’);

    function add_rewrite_rules($aRules) {
    $aNewRules = array(‘articulos/([^/]+)/?$’ => ‘index.php?pagename=articulos&op=$matches[1]&search=$matches[2]‘);
    $aRules = $aNewRules + $aRules;
    return $aRules;
    }

    add_filter(‘rewrite_rules_array’, ‘add_rewrite_rules’);
    function getRewriteRules() {
    global $wp_rewrite; // Global WP_Rewrite class object
    return $wp_rewrite->rewrite_rules();
    }

    If i do a query like this: http://localhost/wp/p/ It works Ok and $op returns p.
    But if i do this http://localhost/wp/p/work/ it gives me 404 Error, i did updated my permalink structure (/%category%/%postname%/) and the output of getRewriterules() gives me Array ( [articulos/([^/]+)/?$] => index.php?pagename=articulos&op=$matches[1]&search=$matches[2] etc…

    What I’m doing wrong?

    Thanks so much for helping me out!!

    • Janes Oosthuizen

      Hi Alberto

      The problem lies in the actual rewrite rules. Your getting the 404 error because WordPress doesnt recognize the permalink. I have seen people work with $matches[2] but I am also getting the same problem. I found a solution, will post it in the next day or two.

  • http://www.getbestprice.co.uk Abhishek

    Hi Janes,
    Could you please post the solution for passing 2 variables. I know the solution lies in using two regular expressions and using matches 1 and 2 but I suck at regex

  • vijay

    it help me alot..thank u very much…

  • Pingback: March 26, 2012 Update | Richard X. Thripp's Website

  • catler

    nice plugin. how about having this link: http://sitename.com/username where username can be change. and now if we try to visit the contact page which is basically base on url example is http://sitename.com/contact will be change to http://sitename.com/username/contact since the username is activated though this link http://sitename.com/username so, the other links will add http://sitename.com/username/pagename

  • catler

    any idea? thanks in advance.

  • http://www.blogdemy.com parasmani

    This code works fine. But there is small problem. If I change myvar to any other name, it doesnt work. Any idea why so

    • Janes Oosthuizen

      Hi Parasmani, Make sure you set the name in your add_query_vars aswell as the add_rewrite_rule function and also dont forget to flush the rules by saving permalink changes in your admin. Let me know if you get it working.

  • Omar

    Thanks a lot for the post, it’s very helpful. However I haven’t been able to make it work.

    I’m trying to add an extra variable to the search, which works well without permalinks: site.com/?s=x&search-type=custom

    I know that wordpress will recognize /search/x but haven’t yet figured out how to make it work with the extra parameter:
    site.com/search/x/search-type/custom

    Do you know what is it that I’d need to add to your code to make this work?

    Many thanks!

    • Janes Oosthuizen

      Hi Omar. The Secret is in your regex. See the solution here: http://www.janes.co.za/wordpress-permalinks-and-custom-_get-variables-part-2/
      Let me know if it works.

      • Omar

        Many thanks Janes, it was the rewriting the rule that had to be a bit different.

        Adding the “search-type” query var remained the same, then rewrote the rule like this:
        $aNewRules = array(‘search/([^/]+)/search-type/([^/]+)$’ => ‘index.php?s=$matches[1]&search-type=$matches[2]‘);

        It works like a charm.

        Thanks again !

        • Janes Oosthuizen

          My Pleasure! Glad you sorted it out.

  • Pingback: WordPress permalinks and custom $_GET Variables : Part 2 | Janes Oosthuizen

  • Pingback: The Daily Six Pack: November 14, 2012 | Dirk Strauss

  • http://www.coins-voyages.com ngita

    Thank you very much, this saves me a lot of headache. To works with many variables don’t need to declare it inside the functions, i just concaneted it and do an explode when getting to another page, works like a charm.