I want to access a plugin file (when <a> is clicked) without exposing actual path of the file. I am using the following rewrite rule:

add_rewrite_rule( 'continue/([0-9]+)/?$', 'wp-content/plugins/my-plugin/continue.php?where=$matches[1]', 'top' );

The request is redirected to continue.php but I always get $_GET['where']=$matches[1] instead of $_GET['where']=123 inside continue.php. It should have been replaced by some number.

I want something similar to this


I have tried Monkeyman Rewrite Analyzer but my rule does not show up in it. Then why am I being redirected to the correct page?

e.g. for continue/2 it has the following output:

(.+?)(/[0-9]+)?/?$ pagename: continue page: /2

  • After you added your rewrite rule, did you flush your rule set? You can do this programmatically by calling flush_rewrite_rules() or force it by loading the permalink settings page. – EAMann Aug 29 '11 at 15:55
  • @eamann I was about to send you this Q's link! Yeah, I did that. In fact, the request is redirected correctly. The only problem is that $matches[1] is not being evaluated. Am I supposed to use $_GET['where']? – a_fan Aug 29 '11 at 15:57
  • 1
    Since your query variable is "where" you should be using $_GET['where'] – EAMann Aug 29 '11 at 16:24
  • Is your rewrite showing up in the list (from the Rewrite Analyzer) at all? – EAMann Aug 29 '11 at 17:01
  • No, it does not. Otto just explained why. His explanation is remarkable. Thanks a lot for time and effort! Really appreciate it! :) – a_fan Aug 29 '11 at 17:31

That rewrite rule won't work at all, flushed or not.

There's two kinds of rewrite rules in WordPress. Those that have their rewrite urls start with index.php and those that don't.

All WordPress internal rewrite rules must start with index.php. It can't redirect to anyplace else, because it's already been redirected to the index.php file by the time the WordPress functions are processing the ruleset. So non-index.php rules have to go into the .htaccess directly, so that they can be redirected to anywhere other than index.php.

  • Those that start with index.php will be processed inside WordPress itself, and the $matches[1] syntax will be the correct one to use in that case.

  • Those that don't start with index.php will instead be written to the .htaccess file as direct RewriteRules. The $matches[1] syntax makes no sense in that case.

If you look in your .htaccess file after using your rule, you'll find this:

RewriteRule continue/([0-9]+)/?$ wp-content/plugins/my-plugin/continue.php?where=$matches[1]

Which obviously won't work.

Instead, try making your code into this:

add_rewrite_rule( 'continue/([0-9]+)/?$', 'wp-content/plugins/my-plugin/continue.php?where=$1');

Note the $1 replacement instead? This will work properly when converted to a normal RewriteRule.

| improve this answer | |
  • I'm using a rewrite rule that starts with index.php but $matches[1] still doesn't get replaced, why could that be? – Petruza May 18 '15 at 18:36
  • Great info! I've added a summary of it to the WordPress docs, which were previously completely silent about this nuance. If you could look it over to make sure it's accurate, I'd really appreciate it. – Nathan Arthur Feb 6 '19 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.