I am using the following in .htaccess to transform a language specified in the url to a query string:
RewriteEngine On
RewriteBase /
RewriteRule ^(en|fr)/(.*)$ $2?language=$1 [L,QSA]
It works as expected when I enter any of:
mydomain.com/en/
mydomain.com/en/about/
mydomain.com/en/about/index.php
But if I enter this:
mydomain.com/en/about
(no trailing slash), the browser redirects to
mydomain.com/en/about/?language=en
Which is the correct destination except that it should be an internal rewrite. I don't want to see this in the browser location bar.
What am I missing?
You'll need to turn off mod_dir and handle the trailing slashes internally. Maybe something like this:
DirectorySlash Off
RewriteEngine On
RewriteBase /
# handle post-rewrite trailing slashes
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/ [L,R]
# handle pre-rewrite trailing slashes
RewriteCond %{DOCUMENT_ROOT}/$2 -d
RewriteRule ^(en|fr)/(.*[^/])$ /$1/$2/ [L,R]
RewriteRule ^(en|fr)/(.*)$ $2?language=$1 [L,QSA]
This should take a request like mydomain.com/en/about and redirect it to mydomain.com/en/about/ before your last rule internally rewrites it.
Related
I'm new on .htaccess and rewrite rules.
So if my question is not relevant, please forgive me.
I have below htaccess code.
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
If i visit url like www.example.com/category/0 it works.
But if i strip page url and last slash www.exapmle.com/category i see an ugly 404 page.
What is wrong with my htaccess directive?
Thanks in advance.
EDIT: Compeletely .htaccess
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
## If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
## If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
## If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
## don't do anything
RewriteRule ^ - [L]
RewriteRule ^haber/([^/]+)-([^/]+)/?$ article.php?link=$1&i=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
This is a correct behaviour.
Actually, in a regular expression, a + means at least one.
When you use ([^/]+) it means at least one character which is not a slash.
Your rule ^([^/]+)/([^/]+)/?$ means at least one character which is not a slash / at least one character which is not a slash optional slash.
That's why it does not work with only the first part url.
If you also want to handle example.com/category you'll need another rule:
RewriteRule ^([^/]+)/?$ article-list.php?link=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L]
I wrote htaccess rewrite rule to get the content from another folder. For example: if the URL is http://test.com/folder2/folder3/ then the index file is loaded from the folder1/folder2/folder3 directory. All is working well in this case but if I omit the trailing slash in the URL i.e. if the URL is http://test.com/folder2/folder3 then the URL is redirected to http://test.com/folder1/folder2/folder3/. How do I load the content from folder1/folder2/folder3 without changing the URL?
The rewrite rule is:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(folder2/.*)$ folder1/$1 [L]
That is due to mod_dir module running after mod_dir and adding a trailing slah on rewritten URI. You can change your htaccess to this:
Options +FollowSymLinks
DirectoryIndex index.php
RewriteEngine on
RewriteBase /
# add trailing slash to directories
RewriteCond %{DOCUMENT_ROOT}/folder1/$1 -d
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=302,NE]
RewriteRule ^(folder2/.*)$ folder1/$1 [L,NC]
I found the solution to the problem by forcing trailing slash to every URLs. So, the .htaccess file is:
Options +FollowSymLinks
RewriteEngine on
# Force Trailing Slash
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule ^(folder2/.*)$ folder1/$1 [L]
I want to change alle dynamic url's to static ones,
but after rewriting the dynamic url's are still responding/available.
What did I do =>
I found this Tool for SEO:
http://www.webconfs.com/url-rewriting-tool.php
I entered this:
.../filmdetails.html?var=ich_einfach_unverbesserlich_ii
Then I put into my .htaccess this:
RewriteEngine On
Options +FollowSymLinks
RewriteRule ^filmdetails/(.*)/$ filmdetails.html?var=$1
Works, but now I got a problem: This URL is still available and should not be: .../filmdetails.html?var=ich_einfach_unverbesserlich_ii
How do I get rid of the dynamic url's?
Your rule only rewrites the nicer looking URL to the one with a query string. Rules only work from a "pattern" -> "target" way, the mapping won't magically work the other way. You'll have to create a separate rule in order to redirect the browser:
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /filmdetails\.html\?var=([^&\ ]+)&?([^\ ]*)
RewriteRule ^ /filmdetails/%2/?%3 [L,R=301]
Try:
Options +FollowSymLinks
RewriteEngine On
#set this to path to your filmdetails.html file (from the document root)
RewriteBase /
#checking if redirect already happened
RewriteCond %{ENV:REDIRECT_PASSED} !^$
RewriteRule $ - [L]
#Your rewrite rule
RewriteRule ^filmdetails/(.*)/$ filmdetails.html?var=$1 [L,E=PASSED:1]
#redirecting from filmdetails.html with query string ?var=something
RewriteCond %{QUERY_STRING} ^var=(.+)$ [NC]
RewriteRule ^filmdetails.html$ filmdetails/%1/? [R]
filmdetails.html?var=something will be redirected to filmdetails/something
I need to redirect the request from
www.mysite.com/?querystring=data
to
www.mysite.com/dir/phpfile.php/?querystring=data
It means that it should be translated only the url with empty request_uri ( for example
www.mysite.com/css/style.css
should not be translated), and with not empty query string ( for example the main page
www.mysite.com/
should not be translated).
I wrote this code
RewriteCond %{HTTP_HOST} ^www.mysite.com$ [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^/?(.*)$ www.mysite.com/$1 [QSA]
But it doesn't work. Any suggestion?
The rule that you have has the domain name in it without a protocol, it's going to look like a URI or file pathname to mod_rewrite. Additionally, you're rewriting it nothing, since $1 backreferences the grouping (.*) in your match, which must be nothing since your condition says the URI can only be /. You probably want something like:
RewriteCond %{HTTP_HOST} ^www.mysite.com$ [NC]
RewriteRule ^/?$ /dir/phpfile.php/ [L,R]
The query string will automatically get appended to the end. Remove the R if you don't want to externally redirect the browser (thus changing the URL in the location bar), or replace it with R=301 if you want a permanent redirect.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^(.+)$ [NC]
RewriteRule ^$ /dir/phpfile.php/ [L,QSA,R=302]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.
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.