A while ago I was figuring out how to rewrite GET variables for a wordpress plugin. For example:
http://mysite.com/mypage/?myvar=test
rewriting to
http://mysite.com/mypage/test
After a long search on the WordPress forums and the whole internet I’ve found this topic: using an extra parameter in an URL but it wasn’t very sufficient in my opinion. So that’s why I’ll explain the use of multiple parameters in the url.
One $_GET variable
function add_mypage_var($public_query_vars) {
$public_query_vars[] = 'myvar1';
return $public_query_vars;
}
//add a rewrite rule
function do_rewrite_mypage() {
add_rewrite_rule('brands/([^/]+)/?$', 'index.php?pagename=mypage&myvar1=$matches[1]','top');
}
add_filter('query_vars', 'add_mypage_var');
add_action('init', 'do_rewrite_brands');
You can use this variable in a plugin like this:
$slug = get_query_var('myvar');
Multiple $_GET variables
There was just one thing that cost me a headache… I’d like to add multiple parameters to the url and this method I just described isn’t sufficient. I’ve checked the basic url rewrite trough mod_rewrite and this method needs several lines to declare all the possible amount of variables in the url. I’ve tried this method also for the url rewrites via WordPress and here we are: a simple working function:
function add_mypage_var($public_query_vars) {
$public_query_vars[] = 'myvar1';
$public_query_vars[] = 'myvar2';
return $public_query_vars;
}
//add a rewrite rule
function do_rewrite_mypage() {
add_rewrite_rule('brands/([^/]+)/?$', 'index.php?pagename=mypage&myvar1=$matches[1]&myvar2=$matches[2]','top');
add_rewrite_rule('brands/([^/]+)/?$', 'index.php?pagename=mypage&myvar1=$matches[1]','top');
}
add_filter('query_vars', 'add_mypage_var');
add_action('init', 'do_rewrite_mypage');
You can check all the url rewrites that are used for your WordPress post.
function get_rewrite_urls(){
global $wp_rewrite;
return $wp_rewrite->wp_rewrite_rules(); /* Returns an array */
}
print_r(get_rewrite_urls());
flush_rules
You need to flush your rules to install your plugin and make the rewrite work. Also it can be handy to flush the rules during your development phase. So, just detect if the plugin is going to be installed:
register_activation_hook(__FILE__,'do_flush_gear'); /* Place this at the bottom of your plugin file */
And in some cases you’d like to remove all your custom rewrites. Just use this function:
function do_flush_gear{
global $wp_rewrite;
$wp_rewrite->flush_rules();
}





Comments (21)
dureo says:
hello,
I come from france so sorry for my english.
first thank you for your wonderful post!!! it’s a true solution for me !!!
but I have a question..
in what folder (function.php, page.php…) I have to put your code??
thank you very much
Crispijn says:
Well, I assume that you’re building a plugin for WordPress. Just place this functions in the file of the plugin you’re building. If you don’t know anything about building plugins for WordPress, read the documentation that helps you with the basics.
http://codex.wordpress.org/Writing_a_Plugin
Good luck!
Ryan says:
Hello,
Like duero I must say that this post is great and I believe it would be handy for me and others.
But I have some questions.
1. I have already found sth similiar like not almost the same solution and John in his comment http://www.rlmseo.com/blog/passing-get-query-string-parameters-in-wordpress-url/comment-page-1/#comment-1197
mentioned about some “overkill”
“…
Incidentally, if you call the flush_rules function using init filter, it’ll run on every page load, which is overkill and will slow down your app.”
then R’phael gave solution:
“Yes, if you are going to use flush_rules, only do it in your plug-ins’ activate callback so it is only done once.”
So what about it in your solution? I have to get GET variables for sorting posts etc. so I need them in my theme files like index.php, category.php – how should I do that without slowing down my blog?
2. My current urls looks like:
http://localhost/top/ – index
http://localhost/top/category/games/ – main category
http://localhost/top/category/games/fpp/ – sub category
http://localhost/top/category/gry-pc/akcji/page/X/ – sub category page X(0-N)
I would like to sort posts by sortby (name/rating), sorthow(asc,desc) in index, categories pages and subcategories pages. In my themes file I get $_GET variables and then put them in query_posts(….)
I know that I should have sth like this
# function add_mypage_var($public_query_vars) {
# $public_query_vars[] = ‘sortby’;
# $public_query_vars[] = ‘sorthow’;
#
# return $public_query_vars;
# }
but I’m not sure what I should change here:
# //add a rewrite rule
# function do_rewrite_mypage() {
# add_rewrite_rule(‘brands/([^/]+)/?$’, ‘index.php?pagename=mypage&myvar1=$matches[1]&myvar2=$matches[2]‘,’top’);
# add_rewrite_rule(‘brands/([^/]+)/?$’, ‘index.php?pagename=mypage&myvar1=$matches[1]‘,’top’);
# }
3. Am I right that I i have to put these two above functions in functions.php (my theme file)? But what with the last function do_flush_gear ? When and where I should add this one?
ps. English isn’t my mother tongue so if anything what I wrote can’t be understood just let me know. I will try to explain it again.
Ryan says:
I put below code to functions.php in my theme folder but I can’t see my rewrite url in the listing in the footer. What’s wrong?
functions.php:
=================================================
function add_mypage_var($public_query_vars) {
$public_query_vars[] = ‘sortby’;
$public_query_vars[] = ‘sorthow’;
return $public_query_vars;
}
//add a rewrite rule
function do_rewrite_mypage() {
add_rewrite_rule(‘category/gry-pc/([^/]+)/([^/]+)?$’, ‘index.php?cat=4&sortby=$matches[1]&sorthow=$matches[2]‘,’top’);
}
add_filter(‘query_vars’, ‘add_mypage_var’);
add_action(‘init’, ‘do_rewrite_mypage’);
function get_rewrite_urls(){
global $wp_rewrite;
$sth = $wp_rewrite->wp_rewrite_rules(); /* Returns an array */
$sth2 = ”;
foreach ($sth as $key => $value) {
$sth2 .= “$key; => $value”;
}
print_r($sth2.”);
}
add_action(‘wp_footer’, ‘get_rewrite_urls’);
=======================================
Ryan says:
ok I added:
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
add_filter(‘init’,'flushRules’);
and it works. Now I must try to get my parametrs from URL.
But R’phael Spindel says:
“Yes, if you are going to use flush_rules, only do it in your plug-ins’ activate callback so it is only done once.”
source: http://www.rlmseo.com/blog/passing-get-query-string-parameters-in-wordpress-url/comment-page-1/#comment-1242
I don’t know how to do it in functions.php (not mention doing plugin). But maybe someone will tell me and others here or on rlmseo blog how to do it.
Crispijn says:
Run this function only on installation. So, you can run an function whether you’re installing the plugin, otherwise you’re always flushing the rules and that’s not recommend (you’re screwing your WP installation).
I had to tell you in my post and I’ll update this as soon as possible.
Just run the function on installation:
register_activation_hook(__FILE__,’myplugin_installation’);
function example:
function myplugin_installation(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
Good luck!
Will Blair says:
Hey,
Many thanks for going through how WordPress uses $_GET variables. I was ready to pull my hair out when my redirects were working but none of the variables were showing up.
Thanks again!
-Will
Crispijn says:
Great! It’s always good to know that I didn’t write this for nothing! What kind of plugins are you guys writing, bases in this post?
Praveen Kumar says:
http://satche.org/wp/directories/tamil-sangam/?cp=2
help me to get rewrite url for this one..
Raul Illana says:
Hi!
But `?pagename=mypage` will work for page variables only, then what about single template variables?
I mean, imagine my scenario:
I’m developing v2 for a plugin (Awebsome! Comment Author Mail Validation in the plugin repository) to add a new comment validation method, that sends the comment author an email with a validation link every time he sends a comment, that must be followed to update comment status.
I only want to validate 2 vars in that link, and if they’re correct, change the comment status and the post comments number, and maybe change comment ‘hold’ warning.
The link looks like: http://sitename/category/postname/#comment-ID?var1=x&var2=y
Can you help me? Thanks for your time!
Crispijn says:
Hi Raul,
You’re uri is not how it supposed to be I think… Everything after a # will be read by the browser. If you’d like to use the GET variables your uri has to be something like this:
http://sitename/category/postname/?var1=x&var2=y#comment-ID
Good luck!
Raul Illana says:
You’re sooo right.
Got stuck on this for some hours, but didn’t check that. Damn me…
Many thanks!
henri says:
Hi,
Really nice post and I think it will answer my redirect problem
Currently I have this kind of url :
http://www.blogdecodesign.fr/galleries?ti=IMG_3186&fa=3&se=2227&id=1964275636&ps=afc997e4fb&ow=79835877@N00&ho=2304&so=55ddc35b9b
And I want to have nicer URL and still get the variables… So an URL like this will be pretty cool :
http://www.blogdecodesign.fr/galleries/IMG_3186/3/2227/1964275636/afc997e4fb/79835877@N00/2304/55ddc35b9b
So I use your function like this :
function add_mypage_var($public_query_vars) {
$public_query_vars[] = ‘ti’;
$public_query_vars[] = ‘fa’;
$public_query_vars[] = ‘se’;
$public_query_vars[] = ‘id’;
$public_query_vars[] = ‘ps’;
$public_query_vars[] = ‘ow’;
$public_query_vars[] = ‘ho’;
$public_query_vars[] = ‘so’;
return $public_query_vars;
}
//add a rewrite rule
function do_rewrite_mypage() {
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ti=$matches[1]&fa=$matches[2]&se=$matches[3]&id=$matches[4]&ps=$matches[5]&ow=$matches[6]&ho=$matches[7]&so=$matches[8]‘,’top’);
}
add_filter(‘query_vars’, ‘add_mypage_var’);
add_action(‘init’, ‘do_rewrite_mypage’);
But it doesn’t work, if you have some input it will very kind!
Thanks a lot and nice we!
Crispijn says:
Hi Henri,
Add for each GET variable an rewrite rule, so look at rule 10 and 11 in the multiple GET example.
Good luck,
Crispijn
henri says:
Thanks I will try this, I miss this step
henri says:
I try to add those rewrite rules :
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ti=$matches[1]&fa=$matches[2]&se=$matches[3]&id=$matches[4]&ps=$matches[5]&ow=$matches[6]&ho=$matches[7]&so=$matches[8]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ti=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&fa=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&se=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&id=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ps=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ow=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&ho=$matches[1]‘,’top’);
add_rewrite_rule(‘galleries/([^/]+)/?$’, ‘index.php?pagename=galleries&so=$matches[1]‘,’top’);
But it doesn’t work, do I miss something or doesn’t understand one step?
Thanks for your kind help!
Crispijn says:
Do one thing at the time, and add more rules if you’re sure the code is working correctly. But I also think that you’re doing it wrong:
On every line you define the parameter, starting with the first line with all the parameters, subsiding to the line with only one defined parameter.
See for an two parameter example at rule 10 and 11 in the multiple GET.
Good luck!
Binh says:
Hi Crispijn,
i have page structure like this: glossary/dictionary-terms/a
can you point me how can use “index.php?pagename” with sub page (dictionary-terms)
sorry my bad Eng. Thanks for your help.
Binh says:
hey,
sorry for duplicate comment, i just found solution:
index.php?pagename=glossary/dictionary-terms is working
Thank Crispijn.
James Riter says:
I could use a little help.
The site is http://whopeesintheshower.com/
If you take a look at you will see that “facts” “stories” “techniques” and “news” are all pages but are pulling in post on every page.
If I click on any post then the link will be like this.
http://www.thesite.com/fact/the-post
I did this by removing the word “category” in wp-includes/rewrite.php line (about line 1031)
and making the permalink “/%category%/%postname%/”
—————————————–
The down side is ever time I make a page or post I have to add back “category” and resave permalink , then remove “category”…
—————————————–
I am looking for a way to fix this? Maybe add something to the functions.php?
Jon Kristian says:
Just what I was looking for, my case is a little special though, hope someone can shed some light on this.
Issue: The first page is unknown, because my plugin adds a shortcode which the user manually inserts in a page that he creates.
Scenario: Let’s say the user creates a page called products, then adds the plugin shortcode to that page, now he has http://domain.com/products/ Remember that products is unknown to my plugin.
Now I want to create a re-write rule for http://domain.com/products/?product_details=1
Q: How can I append re-write rules to that unknown page? Is it even possible?