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]
Related
I am making a mini blog that could make it's url looks like this:
From: http://127.0.0.1/index.php?post=the-story-of-us
To: http://127.0.0.1/view/the-story-of-us
I have tried this but i'm getting 404 not found.
RewriteEngine on
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /index\.php\?post=([^&]+)
RewriteRule ^ /view/%2/? [L,R=301]
Your current rule only handles the case: Redirect old url to new url.
(By the way, +1 for using THE_REQUEST to avoid a redirect loop)
You also need to handle the case: Rewrite (internally) new url to old url.
Here is how your htaccess should look like
RewriteEngine On
# Redirect /index.php?post=XXX to /view/XXX
RewriteCond %{THE_REQUEST} \s/index\.php\?post=([^&\s]+)\s [NC]
RewriteRule ^ /view/%1? [L,R=301]
# Internally rewrite back /view/XXX to /index.php?post=XXX
RewriteRule ^view/([^/]+)$ /index.php?post=$1 [L]
I do not udnerstand your RewriteCondition, but the RewriteRule should look like this:
RewriteEngine on
RewriteBase /
RewriteRule ^view/(.*)/? ./index.php?post=$1 [L,R=301]
I'm not sure if it is possible but I want rewrite old URLs to new style and if someone will access the old URL i want to 301 redirect him to new URL style
OLD URL: /catalogue/category/some-category-page
NEW URL: /some-category-page/category
Also what I need is to pass REQUEST_URI to PHP script
I've got something like this but its not working (recursion):
RewriteEngine On
RewriteRule ^catalogue/category/(.+)$ /$1/category [R=301,L] # this is bad I know
RewriteRule ^(.+)/category?$ /catalogue/category/$1 [P]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php?modrewrited=%{REQUEST_URI} [QSA,L]
Thank you for help.
If your PHP script needs to read from $_SERVER['REQUEST_URI'], the you need to make sure mod_proxy is loaded. Except that causes a redirect loop. You need to have your first rule which redirects check the actual request variable. So instead of:
RewriteRule ^catalogue/category/(.+)$ /$1/category [R=301,L] # this is bad I know
you want:
RewriteCond %{THE_REQUEST} \ /+catalogue/category/([^\ \?]+)
RewriteRule ^ /%1/category [L,R=301]
I tried some of the other answers I could find in here, but it didn't work out. It's really simple though.
I want
/page?id=PAGENAME
to be accessible AND redirected to
/PAGENAME
Can you help me?
EDIT:
It feels like my already messed-up .htaccess file needs to be included in here. I already have basic rewriting enabled, but this feature is needed for two other "special pages". In the requested solution above, I would therefore just replace "page" with the two pagenames (it's danish names, so I thought it was easier this way).
Currently I have this. If you have any improvements to it, it's appreciated - but I just want this to work with the requested solution aswell.
# Options -Multiviews -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
# Always on https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# remove trailing slash
#RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]
#301 Redirect everything .php to non php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+\.)+php?\ HTTP
RewriteRule (.+)\.php?$ http://MYURL.dk/$1 [R=301,L]
#Hide the .php from url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
#301 Redirect everything mistype after file extension -
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
#301 Redirect everything to current url -
RedirectMatch permanent /(.*).php/.* http://MYURL.dk/$1.php
RewriteCond %{REQUEST_FILENAME} -D
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L]
#301 Redirect from non www to www
RewriteCond %{HTTP_HOST} ^www.MYURL.dk [NC]
RewriteRule (.*) http://MYURL.dk/$1 [R=301,L]
#301 redirect index.php to /
RewriteBase /
RewriteCond %{REQUEST_URI} index.php
RewriteRule .* http://MYURL.dk/ [R=301,L]
#Deny access to songs
RewriteCond $1 !(loadmedia)\.php
RewriteRule ^songs/(.*)$ - [L,F]
Generally the URL in address bar should be like
www.siteurl.com/pagename/ for seo purpose and then read this url from .htaccess using rule which gives this query string parameter values in your php file.
.htaccess rule can be like
RewriteRule ^(.*)/$ /page?id=$1 [QSA,L]
It looks like you are wanting to implement "friendly" (or "pretty") URLs, making the URLs more friendly for you users (search engines don't really mind what your URLs look like).
The first step is to change all your on-page links to use the new "friendly" URL. So, you links should all be of the form /pagename (not /page?id=PAGENAME).
Then, in .htaccess, you need to internally rewrite this "friendly" URL into the real URL that your server understands. This can be done using mod_rewrite. In the .htaccess file in your document root:
# Enable the rewrite engine
Options +FollowSymLinks
RewriteEngine On
# Rewrite the "friendly" URL back to the real URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^id=
RewriteRule ^([\w-]*) /page?id=$1 [L]
If the file does not exist (!-f) and does not contain the id URL param then internally rewrite the request from /<pagename> to /page?id=<pagename>. This assumes your <pagename> consists only of the characters a-z, A-Z, 0-9, _ and -.
If this is a new site and the old URLs are not already indexed or referenced by external sites then you can stop here.
However, if you are changing an existing URL structure then you also need to externally redirect the real (ugly) URL to the "friendly" URL before the above internal rewrite. (This is actually what you are asking in your question.) In order to prevent a rewrite loop we can check against %{THE_REQUEST} (which does not change when the URL is rewritten).
# Redirect real URLs to "friendly" URLs
RewriteCond %{THE_REQUEST} \?id=([\w-]*)
RewriteRule ^page$ /%1? [R=302,L]
Change the 302 (temporary) to 301 (permanent) when you are sure this is working OK. Permanent redirects are cached by the browser so can make testing a problem.
So, in summary, with the above two parts shown together:
# Enable the rewrite engine
Options +FollowSymLinks
RewriteEngine On
# Redirect real URLs to "friendly" URLs
RewriteCond %{THE_REQUEST} \?id=([\w-]*)
RewriteRule ^page$ /%1? [R=302,L]
# Rewrite the "friendly" URL back to the real URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^id=
RewriteRule ([\w-]*) /page?id=$1 [L]
The order of directives is important. External redirects should nearly always come before internal rewrites.
UPDATE#1:
I want /concept?id=NAME to go to /NAME and /studio?id=NAME to go to /NAME - there's 5-10 different "pages" from both concept and studio. [Corrected according to later comment]
Since id=NAME maps to /NAME you can achieve all 10-20 redirects with just a single rule:
RewriteCond %{QUERY_STRING} ^id=(NAME|foo|bar|baz|abc|def|ghi)
RewriteRule ^(concept|studio)$ /%1? [R,L]
This will redirect a URL such as /studio?id=foo to /foo.
As with all external redirects this should be one of the first rules in your .htaccess file.
Change R to R=301 when you have tested that it is working OK.
To make this more "dynamic", ie. match any "NAME" then change the CondPattern, for example:
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
UPDATE#2:
If the path part of the URL (ie. concept or studio) is required then you can modify the RewriteRule substitution like so:
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
RewriteRule ^(concept|studio)$ /$1/%1? [R,L]
Which will redirect /concept?id=foo to /concept/foo.
Or, to be completely "dynamic" (bearing in mind this will now capture anything):
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
RewriteRule ^([\w-]+)$ /$1/%1? [R,L]
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.
This is my current .htaccess file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/
RewriteRule ^([^/]+)/$ index.php?p1=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4&p5=$5 [L]
Basically, it takes up to five "Friendly url folders" and assign the value to varibles and then, send those to my index.php page
IE: http://www.example.com/ford/focus/grey/
$p1 = 'ford';
$p2 = 'focus';
$p3 = 'grey';
$p3 = 'grey';
So far, so good.
Now, I need to integrate a 301 instruction (RegExp?) in that same .htaccess because initially, I had GET parameters like this :
IE: http://www.example.com/ford/focus/grey/?lang=fr
I need to get rid of all GET variables because Google sees it as duplicate content (even if I'm using the nofollow attribute on my languages links)
IE: http://i.want.to.keep/my/url/?AND_DUMP_GET_VARIABLES
http://www.example.com/ford/focus/grey/?lang=fr
http://www.example.com/ford/focus/grey/?lang=en
http://www.example.com/ford/focus/grey/?lang=sp
==> http://www.example.com/ford/focus/grey/
Logically, the instruction should be interpreted between the first and the second block but I just don't know where to start. Any hints?
THANKS!
As I understand you want to get rid of the QUERY STRING and redirect (301 Permanent Redirect) to the same URL but without QUERY STRING.
The rule below will redirect EVERY request that has query string:
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
1. The ? will do the magic -- will strip query string
2. You desperately need this line: RewriteCond %{ENV:REDIRECT_STATUS} ^$. The problem is that it may not work on your Apache setup and I cannot give you what exactly you need to make it work (it works fine on my vanilla Apache v2.2.17 on Windows).
After rewrite (internal redirect) occurred, it goes to next iteration and Apache starts matching all rules from the top again but for already rewritten URL. If we not add the above line, then mod_rewrite will apply the above rule to rewritten URL form and you will end up with all URLs get rewritten to /index.php with no parameters at all.
If the above will not work, then try the code below:
# do not do anything for already existing files and folders
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
With help of # do not do anything for already existing files and folders rule, mod_rewrite will stop rewriting after URL will be rewritten to /index.php?p1=... format.
In case the above will not work at all (better -- in addition to the above -- I would suggest adding this anyway) use <link rel="canonical" href="FULL_PROPER_RUL"/> in your page:
http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html
http://www.google.com/support/webmasters/bin/answer.py?answer=139394