I want to redirect each link with a query string to a specific address by appending the string. I have the following in my WordPress .htaccess
:
RewriteEngine On
RewriteCond %{QUERY_STRING} catid=([0-9] ) [NC]
RewriteRule (.*) catid%1? [R=301,L]
When a user hits example.com/?catid=10
, they are successfully redirected to example.com/catid10
, which is what I want.
However, when they go a directory deeper (example.com/category/?catid=10
), they are not redirected to example.com/category/catid10
.
I have been reading manuals but can't find the answer.
CodePudding user response:
You just need to add the captured group from (.*)
to your redirect target using $1
. I'd break it up into a few rules so that you don't get duplicated slashes. Rather then ending your rewrite targets with a question mark, I would add the QSD
(query string discard) flag to the rule. I would also add starts with (^
) and ends with ($
) to rewrite rule so you always match the whole thing. I also like to start my rules with an optional slash (/?
) so that the rules can be used in both .htaccess and apache conf.
RewriteEngine On
# Home URL with catid query string
RewriteCond %{QUERY_STRING} catid=([0-9] ) [NC]
RewriteRule ^/?$ /catid%1 [R=301,L,QSD]
# Deep URL ending in slash with a catid query string
RewriteCond %{QUERY_STRING} catid=([0-9] ) [NC]
RewriteRule ^/?(.*)/$ /$1/catid%1 [R=301,L,QSD]
# Deep URL not ending in slash with a cadid query string
RewriteCond %{QUERY_STRING} catid=([0-9] ) [NC]
RewriteRule ^/?(.*)$ /$1/catid%1 [R=301,L,QSD]
CodePudding user response:
Providing RewriteBase /
is already defined (which it normally is with WordPress and must be if your existing redirect is working) then you can do it like the following with a single rule:
RewriteCond %{QUERY_STRING} (?:^|&)catid=(\d ) [NC]
RewriteRule (.*?)/?$ $1/catid%1 [QSD,R=301,L]
The capturing group (.*?)
is non-greedy so does not consume the optional trailing slash that follows.
Requests for the document root do not require RewriteBase
, but all "deeper" URLs do, since the resulting substitution string will otherwise be a relative URL.
The non-capturing (?:^|&)
prefix on the CondPattern ensures that it only matches the URL parameter name catid
and not foocatid
etc.