1

I am using URL rewrite like this page: unexpected problem in url rewrite

It works without any problem, but when I try to use the same rules for nested page, it doesn't work. Say, I have two pages named page-a and page-b. page-a is parent for page-b. Now I want to catch the passed variable. The URL structure will be:

page-a/page-b/
page-a/page-b/var1/
page-a/page-b/var1/var2/
page-a/page-b/var1/var2/var3/

So, I created three rules. The full code is as follows:

add_filter( 'query_vars', 'wpse26388_query_vars' );
function wpse26388_query_vars( $query_vars ){
    $query_vars[] = 'var1';
    $query_vars[] = 'var2';
    $query_vars[] = 'var3';
    return $query_vars;
}

function wpse26388_rewrites_init(){
     add_rewrite_rule(
        'page-a/page-b/([0-9]+)/?$',
        'index.php?pagename=page-b&var1=$matches[1]',
        'top' );

    add_rewrite_rule(
        'page-a/page-b/([0-9]+)/([0-9]+)/?$',
        'index.php?pagename=page-b&var1=$matches[1]&var2=$matches[2]',
        'top' );

    add_rewrite_rule(
        'page-a/page-b/([0-9]+)/([0-9]+)/([0-9]+)/?$',
        'index.php?pagename=page-b&var1=$matches[1]&var2=$matches[2]&var3=$matches[3]',
        'top' );
}
add_action( 'init', 'wpse26388_rewrites_init' );

I am using Rewrite analyzer and the variables get the correct regex values. Now when I go to that page with parameter like page-a/page-b/10/20, the parameters are truncated automatically. get_query_var('var1') doesn't get anything. So, if I pass 1, 2 or 3 parameter it will always redirect to page-a/page-b/.

Can anyone point me what I'm doing wrong?

I know this regex capture numbers. But I need regex so that anything that comes after page-a/page-b/ will be captured by the query variables. I hope someone can help me with this too.

  • If page-a is the parent of page-b, then the url would be page-a/page-b/var.... – cale_b Oct 19 '13 at 5:13
  • @cale_b Fixed it. – sakibmoon Oct 19 '13 at 6:20
0

Okies, so before we begin doing anything with regex besides numbers, lets take a look at all of your patterns really quick:

add_rewrite_rule(
    'page-a/page-b/([0-9]+)/?$',
    'index.php?pagename=page-b&var1=$matches[1]',
    'top' );

This rule is added to the top of the list, first. This means that it will be processed LAST of these 3 rules. This rule looks like it does what you want it to.

add_rewrite_rule(
    'page-a/page-b/([0-9]+)/([0-9]+)/?$',
    'index.php?pagename=page-bs&var1=$matches[1]&var2=$matches[2]',
    'top' );

This rule is processed 2nd (of these 3 rules). This rule's pattern looks fantastic, however, the url it's rewriting too looks like it has a typo. Change pagename=page-bs to pagename=page-b, unless you have a pagename of page-bs on your site.

add_rewrite_rule(
    'page-a/page-b([0-9]+)/([0-9]+)/([0-9]+)/?$',
    'index.php?pagename=page-b&var1=$matches[1]&var2=$matches[2]&var3=$matches[3]',
    'top' );

Finally, this rule is processed FIRST (of these 3 rules). This rule's rewrite looks fine, however it looks like your pattern has a typo. Change 'page-a/page-b([0-9]+)/([0-9]+)/([0-9]+)/?$' to 'page-a/page-b/([0-9]+)/([0-9]+)/([0-9]+)/?$' (you missed a forward slash after page-b).

Now, after those typos are corrected, we should be rewriting to the correct rule, depending on the number of slashes (or query vars, in this case). Keep in mind that Regex is [b]very[/b] picky when it comes to typos and making sure that your pattern is correct. It looks like your rules are in the correct order as well.

Now, if we want to match anything more than numbers, we need to specify this in our regex patterns. Usually we want to match numbers, lowercase letters, uppercase letters, and hyphens when we do URL rewriting. To do this we need to change all instances of ([0-9]+) to ([0-9a-zA-Z-]+).

Here is an example URL and its corresponding pattern: URL: www.example.com/page-a/page-b/my-cool-new-slug-12/my-cool-new-subslug-11/ Rewrite Rule:

add_rewrite_rule(
    'page-a/page-b/([0-9a-zA-Z-]+)/([0-9a-zA-Z-]+)/?$',
    'index.php?pagename=page-b&var1=$matches[1]&var2=$matches[2]',
    'top' );

Expected Rewritten URL: www.example.com/index.php?pagename=page-b&var1=my-cool-new-slug-12&var2=my-cool-new-subslug-11

Hope that helps!

Let me know if you have any questions.

  • thanks for the answer. But you are missing the main point. I changed the original page name to page-a and page-b. Typos happened for that. My original code has no typo. The problem is, parameters aren't passed to that page. Instead parameters are ripped off. When I go to /page-a/page-b/10/20/30 the page redirect to /page-a/page-b/ and I don't get any parameter in that page. – sakibmoon Oct 19 '13 at 6:27
0

I have found my answer while searching. Thanks to this answer of @Milo: https://wordpress.stackexchange.com/a/50775/23214

pagename must include the full parent/child path. So, I had to change index.php?pagename=page-b... to index.php?pagename=page-a/page-b.... Changed it and works ok.

Here is the Full code:

add_filter( 'query_vars', 'wpse26388_query_vars' );
function wpse26388_query_vars( $query_vars ){
    $query_vars[] = 'var1';
    $query_vars[] = 'var2';
    $query_vars[] = 'var3';
    return $query_vars;
}

function wpse26388_rewrites_init(){
     add_rewrite_rule(
        'page-a/page-b/([0-9]+)/?$',
        'index.php?pagename=page-a/page-b&var1=$matches[1]',
        'top' );

    add_rewrite_rule(
        'page-a/page-b/([0-9]+)/([0-9]+)/?$',
        'index.php?pagename=page-a/page-b&var1=$matches[1]&var2=$matches[2]',
        'top' );

    add_rewrite_rule(
        'page-a/page-b/([0-9]+)/([0-9]+)/([0-9]+)/?$',
        'index.php?pagename=page-a/page-b&var1=$matches[1]&var2=$matches[2]&var3=$matches[3]',
        'top' );
}
add_action( 'init', 'wpse26388_rewrites_init' );

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.