htaccess change url parameter - regex

I have a WP site which uses a calendaring plugin - currently the url the calendar system creates to change the month view of the calendar is hitting a url which fails to advance the month view of the calendar... I have worked out what the correct url should be - but need a way of redirecting from the incorrect url to the correct one...
So...
The incorrect url is: /calendar/?date=2018-04
The correct url is /calendar/?tribe-bar-date=2018-04
So, I am basically looking for a way to redirect / rewrite the url so that "?date=2018-04" becomes "?tribe-bar-date=2018-04" bearing in mind the year-month after the "=" element in the parameter will change all the time. So need to change "?date" to become "?tribe-bar-date"...
I have had a go using the redirection WP plugin with a rule as below:
/calendar/?date=(.*)
/calendar/?tribe-bar-date=(.*)
but it doesn't work... not sure why... I thought it would but I don't know regex very well!
Any ideas?

Try:
RewriteCond %{QUERY_STRING} (?:^|&)date=(.*)$
RewriteRule ^calendar/(.*)$ /calendar/$1?tribe-bar-date=%1 [L,R]
This assumes that the "date" parameter will be the first in the query string, otherwise you can add an additional grouping in front to try to capture that as well. This is doing a 302 (not permanent) redirect, you can change that if you want by changing the R to R=301.
Make sure this rule is before any wordpress rules.

If you want to redirect externally only , do this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^date=(.+)$
RewriteRule ^calendar/$ /calendar/?tribe-bar-date=%1 [QSD,R=301,L,NE]
Or this :
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(/calendar/)\?date=(.+)\sHTTP.*$
RewriteRule ^ %1?tribe-bar-date=%2 [QSD,R=301,L,NE]
If it is externally for that target then internally to same path , do this :
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(/calendar/)\?date=(.+)\sHTTP.*$
RewriteRule ^ %1?tribe-bar-date=%2 [QSD,R=301,L,NE]
RewriteCond %{QUERY_STRING} ^tribe-bar-date=(.+)$
RewriteRule ^calendar/$ /calendar/?date=%1 [L,NE]
To prevent query string from being appended you should put ? at the end of RewriteRule substitution
In apache 2.4 and later you could discard query string by this flag [QSD] https://httpd.apache.org/docs/2.4/rewrite/flags.html

Related

.htaccess redirect with GET parameters and URL condition

I try to redirect to another domain and changing the URL structure (not keeping URI part) based on 2 conditions:
The original URL has "lang" parameter.
The original URI begins with "page".
It's Apache 2.2
This is working when only have the lang paramenter in the orginal URL:
RewriteCond %{QUERY_STRING} lang=en$
RewriteRule ^.*$ https://www.destination.com/en/? [R=301,L]
For example it redirects ok for:
http://www.origin.com/?lang=en
to:
http://www.destination.com/en/
But I also need to redirect something like:
http://www.origin.com/page/5/?lang=en
to:
http://www.destination.com/en/
I'm trying things like this, but doesn't work, I think there's something wrong in the RewriteRule pattern:
RewriteCond %{QUERY_STRING} ^lang=en$
RewriteRule ^/page/.*/?$ https://www.destination.com/en/? [R=301,L]
Welcome!
You may not want to do have a ? at the end of your RewriteRule. However, if you wish to have you can do so. Maybe, you want to have a RewriteRule similar to:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} lang=en$
RewriteRule (.*)(\?lang=en) https://www.destination.com/en/ [R=301,L]
</IfModule>
You might want to restart your apache, with a command similar to:
sudo apachectl restart
You might clear your browser cache every time that you make a change on .htaccess file
Graph
This graph shows how your expression works, if you wish to know:
This tool can help you to simply design any rule that you like to have.
I have assumed that you want to redirect all your ?lang=en containing ULRs to a single URL. I was not sure about that. If that's not the case, you may not use my expression.

Apache redirect only part of a query

I'm trying to redirect a query string to a non query url. It looks something like this.
Original
http://searchtest.help.org/search?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=stackoverflow
Expected result
https://searchtest.help.org/cool-search/stackoverflow
I only want to grab the last part of the query. In this case stackoverflow.
This part will always be static.
search?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=
I'm using this in my apache vhost
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/search$
RewriteCond %{QUERY_STRING} ^client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=(.*)
RewriteRule ^(.*)$ https://searchtest.help.org/cool-search/%1 [R=301,L]
However the results with that is
https://searchtest.help.org/cool-search/stackoverflow?client=Cool_Sub&site=Cool_Sub&proxystylesheet=Cool_Sub&q=stackoverflow
I've tried many variations of the above rule but no dice. Any assistance would be grateful.
Add QSD flag to your RewriteRule
RewriteRule ^(.*)$ https://searchtest.help.org/cool-search/%1 [R=301,QSD,L]
According to Apache 2.4 documentation:
When the requested URI contains a query string, and the target URI
does not, the default behavior of RewriteRule is to copy that query
string to the target URI. Using the [QSD] flag causes the query string
to be discarded.

rewritecond with query string works, but when i submit a new query from the clean url, it just appends the url with the old query string

Here is are my rewrite rules and conditions
#link ReWrite
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]
#query Rewrite
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{REQUEST_URI} ^/searchresults.php [NC]
RewriteCond %{QUERY_STRING} ^.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule . /searchresults/%1/%2/%3/%4/%5? [R=301,L]
Situation -
i have a search page that searches the database and shows results. This setup catches the Query and rewrites it to clean urls (awesome!) BUT if i run a query a second time, aka from the cleaned url, the search request now just adds the original ?key=value&key=value to the clean url to make the request.
searchresults.php?make=value&model=value turns into searchresults/value/value as i want it to
but when i run the second query from searchresults/value/value it ends up turning it into
/searchresults/value/value?make=value&model=value
any way to defeat that from within .htaccess as the search query itself is in some deep php crazy land of code, and i honestly cant even find the thing, so editing the php is not in the cards.
ALSO, as a bonus, if anyone can tell me what edits to make so that when the query sends a request that looks like key=value+with+spaces i get the correct clean url back? right now it takes key=value+with+spaces and gives me back "value" but drops off with+spaces and moves onto the next key value pair....
THANKS
Not sure why you're having the problem, your rules worked perfectly fine for me on a vanilla apache install in a blank htaccess file. But you can try changing your rules a little:
The first thing you need to do is swap the order of your two rules. The redirect rule must be before any internal rewrites. This prevents two rules from being applied to the same request (the rewrite engine loops through all the rules until the URI stops changing). Second, you need to match against the actual request instead of the %{QUERY_STRING} match against the %{THE_REQUEST} variable:
RewriteCond %{THE_REQUEST} \ /+searchresults\.php\?.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule ^ /searchresults/%1/%2/%3/%4/%5? [R=301,L]
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]

htaccess rewrite from url query

I need some help trying to redirect a query to a url.
www.example.com/?categoryID=79
needs to redirect to
www.example.com/catname
where catname is just a string, it has no variables.
Here's what I tried so far:
I began with a humble approach that failed horribly:
redirect 301 /?CategoryID=79 http://www.example.com/catname/
then i moved on to mod_rewrite :
RewriteCond %{QUERY_STRING} CategoryID=79$
RewriteRule (.*) /catname/? [R=301,L]
Both did not work and I'm actually stomped.
any help would be appreciated.
Just to be clear, In the end i'll have many of these rules redirecting to various category names.
important - it's not enough for /catname to display the proper page, the request with the query parameter must redirect to the new url.
This rule should work for you as first rule in your .htaccess:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+\?CategoryID=79[&\s] [NC]
RewriteRule ^ /catname/? [R=302,L]

htaccess 301 redirect - Remove query string (QSA)

I've been struggling with some htaccess redirects. I just spent some time reading and searching on stack and couldn't get an anwser that works with my scenario.
I'm in the process of making the 301 redirect for an old client website to a new one. The old pages has parameters query which I want to remove from the url.
/menu.php?idCategorie=29&idDetail=172
to
/new-website-page/
I have multiple queries to do, here's a couple example:
/menu.php?idCategorie=29&idDetail=172
/menu.php?idCategorie=29&idDetail=182
/menu.php?idCategorie=29&idDetail=184
/menu.php?idCategorie=29&idDetail=256
Which all link to different new pages.
Here's what I tried:
RewriteCond %{QUERY_STRING} idDetail=172
RewriteRule ^menu.php(.*) /new-page/? [R=301,L]
I get redirected correctly, but the URL keeps the query string:
http://website.com/new-page/?idCategorie=29&idDetail=172
I also tried this:
RewriteRule ^menu.php?idCategorie=29&idDetail=172$ http://website.com/new-page/? [L,R=301]
And this:
RewriteCond %{QUERY_STRING} idDetail=172(.*)$
RewriteRule ^menu.php /new-page-name?$1 [L,R=301]
And it didn't work (Still have the query string at the end)
Thanks!
You can use this rule:
RewriteRule ^menu\.php$ /new-page-name? [L,R=301]
Take note of trailing ? in the end which is used for stripping off any existing query string in the original URI.
In addition to anubhava's answer you can alternatively use the QSD flag from Apache 2.4.0
RewriteRule ^menu\.php$ /new-page-name [L,R=301,QSD]
http://httpd.apache.org/docs/current/en/rewrite/flags.html#flag_qsd