Funny business with add_rewrite_rule() and “external” rewrites

There’s some funny business going on when you try to add a custom rewrite rule to WordPress and it gets interpreted as an “external” rule. What’s going on?

add_rewrite_rule() is used to add rewrite rules to WordPress. It’s used to instruct WordPress to translate URLs such as

http://example.com/France/Paris/Eiffel_Tower

to:

http://example.com/index.php?country=France&city=Paris&landmark=Eiffel_Tower

To achieve this, you use the function like this:

add_rewrite_rule( 
    '^([^/]*)/([^/]*)/([^/]*)', 
    'index.php?country=$matches[1]&city=$matches[2]&landmark=$matches[3]' 
);

There’s a nice tutorial about the function over at Pippin’s plugins.

The examples given on the Codex page are OK if you use the function to add a rewrite that direct to the index.php file. However, if the redirect target is not the index.php, WordPress interprets the redirect as an “external” and writes it to the .htaccess file instead.

There are (at least) three undocumented catches here:

  1. The redirect URL must be relative, because in the .htaccess file it gets preceded by a slash /. That makes for example plugins_url() unusable in conjunction with add_rewrite_rule().

  2. The $matches[1] syntax won’t work, because it gets written in the .htaccess file as such, and it is not understood by Apache.

  3. The regex gets prepended with ^ in the .htaccess, so if it already starts with ^, you get two.

Advertisements
Tagged , ,

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

%d bloggers like this: