WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In general, the code from this question fit to me for 90%. One little change I need - I want all URL like *example.com/snpv/any_text/* direct not to index.php as in original code, but to my.php script in root of my THEME (not site!). So, I correct the code for my needs:

register_activation_hook(__FILE__, 'make_flush_rules');
function make_flush_rules()
    add_rewrite_rule('snpv/([^/]+)', '/wp-content/themes/lightsaber/my.php?prm1=$matches[1]', 'top');

add_filter('query_vars', 'make_query_vars');
function make_query_vars($query_vars)
    $query_vars[] = 'prm1';
    return $query_vars;

To make picture clear:

  • lightsaber-my Theme
  • my.php-just independent script. It is not page (or, to be precise, not WP page) or page template, just php-code to generate some output

I create this plugin and activate it. Enter URL example.com/snpv/ABC/ and get 404 page. :( How to correct problem? Thanks!

share|improve this question
you can't direct rewrite rules to other scripts, everything should still be directed to index.php, but you should also set up a hook early in the request to check if your special query var has been set and execute your code then. – Milo Dec 17 '11 at 15:24
Thanks a lot for you answer! I understand - straight redirect to my.php is impossible. :( Can you tell, please, the name of hook (filter?) you mention above? – Smarty Dec 18 '11 at 6:58
see answer with the code. – Milo Dec 18 '11 at 19:21
up vote 2 down vote accepted

Here's an example with template_redirect that loads your php script if the prm1 query var is set:

// set up the rewrite
add_action( 'init', 'wpse36736_setup_rewrites' );
function wpse36736_setup_rewrites(){
    add_rewrite_rule( 'snpv/([^/]+)', 'index.php?prm1=$matches[1]', 'top' );

// add query var
add_filter('query_vars', 'wpse36736_query_vars');
function wpse36736_query_vars( $query_vars ){
    $query_vars[] = 'prm1';
    return $query_vars;

// check the query var on template_redirect
add_filter( 'template_redirect', 'wpse36736_template_redirect' );
function wpse36736_template_redirect(){
    global $wp_query;
    if( $wp_query->get( 'prm1' ) ):
        include( get_template_directory() . "/prm1.php" );

You can then access prm1 in your script via:

$prm1 = get_query_var( 'prm1' );

The only strange thing about this is the way WordPress interprets this query, the behavior in 3.3 seems to be a bit different than with previous versions. If you inspect the global $wp_query variable set for any of these requests, everything is populated as if it's the main posts page and is_404 is false. I recall this wasn't the case back when I tried to help out on this question.

Anyway, what I typically do in this situation is create a page, say snpv, and change the rewrite rule to 'index.php?pagename=snpv&prm1=$matches[1]'.

share|improve this answer
+1 quick & simple – mate64 Feb 28 '13 at 12:14

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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