Custom .htaccess rewrite rules in WordPress

Dan Marvelo
I’m working on a WordPress plugin to store content as posts in WordPress, but display the content a unique manner, outside of the post / page frame.

this included wanting a unique URL pattern to access that content. after some digging in WordPress code, I got some simple URL customization working.

there is some info on the codex page titled WP Rewite API, but seems to be in development, and is short on specific information.

the code

the main plugin file should have something similar to this:


function plugin_add_custom_urls() {
  add_rewrite_rule('(calendar)/[/]?([0-9]*)[/]?([0-9]*)$',
  'index.php?pagename=$matches[1]&var1=$matches[2]&var2=$matches[3]');

  add_rewrite_tag('%var1%', '[0-9]+');
  add_rewrite_tag('%var2%', '[0-9]+');
}

// runs the function in the init hook
add_action('init', 'plugin_add_custom_urls');

some explanation

just about every request to WordPress is translated to a request of the index.php with query string values. if you have the fancy permalinks enabled, Apache will redirect all the traffic to index.php, then at some point WordPress does the translation from the fancy URL to the query string.

using the add_rewrite_rule function adds your own translation rule to the default set that WordPress already has.

matching regular expression

the first parameter is the regular expression to match against the incoming request. if the request is “http://yoursite.com/calendar/12/2”, the expression attempts to match the portion after the domain name, or “calendar/12/2”.

this isn’t a tutorial on regular expressions, and I’m not the one to do it anyways. just note that the parentheses are important as these indicate portions of the URL that will be matched, and end up in the resulting matches array.

translation to index.php

the second parameter is the translated request to index.php with the query string values. the translation code runs the regular expression against the request, and comes up with the matches in the $matches array. then evaluates the second parameter to this function call, so $matches[1] in the string turns in to the value referenced in the array. in this example, that will be “calendar”.

in the above example, the “calendar/12/2” request turns in to “index.php?pagename=calendar&var1=12&var2=2” because $matches[1] = “12” and $matches[2] = “2”. $matches[0] = “calendar/12/2”, by the way.

recognising query string variables

the call to the add_rewrite_tag function introduces WordPress to the query string variables used in the second parameter of add_rewrite_rule, making them available in the $wp_query object and the get function.

a snippet from a function meant for a template:

function plugin_get_calendar() {
  global $wp_query;

  $var1 = $wp_query->get('var1');
  $var2 = $wp_query->get('var2');

}

some caveats

any rules added with the function are at the end of the list, and WordPress stops after finding the first match. if the URL is matched by one of the default WordPress rules, it won’t reach your custom rule.

the list of rules is stored as an option in the options table. when a request comes in to WordPress, it first checks for the row in the options table, and uses that list if it finds it. this means the rule list needs to be flushed after any changes to the add_rewrite_rule function call. this flush occurs when the Permalinks page is loaded in the WordPress admin, which calls the flush_rules function.

Reposted from: custom rewrite rules in WordPress (add_rewrite_rule and add_rewrite_tag)

Advertisements

2 thoughts on “Custom .htaccess rewrite rules in WordPress

  1. Hi there,
    I have my WordPress installed at:
    mysite/blog/
    I want the about page to be accessible with:
    mysite/about/

    I tried setting up an .htaccess file in the root with:
    RewriteRule ^about(.*)$ blog/?page_id=203$1 [L,NC]

    This works, but pulls to:
    mysite/blog/about/
    because interfears with WordPress’ .htaccess (I use the pretty permalinks)

    I tried adding the rewrite rule above the # BEGIN WordPress – # END WordPress block but no luck.
    I am also not sure about the RewriteBase as I want to target up level up.

    Any help appreciated!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s