301 Redirecting Multiple Pages - .htaccess

My rewrite rule almost works but there are still some problems. Here is the code:
RewriteEngine on
RewriteRule ^tag/(.*)$ /?s=$1&search=GA [L,R=301]
The first problem now is that the redirect links to:
mydomain.com/?s=tag/&search=GA
How can I get rid of the second slash?
Now the second problem... when a tag contains more than 1 word (for example the tag marketing tips) the redirect is:
mydomain.com/?s=marketing-tips/&search=GA
How do I convert that - symbol to a + symbol?

Try this:
# getting rid of trailing slash:
RewriteRule ^tag/(.*?)/?$ /?s=$1&search=GA [L]
# change "-" with "+":
RewriteCond %{QUERY_STRING} ^s=([^&]+)-([^&]+)&(.*)
RewriteRule ^(.*)$ /$1?s=%1+%2&%3 [L,NE]
# if there's no more "-", redirect:
RewriteCond %{QUERY_STRING} ^s=([^&-]+)(&|$)
RewriteRule ^(.*)$ /$1 [L,R=301]
When I go to a URL like mydomain.com/tag/some-thing-else-lots-of-dashes/, I get redirected to mydomain.com/s=some+thing+else+lots+of+dashes&search=GA

It looks like your regex is picking up the slash from the incoming URL in it's collection, try moving it out and making it optional, also I made your selector less greedy:
RewriteRule ^tag/(.*?)/?$ /?s=$1&search=GA [L,R=301]

Related

.htaccess rewrite and redirect two types of urls

I'm trying to create clean URL with .htacces rewrite. I have two types of urls:
site.com/page.php?page=something
site.com/something.php
I need them both to be just site.com/something, with redirect from ugly to pretty url. So now I have the following rules, which don't work together, and I totally stuck with the redirect.
Options -Multiviews
RewriteEngine On
RewriteBase /
# page.php?page=about to about
RewriteRule ^([^/.]+)?$ /page.php?page=$1 [NC,L]
# something.php to something
RewriteRule ^([^/.]+)?$ $1.php [NC,L]
Will appreciate any help. Thanks in advance.
There are a few things that are incorrect in your example:
You cannot inspect the query string in a RewriteRule, only in a RewriteCond
Your RewriteRule lines are backwards - the first part is a regular expression match of the URL and the second is what you want it to be.
You will need to have an [R] rule as part of the rewrite to perform a redirect, otherwise it will just "rewrite" the URL the server sees and not change the actual URL.
Here is an example of your first rewrite, redirecting /page.php?page=foo to /foo. You first need a RewriteCond to inspect the %{QUERY_STRING} variable to see if it has page=... in it. We can use the character match ([^&]*) to grab all of the characters that are not an ampersand and store in a matching group. Next we perform a RewriteRule for page.php (note that we don't need the leading / because of the RewriteBase and that the . is escaped). If there is a match here, you want to redirect to the matching group from the RewriteCond - it is referred to with a %1 rather than a $1 like it would if it were from the RewriteRule. You will also want to append a ? to the end of your redirect which tells Apache to drop the query string so you don't end up with /foo?page=foo. Finally you will need [R=301] to perform a redirect with an HTTP status code of 301. The [L] indicates that that this is the Last rule you want to process if there is a match.
RewriteEngine On
RewriteBase /
# page.php?page=about to about
RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
RewriteRule page\.php /%1? [R=301,L]
Your second rewrite is closer, but as in the first the logic is backwards. You want the first part to match *.php and then the second to indicate the redirect to /$1. Again you will need the [R-301] for the redirect.
# something.php to something
RewriteRule (.*)\.php$ $1 [R=301,L]
You can test this out on http://htaccess.madewithlove.be/.
Using http://example.com/page.php?page=foo, redirects to http://example.com/foo
1 RewriteEngine On
2 RewriteBase /
3 # page.php?page=about to about
4 RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
This condition was met
5 RewriteRule page\.php /%1? [R=301,L]
This rule was met, the new url is http://example.com/foo
Test are stopped, because of the R in your RewriteRule options.
A redirect will be made with status code 301
Using http://example.com/foo.php redirect to http://example.com/foo
1 RewriteEngine On
2 RewriteBase /
3 # page.php?page=about to about
4 RewriteCond %{QUERY_STRING} page=([^&]*) [NC]
This condition was not met
5 RewriteRule page\.php /%1? [R=301,L]
This rule was not met because one of the conditions was not met
6 # something.php to something
7 RewriteRule (.*)\.php$ /$1 [R=301,L]
This rule was met, the new url is http://example.com/foo
Test are stopped, because of the R in your RewriteRule options.
A redirect will be made with status code 301

RewriteRule Not Working using RewriteCond

I am trying to get this
http://my.url.com/login/ or
to redirect to:
http://my.url.com/app/index.cfm?event=user.login
I am using this rewrite rule and it isn't working.
RewriteCond %{REQUEST_URI} ^/login/$
RewriteRule ^/app/index.cfm?event=user.login [NC,L]
What am I doing wrong?
Thanks
The first argument of a RewriteRule is the pattern which matches against the URI, and you're missing that pattern. Try:
RewriteRule ^/?login/$ /app/index.cfm?event=user.login [NC,L]
If you want to externally redirect the browser, include a R or R=301 (permanent) flag in the square brackets, e.g. [NC,L,R=301].

(htaccess) Rewrite English names of php files to their Dutch equivalents

I would like to rewrite the English names of php files to their Dutch equivalents.
For example: someurl.com/news.php?readmore=4#comments should become someurl.com/nieuws.php?leesmeer=4#kommentaar. The code from news.php should be executed but nieuws.php should be in the url the arguments should function as well.
I tried several htaccess examples but I can't get it to work.
Any help would be appreciated.
Edit: Working progress from answers below and final solution.
RewriteCond %{QUERY_STRING} ^readmore=(.*)$
RewriteRule ^news.php$ nieuws.php?leesmeer=%1 [R=301,L]
RewriteCond %{QUERY_STRING} !^norewrite[\w\W]*$
RewriteRule ^news.php$ nieuws.php [R=301,L]
RewriteRule ^nieuws.php$ news.php?norewrite [QSA]
RewriteCond %{QUERY_STRING} !^norewrite[\w\W]*$
RewriteRule ^search.php$ zoeken.php [R=301,L]
RewriteRule ^zoeken.php$ search.php?norewrite [QSA]
# make sure rewrite is activ
RewriteEngine On
# Rewrite a request for nieuws.php to news.php
RewriteRule ^nieuws.php$ news.php
Should do the trick.
Instad you could send all requests to an index.php and parse them there:
## Redirect everything to http://hostname/?path=requested/path
RewriteEngine On
RewriteRule ^([\w\W]*)$ index.php?path=$1 [QSA]
[QSA] makes sure you get the original get arguments too.
Now you have to parse the request in $_GET['path'] in you index.php and include the requested page.
eg:
if ($_GET['path'] == 'nieuws.php') {
include 'news.php';
} else if (empty($_GET['path'])) {
echo "HOME";
}
if you want to make make the user always sees nieuws.php in its address bar, even if he requested news.php, you could try the following:
RewriteEngine On
# Redirect news.php to nieuws.php if and only if the request comes from the client
# (suppose the client didn't set ?norewrite.)
RewriteCond %{QUERY_STRING} !^norewrite[\w\W]*$
RewriteRule ^news.php$ nieuws.php [R=301,L]
# Send news.php if nieuws.php was requested and prevent news.php from being redirected
# to back to nieuws.php by the rule above.
RewriteRule ^nieuws.php$ news.php?norewrite [L,QSA]
(R=301 means send a "moved permanently" redirect to the client, L means stop rewriting after this rule matched)
The hole thing with norewrite (you could use something else instead) is only needed to avoid an endles loop of rewriting between news and nieuws.
To translate the GET arguments, you can try the following code before the first line of the above code:
RewriteCond %{QUERY_STRING} ^readmore=(.*)$
RewriteRule ^news.php$ nieuws.php?lesseer=%1 [R=301,L]
Things after a the # in an url can't be changed in .htaccess, since they aren't send to the server at all. The only chance to change them is using JavaScript. (See lots of question here on manipulating them within JavaScript)
Try:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /news\.php
RewriteRule ^ /nieuws.php [L,R=301,QSA]
RewriteRule ^nieuws\.php$ /news.php [L,QSA]

SEO Url for Profiles

Preface
I'm trying to re-write a URL for a profile page. All of my application pages have a .html extension, so I'm trying to match just letters, numbers, -, and ..
So these would be valid
site.com/steve
site.com/steve-robbins
site.com/steve.robbins
But these wouldn't be
site.com/steve.html
site.com/steve-robbins.php
Assume I have a check in place so that custom URLs don't have .html or .php on the end.
Problem
I'm currently using this but it's not working
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
It should set url to steve, but it's setting it to profile.php
What am I doing wrong?
My complete .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*) http://www.%{HTTP_HOST}/$1 [R=301]
#
# LOGIN
#
RewriteRule ^([a-z0-9]{255})/activate\.html$ login.php?activate=$1 [L]
RewriteRule ^logout\.html$ login.php?logout [L]
#
# SETTINGS
#
RewriteRule ^change-([a-z]+)\.html$ account-settings.php?$1 [L]
RewriteRule ^([a-zA-Z0-9\.-]+)$ profile.php?url=$1 [L]
# SEO friendly URLs
RewriteRule ^([a-zA-Z0-9-_.]+)\.html$ $1.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([a-zA-Z0-9-_.]+)\.php
RewriteRule ^([a-zA-Z0-9-_.]+)\.php$ $1.html [R=301]
Add this to the top of your rules (under the RewriteBase / directive):
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
That should stop it from looping. The rewrite engine will keep re-applying all the rules until the URI going in (sans query string) is the same as the URI that comes out of the rules. That's why the value of url is profile.php.
I'm kind of a beginner in interpreting mod_rewrite rules but if I understand it correctly your rule is matched and than matched again, either add something to the url matching scheme like /profile/user or add a condition to not redirect if already redirected
Try adding a leading slash to the redirect like this:
RewriteRule ^([a-zA-Z0-9.-]+)$ /profile.php?url=$1 [L]
The reason you're getting a url value of profile.php is because the [L] flag is kinda misleading when it comes to the .htaccess file. In the server config files it does exactly what you'd think, but in the .htaccess file it stops reading rules at that rule, but then goes through the rules again until path is unchanged by any of the rules. By adding the leading /, your rule will not match the second time around as you exclude / from the regex. I spent a while struggling with this feature myself.

htaccess - rewrite rule to get end of url

I have a url which ends with a certain variable string, and was erroneously generated and indexed unfortunately.
Example:
http://domain.com/anything-in-between/?var=xyz-abc-abc-abc
How can I redirect to main site (kill it), by detecting 'abc-abc-abc' using htaccess?
Why wouldn't this work and what would be the best solution:
RewriteCond %{REQUEST_URI} abc-abc-abc
RewriteRule .* index.php
You want to use the query string as claesv suggests but you need to then kill the query string
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} \bvar=.*?abc-abc-abc$
RewriteRule ^ index.php? [L]
This will do it silently (i.e. in the server as an internal redirect and not involving the browser). You can't use 301s reliably to trim query strings.
Something along the lines of:
RewriteCond %{QUERY_STRING} ^var=.*abc-abc-abc$
RewriteRule ^.*$ http://domain.com/ [R=301,L]

Resources