I have a main page and beyond that it has children. I successfully rewrite the children like so:

add_rewrite_rule('my-url/?([^/]*)', 'index.php?my-var=$matches[1]', 'top');

This works great. But when I try to rewrite the base:

add_rewrite_rule('my-url/?', 'index.php?my-var=main', 'top');

... it doesn't work. I know, it's getting rewritten by the first rule, so I switched them around, but then the children were all getting redirected to the main page.

Is there a way to make the second rule strict so that it will only be effective if there is NOTHING after the "my-url/" ? This way I should be able to move it first, and all should work.

I have searched the net and found no solution. Maybe it's my terms, but I'm racking myself on this one. I hate regex! Shoot me if it's simple!


Change your rewrite rules and the order to the following:

add_rewrite_rule('my-url/([^/]*)/?$', 'index.php?my-var=$matches[1]', 'top');
add_rewrite_rule('my-url/?$', 'index.php?my-var=main', 'top');

Why the order? If the order would be the other way around, the first rule will always apply, so the ruleset would never reach your main page

Why the changed syntax? To allow an additional query string to be properly processed. E.g. http://foo.bar/my-url/?my-var=foo and http://foo.bar/my-url/foo/?bar=1 should be fetched to.

Additionally: A template redirect, if you want to apply your rewrite rules to query string requests like http://foo.bar/my-url/?my-var=foo:

function custom_template_redirect(){
    preg_match('/(\?|&)my-var=/', $_SERVER['REQUEST_URI'], $matches);
    if (
        get_query_var( 'my-var', false ) !== false &&
        !empty($matches) &&
    ) {
                '/my-url/'.(get_query_var( 'my-var' )?get_query_var( 'my-var' ).'/':'')

add_action( 'template_redirect', 'custom_template_redirect' );
  • 1
    Perfect, works great. Thanks! Thanks for the explanations! – Joshua4550 Mar 14 '16 at 7:23

This should work for both, slight adjustments to each regex pattern-

add_rewrite_rule('my-url/([^/]+)/?$', 'index.php?my-var=$matches[1]', 'top');
add_rewrite_rule('my-url/?$', 'index.php?my-var=main', 'top');
  • Thanks. I think this would work - I accepted the answer that was below you as it had explanations and was more useful to other users. Thanks again! – Joshua4550 Mar 14 '16 at 7:23

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.