Create your own rewrite rules in WordPress

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

<IfModule mod_rewrite.c>
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

This function “getRewriteRules”, will return array with listed rewrite rules. Array will be something like …

    // ....
    [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(2).'&yppage='.     $wp_rewrite->preg_index(3),		
		'('.$template_page_name.')/search/(.*?)/?$' => 'index.php?pagename='.
       // 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   $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.


Leave a Reply