I've got urls like this one:
my-party/viewparty/243-party-in-berlin-2013.html
where the variable part of the url is:
243-party-in-berlin-2013.html
I neet to get a url like:
events/party-in-berlin-2013.html
how can I do it with the apache rewrite rule? I've managed to remove the "my-party/viewparty" but I can't remove the portion of variable link.
Thank you very much
Alessandro
The following will map any URI in the format:
my-party/viewparty/<digits>-<rest-of-file-name>.html
to
/events/<rest-of-file-name>.html
RewriteEngine On
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-([^\.]*\.html)$
RewriteRule .* /events/%1 [L]
The way it works, is that it captures (what's inside the parentheses) the last part (denoted by the dollar-sign) of the request uri, that ends with .html and is preceded by my-party/viewparty/\d+-, where \d+ denotes a string of digits, with a minimum length of one digit. It then appends this captured pattern (denoted by %1) to /events/ in the RewriteRule.
If you want to redirect (301 Moved Permanently) to the new URI, use:
RewriteEngine On
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-([^\.]*\.html)$
RewriteRule .* /events/%1 [R=301,L]
And, if the party-in-berlin-2013 part is not variable, then you could can simply replace the RewriteCond with this:
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-(party-in-berlin-2013\.html)$
Related
RewriteEngine on
RewriteRule ^(.*)$ http://www.NEWfoobar.com/$1 [R=301,L]
I have this line of code from https://stackoverflow.com/a/7578810, inside .htaccess and it currently works by migrating www.OLDfoobar.com to www.NEWfoobar.com and all its sub-directory structure just fine (intended behavior, all good)
now, how do I add additional rule that captures www.OLDfoobar.com to redirect to one specific page in www.NEWfoobar.com? say for example `www.NEWfoobar.com/welcomeToNewDomain
The [L] flag is what gets me. and btw, I'm not so sure about what the $1 is for. That can't be a regex flag for the RewriteRule pattern, yes?
ACCEPTED ANSWER
RewriteEngine on
RewriteRule ^/?$ http://www.NEWfoobar.com/some/sub/directory [R=301,L]
RewriteRule ^(.*)$ http://www.NEWfoobar.com/$1 [R=301,L]
You need
RewriteEngine on
RewriteRule ^(.*)$ http://www.NEWfoobar.com/welcomeToNewDomain [R=301,L]
The $1 meant use the first capture group which is the value between the brackets on the left.
The L in the options means stop processing the rewrite rules (ie this is the Last Rule) if the match applies.
The ^(.*)$ means:
`^` match beginning of string
`(.*)` match zero or more characters and store in capture group 1
`$` match end of string
If I've miss understood an you only want to redirect the root requests while keeping the old capture you need to add a new rule before the existing one that reads
RewriteRule ^/?$ https://www.NEWfoobar.com/welcomeToNewDomain [R=301,L]
This will match either an empty path or just /
I have the a rewrite rule where I am trying to remove any dots and parentheses from the URL and I managed to get get to the point where I can do one or the other but just can't seem to combine both. How would I write the rule so that if any url has a dot or parentheses, they get removed? Thanks.
RewriteEngine On
RewriteCond %{REQUEST_URI} [\(\)\.]+
RewriteRule ^(.*)[\(]+([^\)]*)[\)]+(.*)$ /$1$2$3 [L,R=301]
Try:
RewriteRule ^(.*)[().](.*)$ /$1$2 [E=DOT:Y,DPI]
RewriteCond %{ENV:DOT} Y
RewriteRule ^([^().]+)$ /$1 [L,R=301]
This uses an environment variable as a way to know when to redirect. Any number of parentheses and dots will get removed and when they're all done, the URL gets redirected.
I'm trying to rewrite some urls but my newbness is getting in the way.
URLs input into the address bar
example.com/prefix-suffix.html
example.com/prefix-suffix.html?v=huzzah
Desired output (would like them displayed like)
example.com/prefix/suffix/
example.com/prefix/suffix/huzzah
I've looked at a few other examples like this one, but I just don't understand what they are doing exactly or how rather, which makes it challenging to modify.
If you have the time to explain what each line is doing I would greatly appreciate it.
Thanks.
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/+([^-]+)-([^.]+)\.html\s [NC]
RewriteRule ^ /%1/%2/ [R=302,L,NE]
RewriteCond %{THE_REQUEST} \s/+([^-]+)-([^.]+)\.html\?v=([^\s&]+) [NC]
RewriteRule ^ /%1/%2/%3? [R=302,L,NE]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /$1-$2.html [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /$1-$2.html?v=$3 [L,QSA]
this is a good reference. to summarize the relevant parts:
in the SO question you are referring to, the OP wanted index.php?page=mobile to become index/page/mobile
and the accepted answer to that question was:
RewriteEngine on
RewriteBase /cashearn/
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+) [NC]
RewriteRule ^ index/page/%1? [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^index/page/([^/]+)/?$ index.php?page=$1 [L,QSA,NC]
in order to understand how that is working, let's take a close look at this section:
RewriteCond %{THE_REQUEST} /index\.php\?page=([^\s&]+) [NC]
RewriteRule ^ index/page/%1? [R=302,L]
RewriteCond is a condition that must be matched in order for the subsequent RewriteRule to be used.
the pattern-matching is done using regex. the basics are easy to master so i recommend that you look it up. in any case, anything of the form %N (e.g. %1) is a backreference to the "grouped" part of the pattern of the last RewriteCond in the current set of conditions. A "grouped" part is denoted by parentheses. In other words, the %1 in the RewriteRule refers to the ([^\s&]+) in the RewriteCond.
looking at the regex:
square brackets in regex denote a character class so [^\s&] is thus a character class.
the caret ^ when it is inside a character class denotes negation. \s is an escape code for the whitespace character. so, all in all, [^\s&] means "any character except whitespace and &". the character class is appended with + which means "one or more". so, the regex pattern will match one of characters that are included in the character class. for a url, this essentially means any combination of letters, digits and %.
the other characters in the RewriteRule and RewriteCond, other than the "server-variable" %{THE_REQUEST}, are either regex special characters or literals. (by literals i mean that ab in a regex will match the string cab.)
^, the caret, when it isn't inside a character class, is a special character that denotes the beginning of a line. note that ? and . are also literals here, despite the fact that they are included in the list of regex "special characters". that is because they are escaped with a \.
the only thing left to explain is the flags [NC] and [R=302,L]
NC means case-insensitive. L means last, i.e. if there is a match, then subsequent rules will not be processed. 'R' means "redirect" and 302 is the redirect's HTTP status code.
the difference between an internal and external redirect is relevant here. with an internal redirect, the server will silently grab the resources from the filepath specified at the newly formed URL, while the user still sees the original URL in the browser. the R flag indicates an external redirect and this causes the user to initiate a new HTTP transaction with the newly formed URL. Omit R for an internal redirect.
My .htaccess is running with the Zend framework and one of our developers previously added this code:
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)/index.php$ http://www.mydomain.com/$1 [R=301,L]
Can someone please translate this to English for me? I believe it is saying, if someone tries to access index.php, then do a 301 redirect to the main domain (i.e. don't show the world "index.php" exists). I don't know why the RewriteCond is there when the RewriteRule has the same rule it seems, perhaps this was a mistake. Anyway I don't know if it even works as there are other rules and my site can actually access the index.php file (no redirection) so perhaps the above can be removed entirely. Looking for a proper translation of this to understand.
Many thanks!
Actually both RewriteCond and RewriteRule are required here. But first thing first this rule isn't going to work way it is.
Correct working code will be this:
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ /$1 [L,R=301,NC,NE]
Main difference is presence of / in your RewriteRule which will fail it for http://domain.com/index.php
Explanation:
THE_REQUEST variable represents original request received by Apache from your browser
You need to match URI with THE_REQUEST to make sure /index.php is there in the original URI and not a result of some internal rewrite to /index.php
If you remove RewriteCond it might still work but you have to make sure that none of rules are rewriting your URI to /index.php anywhere.
The RewriteCond test string contains the server-variable %{THE_REQUEST} which takes the form:
GET /index.php HTTP/1.1
or
POST /login.php HTTP/1.1
The condition pattern ^.*/index.php contains a regular expression that matches anything with /index.php in it...
The ^ marks the start of the string, the .* matches zero-or-more instances of any character and the /index.php is self-explanatory.
So, any URL which contains /index.php will be matched. If the condition pattern ended with a $ symbol (the end-of-string symbol), then it wouldn't match any instance of %{THE_REQUEST} as all instances of %{THE_REQUEST} contain the HTTP request type after the URL.
The RewriteRule is then used to do the 301 redirect as you describe, but importantly, the RewriteRule directive matches it's pattern against the current URL (and not against the whole request string like the RewriteCond does in this example).
The RewriteRule pattern ^(.*)/index.php captures (denoted by the brackets) everything in front of /index.php and then creates a 301 redirect that removes the /index.php.
#anubhava has pointed out that if you visit website.com/index.php then the RewriteRule won't work, because the URL it matches against does not include the leading /.
Those two lines can be rewritten as:
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301,L,NC]
Then, if you visit http://website.com/index.php then the (.*) part of the pattern will match an empty string.
Or if you visit http://website.com/sub/folder/index.php then the (.*) part of the pattern will match sub/folder/, which is then referenced in the substitution string by $1.
Remember that every redirect works by telling the browser to request a new URL, and each request gets re-processed by the htaccess, so if there are other rules that allow viewing index.php then that could explain why you can see some URLs containing index.php.
What is the .htaccess code for the following URL rewrite:
www.example.com/dir/file.php
into
www.example.com/file.php?newparam=dir
and
www.example.com/dir/file.php?param1=val1¶m2=val2
into
www.example.com/file.php?newparam=dir¶m=val1¶m2=val2
Thanks in advance.
Try the following, let me know if it works:
RewriteEngine on
RewriteBase /
# Allow files that exist to bypass rewrites
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite remaining files
RewriteRule ^/([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+\.php)$ /$2?newparam=$1 [L,QSA]
This only allows dir and file.php containing alphanumeric characters, underscore and dash.
The final rule looks for a URI matching two path components, between the forward slashes. The first must be 1 or more characters in the given set [-a-zA-Z0-9_]+, the second must be the same, but ending in .php. The ^ and $ characters match the front and back of the URI. The replacement says put the second bracketed group (the file.php part) at the front, and put the first bracketed group (the dir part) as a parameter called newparam. The [L,QSA] at the end says that this is the Last [L] rule if it matches, so stop matching further and perform the redirect and the [QSA] means "Query String Append", which adds the original query string to the end again, leaving that off would remove the original query string.