Let’s say I create a customer support plugin that hijacks the /support part of the URL and redirects it to an MVC framework in my app folder of my plugin folder, like so:
RewriteRule ^support(.*)$ wp-content/plugins/csupport/app/$1 [L]
I know that I can do this in a blog’s .htaccess right before the RewriteBase line, but not everyone has .htaccess turned on unless they add a custom permalink. I found a technique to force custom permalinks, but that’s brute force and not recommended.
What is the recommended way for plugin developers to add a rewrite rule so that they can capture a subdirectory call like /support and redirect it to somewhere else?
Here’s a solution. See comments at the end…
You should never run flush_rewrite_rules() all the time. Andrew Nacin, one of the core devs for WordPress, advises on more than one occasion that this must be done from a plugin or theme’s activation and deactivation callbacks. (Themes don’t have these callbacks, but there are examples on the web that kludge theme callbacks for activation/deactivation.) Andrew says it degrades performance, if otherwise. This is obvious because it could potentially rewrite the .htaccess file every time a page load occurs.
I use static class methods instead of global functions in the namespace. It’s less dangerous and more tidy.
Note the sequence in the activatePlugin() — that’s important. You should rewrite the URL, flush the rules, and, if custom permalinks are not turned on, turn them on.
Custom permalinks are crucial. Without them you don’t get the .htaccess file and thus no rewrite rules.
Note that we don’t blindly brute-force custom permalinks on someone. We see if they have these enabled. If not, we turn them on and use a common kind of permalink often used with SEO.
Note my updatePermalinks() function has a problem. It’s something I detected in all versions of WordPress. I found that the .htaccess file was not being created unless one clicked to see the Permalinks options panel. I have no idea why WordPress has this bug, but it does. So, as you can see with the IFRAME below, I came up with a decent workaround. That IFRAME will ensure the .htaccess file gets created if it was not — as long as that call to updatePermalinks() was done previously.
The WordPress Codex seemed to indicate that I would have all kinds of problems with query parameters in my rewritten URL if I didn’t implement add_query_vars(). However, I found that not to be the case at all. I was able to hijack /support and redirect it to an MVC framework inside my plugin, and then load that framework up with fancy URLs like /support/tickets/1, as well as use query parameters on the end like /support/tickets/1?q=open&s=sample+keywords.
Note that:
add_rewrite_rule(‘support(.*)$’,’wp-content/plugins/sample/app/$1′,’top’);
…equates to:
RewriteRule ^support(.*)$ /wp-content/plugins/sample/app/$1 [QSA,L]
…in the .htaccess file, which is exactly what I needed.
As for why the docs are so confusing and misleading on the topic of RewriteRules, I have no idea.
EDIT1: Changed site_url() to admin_url() in the IFRAME call.