2

We have a section on the site, such as:

www.example.com/for-sale/category-name/

for-sale is a WP page, however category-name is dynamic and is what I wrote the below rewrite rule for.

add_rewrite_rule('for-sale\/([a-z-]+)\/?$', 'index.php?pagename=for-sale&search_slug=$matches[1]', 'top');

However, problems arise when the user needs to use the page query var, if I try going to:

www.example.com/for-sale/category-name/?page=2

it get's rewritten to:

www.example.com/for-sale/2/

So completely strips out the category slug.

Is there a way I can get this to work?

...or preferably I would like to be able to use something like this:

www.example.com/for-sale/category-name/2/

So I tried adding this additional rewrite rule:

add_rewrite_rule('for-sale\/([a-z-]+)\/([0-9])+\/?$', 'index.php?pagename=for-sale&search_slug=$matches[1]&page=$matches[2]', 'top');

..but again, it redirected back to:

www.example.com/for-sale/2/

What am I missing here?

1 Answer 1

4

Your rewrite rules are good, but the redirect happens because WordPress applies canonical redirect via its redirect_canonical() function which is hooked to template_redirect.

And you can cancel the redirect via the parse_request action, like so, where we check if the matched rewrite rule is the one you set when you call add_rewrite_rule() and if it is, then cancel the redirect by "unhooking" redirect_canonical() from the template_redirect action:

add_action( 'parse_request', function( $wp ){
    if ( 'for-sale\/([a-z-]+)\/([0-9])+\/?$' === $wp->matched_rule ) {
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
} );
6
  • Thanks for that. But wouldn't that then allow these pages to be accessed with and without www for example?
    – Brett
    Commented Mar 30, 2019 at 14:03
  • Ah sorry, yes you're correct.. Please ignore my previous comment. :p I'll update the answer later.
    – Sally CJ
    Commented Mar 31, 2019 at 9:43
  • Actually.. no. I've confirmed that even if I do not cancel the (canonical) redirect, if I visit http://example.com/for-sale/foo/2/, I would end up at http://example.com/for-sale/2/. Similarly, if I visit http://www.example.com/for-sale/foo/2/, I would end up at http://www.example.com/for-sale/2/. So I think if you want to force redirect to www or non-www, you can check this - i.e. use a "real" htaccess rule or the cPanel method. And have you already tried the code in the answer?
    – Sally CJ
    Commented Mar 31, 2019 at 10:34
  • Hey Sally, the code worked well with regards to what I wanted it to do, but I was unable to test the www issue since I am only on local right now; but yes, if I didn't implement your code then I get the same results as you experienced.
    – Brett
    Commented Mar 31, 2019 at 11:34
  • So since the answer does help, would you mind upvoting it?.. As with the www issue, you can post a new question, if it actually happens on your/a production site. But I would be happy to help you with that, via this question.
    – Sally CJ
    Commented Apr 1, 2019 at 8:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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