Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have the following code in my functions.php file.

<?php
add_action('init', 'flush_rewrite_rules');

function custom_add_rewrite_rules( $wp_rewrite ) {
    $new_rules = array( 
        'insurance-leads-types/auto-insurance-leads/([^/\.]+)/?$' => 'index.php?pagename=auto-insurance-leads&state=' . $wp_rewrite->preg_index(1),
        'insurance-leads-types/home-insurance-leads/([^/\.]+)/?$' => 'index.php?pagename=home-insurance-leads&state=' . $wp_rewrite->preg_index(1)
    );
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'custom_add_rewrite_rules');

function add_query_vars( $query_vars ) {
  $query_vars[] = 'state';
  return $query_vars;
}
add_filter( 'query_vars', 'add_query_vars' ); 

When I go to the page /insurance-leads-types/auto-insurance-leads/STATENAME/ the URL is redirected to /insurance-leads-types/auto-insurance-leads/ without the trailing STATENAME/ and the variable is not passed to $query_vars.

I used Monkeyman's Rewrite Analyzer and everything looks fine:

pagename: auto-insurance-leads

state: (.[^/]+)

Any ideas why the URL is redirecting?

share|improve this question
    
I'll remove the add_action('init', 'flush_rewrite_rules'); once I get this working. –  Christopher Harden Feb 16 '12 at 18:53
    
FYI - Like a normal rewrite, I want the entire URL of the rewrite to remain in the address bar of the browser. –  Christopher Harden Feb 16 '12 at 18:57

2 Answers 2

You should probably use the built in rewrite api functions rather than using the generate_rewrite_rules filter. There are some issues with your rewrite regex. You need to start each with a carrot ^, to tell WP to match starting at the beginning of the URL.

I'm not really sure what you're trying to accomplish with the ([^/\.]+). Anything that isn't a slash or a period? If that's the case, it's probably not going to work the way you expect. Someone could enter insurance-leads-types/auto-insurance-leads/tx.state/ and it wouldn't get matched becauase your regex doesn't account for the stuff following the dot.

Here is a working version that will match anything that isn't a slash in the final group.

<?php
add_action( 'init', 'wpse42604_add_rewrite' );
function wpse42604_add_rewrite()
{
    add_rewrite_rule(
        '^insurance-leads-types/auto-insurance-leads/([^/]+)/?$',
        'index.php?pagename=auto-insurance-leads&state=$matches[1]',
        'top'
    );
    add_rewrite_rule(
        '^insurance-leads-types/home-insurance-leads/([^/]+)/?$',
        'index.php?pagename=home-insurance-leads&state=$matches[1]',
        'top'
    );
}

All the code as a plugin. I wrote a really big tutorial about the rewrite api that's worth a look.

Edit: Also, you might get some unpredictable behavior flushing rewrite rules one very page load like your code does.

share|improve this answer
    
I tried the code that you provided and now I get a 404. The page you requested could not be found. –  Christopher Harden Feb 16 '12 at 20:17
    
The regex here isn't the issue. I'm using this to parse a variable from a page link that I have created myself. The regex that I created works for my purposes. The REWRITE ANALYZER plugin shows that I have everything inserted correctly. The problem has to be somewhere else. Why does Wordpress redirect to the base PAGE? –  Christopher Harden Feb 16 '12 at 21:06
    
After more testing I can see it has something to do with this being a second level page. If I use my exact same original code and point to a first level page, the process works just fine; the URL with the extra VAR info remains and the variable passes to the page and displays. Any ideas why a second level page is redirecting to the base page? –  Christopher Harden Feb 16 '12 at 21:52
    
I just realised after posting my answer part of your issue may be that the pagename query var should be the slug of both the parent and child page with a slash in between as they appear in the URL. –  sanchothefat Nov 16 '12 at 10:42

I would approach this using the add_rewrite_endpoint() function.

It takes care of adding query vars and is a lot more straight forward to set up plus you won't need to worry about page slugs changing etc...

The code would be:

// in functions.php
add_action( 'init', 'wpse42604_add_endpoints' );
function wpse42604_add_endpoints() {
   add_rewrite_endpoint( 'state', EP_PAGES );
}

// in template file eg. page.php   
if ( '' != get_query_var( 'state' ) ) {
    // ... do stuff with the state query var
}

The one downside (depending on how you look at it) is you won't get the exact URLs you're specifying above, they will be like this:

insurance-leads-types/auto-insurance-leads/state/tx/

But it's a more robust and flexible solution, plus that URL is still nice looking and readable.

The problem you're seeing is one I've run into before to do with WordPress's processing of the rewrite rules performing a canonical redirect before looking at the rewrites. Unfortunately it's a while since I traced through it so can't remember specifics but it's the redirect_canonical() function in wp-includes/canonical.php that was causing me a similar problem.

share|improve this answer

Your Answer

 
discard

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.