How do I add a server-independent external rewrite rule?

External rewrite rules are awesome. They let you define rewrites that don’t necessarily pass through WordPress’ index.php. This means you can map arbitrary rules to arbitrary files like:

$wp_rewrite->add_external_rule( '^somethingrandom/?$', 'wp-content/wp-uploads/hiddendirectory/somefile.php' );

Then, any request to http://site.url/somethingrandom/ will actually be served a static PHP file from a different directory. This is amazing, and it lets you do all sorts of nifty stuff.

Read More

But it only works with Apache.

The add_external_rule() method writes its registered rules out to .htaccess. Since Nginx doesn’t use an .htaccess file, external rules are completely ignored by that server. What I need is a server-independent way to programatically register rules like the one above. Any ideas?

Related posts

Leave a Reply

1 comment

  1. This also assumes .htaccess files are enabled in Apache, which almost always is in shared hosting, but is often disabled in enterprise environments. One way to accomplish this would be to write your own add_external_nginx_rule function that writes redirets out to a file (could use .htaccess even, though that might be confusing – it should be a hidden file starting with . no matter what) that you then include in your Nginx server block like

    include /var/www/html/sitefolder/.htaccess;
    

    In your function, you’d write out redirects in Nginx format, which is nearly the same as Apache format in many cases. This is probably something you could turn into a plugin even. It does require special configuration in your Nginx config file, but using .htaccess in Apache requires that to be enabled in the Apache config file as well, so you could argue it is the same concept.

    Note: I haven’t tried any of this, but see no reason this wouldn’t work. Would be worth exploring.

    Update: Mark is right in the comments – this wouldn’t work because Nginx only reads configuration files upon initial startup or reload, so you’d need to restart Nginx with any change, which makes this solution problematic from a security standpoint.