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?
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 enterinsurance-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.
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.
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:
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.I faced similar issue multiple times and in my case, the redirect was caused by
redirect_canonical()
function placed inwp-includes/canonical.php
. This function tries to redirect to base (canonical) URL for given request and it considers your URL/insurance-leads-types/auto-insurance-leads/STATENAME/
leading to same page as/insurance-leads-types/auto-insurance-leads/
so it redirects it.Quickest fix is to disable canonical redirect when your specific query var is used – like this:
Of course you can play with this filter and add different conditions. I also recommend to check
redirect_canonical
function code to see how exactlty it works.