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
    Commented Aug 29, 2011 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
    Commented Aug 29, 2011 at 15:57
  • 1
    Since your query variable is "where" you should be using $_GET['where']
    – EAMann
    Commented Aug 29, 2011 at 16:24
  • Is your rewrite showing up in the list (from the Rewrite Analyzer) at all?
    – EAMann
    Commented Aug 29, 2011 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
    Commented Aug 29, 2011 at 17:31

1 Answer 1


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.

  • I'm using a rewrite rule that starts with index.php but $matches[1] still doesn't get replaced, why could that be?
    – Petruza
    Commented May 18, 2015 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. Commented Feb 6, 2019 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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