Contents

Role of WP_Rewrite

WP_Rewrite is WordPress' class for managing the rewrite rules that allow you to use Pretty Permalinks feature. It has several methods that generate the rewrite rules from values in the database. It is used internally when updating the rewrite rules, and also to find the URL of a specific post, Page, category archive, etc.. It's defined in wp-includes/rewrite.php as a single instance global variable, $wp_rewrite, is initialised in wp-settings.php.

Methods and Properties

This is the formal documentation of WP_Rewrite. Try not to access or set the properties directly, instead use the methods to interact with the $wp_rewrite object. See also Rewrite_API.

Properties

$permalink_structure

The permalink structure as in the database. This is what you set on the Permalink Options page, and includes 'tags' like %year%, %month% and %post_id%.

$category_base

Anything to be inserted before category archive URLs. Defaults to 'category/'.

$category_structure

Structure for category archive URLs. This is just the $category_base plus '%category%'.

$author_base

Anything to be inserted before author archive URLs. Defaults to 'author/'.

$author_structure

Structure for author archive URLs. This is just the $author_base plus '%author%'.

$pagination_base

Anything to be inserted before pagination indices. Defaults to 'page/'.

Structure for search URLs. This is just the $search_base plus '%search%'.

$comments_base

Anything to be inserted just before the $feed_structure to get the latest comments feed. Defaults to 'comments'.

$comments_feed_structure

The structure for the latest comments feed. This is just $comments_base plus $feed_base plus '%feed%'.

$date_structure

Structure for dated archive URLs. Tries to be '%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%' or '%monthnum%/%day%/%year%', but if none of these are detected in your $permalink_structure, defaults to '%year%/%monthnum%/%day%'. Various functions use this structure to obtain less specific structures: for example, get_year_permastruct() simply removes the '%monthnum%' and '%day%' tags from $date_structure.

$page_structure

Structure for Pages. Just '%pagename%'.

$front

Anything up to the start of the first tag in your $permalink_structure.

$root

The root of your WordPress install. Prepended to all structures.

$matches

Used internally when calculating back references for the redirect part of the rewrite rules.

$rules

The rewrite rules. Set when rewrite_rules() is called.

$non_wp_rules

Associative array of "rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all)" roughly in the form 'Pattern' => 'Substitution' (see below).

$rewritecode

An array of all the tags available for the permalink structure. See Using Permalinks for a list.

$rewritereplace

What each tag will be replaced with for the regex part of the rewrite rule. The first element in $rewritereplace is the regex for the first element in $rewritecode, the second corresponds to the second, and so on.

$queryreplace

What each tag will be replaced with in the rewrite part of the rewrite rule. The same correspondance applies here as with $rewritereplace.

Methods

add_rewrite_tag($tag, $pattern, $query)

Add an element to the $rewritecode, $rewritereplace and $queryreplace arrays using each parameter respectively. If $tag already exists in $rewritecode, the existing value will be overwritten. See also: add_rewrite_tag($tagname, $regex)

A large function that generates the rewrite rules for a given structure, $permalink_structure. If $page is true, an extra rewrite rule will be generated for accessing different pages (e.g. /category/tech/page/2 points to the second page of the 'tech' category archive). If $feed is true, extra rewrite rules will be generated for obtaining a feed of the current page, and if $forcomments is true, this will be a comment feed. If $walk_dirs is true, then a rewrite rule will be generated for each directory of the structure provided, e.g. if you provide it with '/%year%/%month%/%day/', rewrite rules will be generated for '/%year%/', /%year%/%month%/' and '/%year%/%month%/%day%/'. This returns an associative array using the regex part of the rewrite rule as the keys and redirect part of the rewrite rule as the value.

Populates the corresponding property (e.g., $date_structure for get_date_permastruct()) if it's not already set and returns it. The functions get_month_permastruct() and get_year_permastruct() don't have a corresponding property: they work out the structure by taking the $date_structure and removing tags that are more specific than they need (i.e., get_month_permastruct() removes the '%day%' tag, as it only needs to specify the year and month).

init()

Set up the object, set $permalink_structure and $category_base from the database. Set $root to $index plus '/'. Set $front to everything up to the start of the first tag in the permalink structure. Unset all other properties.

mod_rewrite_rules()

returns a string (not an array) of all the rules. They are wrapped in an Apache <IfModule> block, to ensure mod_rewrite is enabled.

page_rewrite_rules()

Returns the set of rules for any Pages you have created.

rewrite_rules()

populate and return the $rules variable with an associative array as in generate_rewrite_rules(). This is generated from the post, date, comment, search, category, authors and page structures.

set_category_base($category_base)

Change the category base.

set_permalink_structure($permalink_structure)

Change the permalink structure.

using_index_permalinks()

Returns true if your blog is using PATHINFO permalinks.

using_mod_rewrite_permalinks

Returns true your blog is using "pretty" permalinks via mod_rewrite.

using_permalinks()

Returns true if your blog is using any permalink structure (i.e. not the default query URIs ?p=n, ?cat=n).

WP_Rewrite (constructor)

Calls init().

wp_rewrite_rules()

returns the array of rewrite rules as in rewrite_rules(), but using $matches[xxx] in the (where xxx is a number) instead of the normal mod_rewrite backreferences, $xxx (where xxx is a number). This is useful when you're going to be using the rules inside PHP, rather than writing them out to a .htaccess file.

Plugin Hooks

As the rewrite rules are a crucial part of your website's functionality, WordPress allows plugins to hook into the generation process at several points. rewrite_rules(), specifically, contains nine filters and one hook for really precise control over the rewrite rules process. Here's what you can filter in rewrite_rules():

generate_rewrite_rules - This action hook runs after all the rules have been created. If your function takes a parameter, it will be passed a reference to the entire $wp_rewrite object.

mod_rewrite_rules() is the function that takes the array generated by rewrite_rules() and actually turns it into a set of rewrite rules for the .htaccess file. This function also has a filter, mod_rewrite_rules, which will pass functions the string of all the rules to be written out to .htaccess, including the <IfModule> surrounding section. (Note: you may also see plugins using the rewrite_rules hook, but this is deprecated).

Examples

(See also: Permalinks for Custom Archives)
The most obvious thing a plugin would do with the $wp_rewrite object is add its own rewrite rules. This is remarkably simple. Filter the generic rewrite_rules_array.

Keep in mind that the flush_rules function is quite slow, so in practice you never want to call it from the wp_loaded action that gets executed on each page load. Instead, call this function only when the rewrite rules change. If the rules get set up and then never change, it is enough to flush in register_activation_hook of your plugin.

The Jerome's Keywords plugin does this to enable URLs like http://example.com/tag/sausages.

Instead of inserting the rewrite rules into the $rewrite array itself, Jerome chose to create a second array, $keywords_rewrite, using the WP_Rewrite function generate_rewrite_rules(). Using that function means that the plugin doesn't have to create rewrite rules for extra pages (like page/2), or feeds (like feed/atom), etc. This array is then appended onto the $rewrite array and returned.

As the array is so simple here, there is no need to call generate_rewrite_rules(). Again, the plugin's rules are added to WordPress'. Notice that as this function filters generate_rewrite_rules, it accepts a reference to the entire $wp_rewrite object as a parameter, not just the rewrite rules.

Of course, as you're adding your rewrite rules to the array before WordPress does anything with them, your plugins rewrite rules will be included in anything WordPress does with the rewrite rules, like write them to the .htaccess file.