When you write your own WordPress plugin you might need to add new rewrite rules to WordPress. Some people add Rewrite rules direct into htaccess file, but when you open it you can see that WP don’t store rules into this file. All WordPress rewrite rules are stored into the database.
Default WordPress htaccess file
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
For manipulation with rewrite you can use WP_Rewrite class. It’s functions all listed at the WP Codes, but i will show you how to use most important ones.
rewrite_rules() function
function getRewriteRules() {
global $wp_rewrite; // Global WP_Rewrite class object
return=$wp_rewrite->rewrite_rules();
}
This function “getRewriteRules”, will return array with listed rewrite rules. Array will be something like …
Array
(
// ....
[author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?author_name=$1&feed=$2
[author/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?author_name=$1&feed=$2
[author/([^/]+)/page/?([0-9]{1,})/?$] => index.php?author_name=$1&paged=$2
[author/([^/]+)/?$] => index.php?author_name=$1
// ...
)
You can use this to check are your rewrite rules inside this array. Only if your rules are listed inside this array your Pretty links will work. Now i will show you how to add your own rewrite rules in WordPress system.
functions add_rewrite_tag and generate_rewrite_rule
function createRewriteRules() {
global $wp_rewrite;
// add rewrite tokens
$keytag = '%tag%';
$wp_rewrite->add_rewrite_tag($keytag, '(.+?)', 'tag=');
$keywords_structure = $wp_rewrite->root . "tag/$keytag/";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);
$wp_rewrite->rules = $keywords_rewrite + $wp_rewrite->rules;
return $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'createRewriteRules');
As you can see first we use add_rewrite_tag function to create tag. This function add element to $rewritecode, $rewritereplace and $queryreplace arrays. The second parameter is our rule for this tag, sometimes we want to set tag to accept only numbers, then we will create tag like this one:
$keytag = '%numtag%';
$wp_rewrite->add_rewrite_tag($keytag, '([0-9]+)', 'numbertag=');
After tag we created rewrite rule, with link structure we wanted. Function generate_rewrite_rules() just returned array with our rewrite rule, at the end we added our rewrite rules array into WordPress rules array $wp_rewrite->rules.
This function added four rules into WordPress rewrite rules.
[tag/(.+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$1&feed=$2
[tag/(.+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$1&feed=$2
[tag/(.+)/page/?([0-9]{1,})/?$] => index.php?tag=$1&paged=$2
[tag/(.+)/?$] => index.php?tag=$1
Don’t forget to call hook
Hook generate_rewrite_rules is called when you save changes on your permalink structure in admin area. There is other way to call this event. Function flush_rules() will regenerate rewrite rules.
Maybe you didn’t wanted first three rules, right ? There is other way to the the same job, with more control in your hands. You can create this array manual without using generate_rewrite_rules function.
Here is code from some of my new plugin, and you can see how to easily add new rewrite rules with full control.
function add_rewrite_rules( $wp_rewrite )
{
$template_page_name = getTemplatePageName(); // This is my function you can ignore it
$new_rules = array(
'('.$template_page_name.')/search/(.*?)/?([0-9]{1,})/?$' => 'index.php?pagename='.
$wp_rewrite->preg_index(1).'&ypsearch='.
$wp_rewrite->preg_index(2).'&yppage='.
$wp_rewrite->preg_index(3),
'('.$template_page_name.')/search/(.*?)/?$' => 'index.php?pagename='.
$wp_rewrite->preg_index(1).'&ypsearch='.
$wp_rewrite->preg_index(2)
);
// Always add your rules to the top, to make sure your rules have priority
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');
Peace of cake, right? In this case you need to do one more thing, add your keys to $public_query_vars variable. As you see we added our rules to rewrite rules array, but we need to add keys to $global $wp_query variable, so lets do it.
function query_vars($public_query_vars) {
$public_query_vars[] = "ypsearch";
$public_query_vars[] = "yppage";
/* Note: you do not want to add a variable multiple times. As in
the example above, multiple rules can use the same variables
*/
return $public_query_vars;
}
add_filter('query_vars', 'query_vars');
Now your new pretty permalinks should work. Now i just want to show you how to get your key values.
global $wp_query, $wp_rewrite;
if ($wp_rewrite->using_permalinks()) { // WordPress using Pretty Permalink structure
$searchKey = $wp_query->query_vars['ypsearch'];
} else { // WordPress using default pwrmalink structure like www.site.com/wordpress/?p=123
$searchKey = $_GET['search']; // now we can get variables from $_GET variable
}
I show you most important functions you need to know how to use when create new rewrite rules in WordPress, if you want to know more start with WP_Rewrite class.
Hi.. this is article i m looking for..
if i have page template named: google.php
and have navigation/pager with page variabel: “paged”
can i use your function?
thanks
Hello webmaster
I would like to share with you a link to your site
write me here [email protected]
Hey nice tutorial ! It helped me to hunderstand rewrite rule in wordpress.
But it would be very intresting if you can add your getTemplatePageName(); function.
Thanks
wow thanks for this. I’ve been trying to make pretty links for my plugin and it’s been so frustrating, this clears it up a bit!
I can’t understand it.
perfect! 🙂
Hi, I’m using permalink using /%postname%/.
I tried to pass variables using wp_redirect as mentioned in the codex but it redirect me at the index.ph instead of staying in the request page.
Here is the code I use:
add_filter(‘query_vars’, ‘geotag_queryvars’ );
function geotag_queryvars( $qvars )
{
$qvars[] = ‘geostate’;
return $qvars;
}
add_action(‘init’, ‘geotags_flush_rewrite_rules’);
function geotags_flush_rewrite_rules()
{
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
add_action(‘generate_rewrite_rules’, ‘geotags_add_rewrite_rules’);
function geotags_add_rewrite_rules( $wp_rewrite )
{
$new_rules = array(
‘geostate/(.+)’ => ‘geostate=’ .
$wp_rewrite->preg_index(1) );
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
it work when you call http://mydomain.com/myblogfolder/geostate/something
but it won’t do if i use:
http://mydomain.com/myblogfolder/mypagepostname/geostate/something
Do you got any ideas?
Thanks for all!
Thanks, i need to change add my own permalink in the custom wordpress plugin written for my client.
Thanks a lot.
Good article, but what would have been better is actually making a simple plugin that showed how to do this for real..
Thank YOU ! This article really helped me !
I have $_GET variables in url like http://www.kennovations.com.au/?page_id=48&subnavi_id=2&pid=77&img=2
How can i rewrite this url. WordPress permalinks only replace page_id with that page title but i want to rewrite the complete url.
Thanks
RSS Feeds are really very helpful and you could get site and news updates from it.*.-
Hi there,
Thanks for explaining. But i’m still stuck. Can you help me out?
I am creating a new post type (‘webspots’).
For this content type i want to create new rewrite rules.
http://www.example.com/webspots/93/this-is-a-test-title/
should point to
http://www.example.com/?post_type=webspot&p=93
Can you explain me how to do this? I’m stuck for three days now. I researched other people’s plugin codes and read every article about this of the first 3 pages on google. But nowhere is explained on how to create (working!) custom rewrite rules for new post type’s.
RSS feeds are really great because you are always updated with the latest news or blog posts.`.*
I have rewritten rewrite rules in my htaccess in place before the WordPress rewrite.
I will rewrite /page/page/12345 to /page/page/?num=12345
Then that is what gets sent to the WordPress rules onto index.php. It works. It is just as if you typed /page/page/?num=12345 into the browser yourself with a $_GET in your template displaying the num.
Your tutorial is good info though. Cool.
Great article! Your writing is so much better in comparison to most other writers. Thanks for posting when you do, I will be sure to subscribe!
RSS feeds are really great if you want to stay updated ~~*
RSS feeds are necessary for transmitting your blog updates to your readers or followers-~~
hi,
I have wordpress installed in the root and I’m trying to incorporate some custom rewrite rules. they look like this:
RewriteRule ^blog[/]?$ index.php
RewriteRule ^writing[/]?$ writing.php
RewriteRule ^art[/]?$ art.php
RewriteRule ^music[/]?$ music.php
RewriteRule ^design[/]?$ design.php
RewriteRule ^animation[/]?$ animation.php
RewriteRule ^video[/]?$ video.php
RewriteRule ^contact[/]?$ contact.php
pretty straight forward stuff. my permalink structure is “/blog/%postname%/” so basically I want website.com/blog to direct to the wordpress home page but instead I get a 404. My other pages seem to work but I get a “page not found” in the page title which is strange.
Is what I’m trying to do possible?
i think that RSS FEEDS should also be included on the list of the best inventions because it makes life easier for bloggers like us ,-“
actually I need to add rewrite rules for the site, I am working on at my work place.
I am not good with url rewriting and our site is bit complicated, I am using 2 databases, one is wordpress’ own database and other is MSSQL database.
I want to add some rewrite rule which gains information from MSSQL database, so can you tell me how I can do that?
Any help would very much appreciated.
Thanks in advance.
Arpita
OMG!!! this is awesome explaination 🙂 i ve ever read abt WP rewriting and BTW the site design is simple and pleasing..
Nice post. But I’m wondering about how to auto generate custom permalink for custom post type. Do you have any solution?
Thank you, thank you, thank you! the add_rewrite_rules function example was just what i was looking for, works perfectly and now i can add more custom urls! thanks a lot
I have go through a handful of the content articles on your website now, and I like your style of blogging. I added it to my favorites site collection and will be checking back again in the near future.
Great post, but i just can’t get it to work, pls if you can tell me what i’m doing wrong.
array looks like:
…
[“news/archive/(.+?)/?$”]=>
string(25) “index.php?d=$1&page_id=84”
…
the url index.php?d=2010|08&page_id=84 work fine, but if i put /news/archive/2010|08 i get 404 error.
pls help, Jernej
Thank you! I had spent ages trying to get pagination to work!
Great tutorial.I have a page created in wp named “synonyme”. Now I like to use links like /synonyme/index/K/. I added in .htaccess this rule
RewriteRule ^synonyme/index/(.*)/$ /synonyme/?index=$1 [L]
But this does not work. I always get redirected to a post starting with the letter I use in index as value. But I need to go to page synonyme with get parameter “index”. I added in functions.php the code like described above, but it does not work.
Hi,
Great tutorial, I am hoping you can help me with my issue to clarify what I need to do.
I have the following code:
function add_rewrite_rules()
{
global $wp_rewrite;
$new_rules = array(
‘([0-9]+)/?$’ => ‘/wp-login.php?action=register&ref=’.$wp_rewrite->preg_index(1),
‘([0-9]+)/?$’ => ‘?ref=’.$wp_rewrite->preg_index(2)
);
# Always add your rules to the top, to make sure your rules have priority
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
return $wp_rewrite;
}
function add_custom_page_variables($public_query_vars) {
$public_query_vars[] = “action”;
$public_query_vars[] = “ref”;
return $public_query_vars;
}
function template_redirect_intercept() {
global $wp_query;
$_REQUEST[‘action’] = $wp_query->get(‘action’);
if ($ref = $wp_query->get(‘ref’)) {
if(isset($_COOKIE[‘ref’])) {
setcookie(‘ref’, 0, time()-1, “/”);//Unsetting
}
setcookie(‘ref’, $ref, time()+86400*30*3, “/”);//Setting new
// include(ABSPATH.”/wp-login.php”);
// exit;
}
}
when I use url like http://www.mysite.com/1 my cookie is set and the page is displayed correctly as long as a ‘static’ home page has not been set, if a ‘static’ page is set in ‘settins/reading’ in WP admin then the returned page is the ‘blog’ page. I think that what I need to do is rewrite URL like http://www.mysite.com/index.php?ref=1 to http://www.mysite.com but I just don’t seem to be getting what I need to do here.
Can you help point me in the correct direction?
Thanks!
I’m looking for a solution, no I fould it. Thanks.
I just have a little question, I see many articles teached us to flush the rewrite rules in hook init, is it required?
e.g. add_action( ‘init’, ‘flush_rewrite_rules’ );