How to rewrite correctly url htaccess - .htaccess

I would know how to rewrite a multilanguae website the url ?
When the rewrite configuration is not applied I have this url
boutique/index.php (default language en)
boutique/index.php?language=fr
boutique/index.php?Products&Description&products_id=20
When the rewrite configuration is applied I have this url
boutique/index.php (default language en)
boutique/index.php/language,en
boutique/index.php/language,fr
boutique/index.php/Products/Description/products_id,20
I tried this but not work.
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^([^/]+)/([^.]+)\.php /$2.php/language=$1 [L,NC,QSA]

Related

Redirection Htaccess without a trailing slash

I would like to redirect all URL having a trailing slash referenced by google to the new url without a trailing slash.
Example :
http://example.com/toto/ ===> to http://example.com/toto
Warning I already rewrite the rule to avoid the .html extension also !
Here is my existing code :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteCond %{REQUEST_URI} (.+)$
RewriteRule ^ %1 [R=301,L]
</IfModule>
I got the following error :
Not Found
The requested URL /example/.html was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
The objectif of the topic was to find a solution to make a redirection of existing URL listed by search engine like google to not lose the current SEO after making a complete refresh of the web site (Wordpress to bootstrap).
The first objective was to redirect all url trafics like http://example.com/toto/ (google) ===> to http://example.com/toto.
Unfortunatly I understood that making the reverse is more powerful to not lose my existing listing on google (sitemap & robots)
So I have decided to review all the code in order to have the following result by deleting the html extension and adding a trailing slash at the end of each url :
http://example.com/toto.html ===> to http://example.com/toto ==> http://example.com/toto/
Below is the code HTaccess that I used to make this possible :
RewriteEngine On
RewriteBase /
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html [NC]
RewriteRule ^ %1/ [R,L]
# add a trailing slash at the end /dir/foo/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [L,R=301]
# delete the extension .html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*?)/?$ $1.html [L,QSA]
I have also added the code line below in each html page to enforce it :
<base href="http://example.com/">
Hoping to help any readers/coders in the same situation

How can I rewrite a 'subfolder' to a script?

I need to redirect a URL example.com/servers/1/ to a PHP script (example.com/serverinfo.php) that recieves the 1 part of the requested URL as a GET variable (or similar).
I currently have a rule RewriteRule ^([^/.]+)$ $1.php that rewrites URLs such as example.com/servers to example.com/[file].php, and tried to base the following rule off that:
RewriteRule ^/?servers/([0-9]+)$/ /serverinfo.php$
The new rule has no effect (other than causing the page's CSS to fail to load), what am I doing wrong?
You can use:
Options -MultiViews
RewriteEngine On
# handle /servers/123
RewriteRule ^/?servers/([0-9]+)/?$ /serverinfo.php?num=$1 [L,QSA,NC]
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

Hiding multiple dynamically-named subdirectories with mod_rewrite in .htaccess

I am having difficulty configuring a mod_rewrite rule in my .htaccess file to hide certain subdirectories.
Input:
https://example.com/hidden_sub1/hidden_sub2/additional_sub/file.php?lang=en-US
Desired output:
https://example.com/en-US/additional_sub/file
I had code that allowed me to hide something if I specifically name it:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^GET\ /hidden_sub1/hidden_sub2/ [NC]
RewriteRule ^hidden_sub1/hidden_sub2/(.*) /$1 [L,R=301]
RewriteRule !^hidden_sub1/hidden_sub2/ hidden_sub1/hidden_sub2%{REQUEST_URI} [L]
However, it stopped working once I added in the following language subdirectory code:
RewriteRule ^([a-z]{2}(-[A-Z]{2})?)/(.*) $3?lang=$1 [L,QSA]
Besides, the name of the subdirectory is dynamic. "hidden_sub1" might be "random_name243". However, they would always be the first two subdirectories.
So how do I take out the first two randomly-named subdirectories while still keeping the language subdirectory?
I appreciate any help.
To change your url from the form
https://example.com/hidden_sub1/hidden_sub2/additional_sub/file.php?lang=en-US
To the form :
https://example.com/en-US/additional_sub/file
You can use the following Rewrite rule
RewriteEngine On
RewriteBase /
#1)externally redirect "/hidden_sub1/hidden_sub2/foo.php?lang=bar" to "/bar/foo"
RewriteCond %{THE_REQUEST} /hidden_sub1/hidden_sub2/([^.]+)\.php\?lang=(.+)\sHTTP [NC]
RewriteRule ^ /%2/%1? [L,R=301]
#2)internally rewrite "/bar/foo" to "/hidden_sub1/hidden_sub2/foo.php?lang=bar"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ /hidden_sub1/hidden_sub2/$2.php?lang=$1 [NC,L]
Tested on apache 2.2. and 2.4.

Implementing "friendly" URLs using .htaccess

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]

htacces redirect for SEO friendly URLs

I have my htaccess file setup, so that the pages remove extensions. Now, I am trying to make the pages that transfer variables, into SEO friendly urls ... so, for example...
http://www.example.com/art-gallery?page=2 ... which is actually "art-gallery.php?page=2", would turn into... http://www.example.com/art-gallery/page/2
Or... http://www.example.com/art-piece?id=3 ...would go to... http://www.example.com/art-piece/id/3
... and so on ...
I have alot in my htaccess file, and am not sure how to do the above (there are plenty of tutorials on going from www.example.com/index.php?page=2 to www.example.com/page/2/ but none that do exactly what I need). Ideally, I'd like to be able to do this for all similar pages...
# enable the rewrite engine
RewriteEngine On
# Set your root directory
RewriteBase /
# Force www:
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]
# Remove the .php extension
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# Remove index and reference the directory
RewriteRule (.*)/index$ $1/ [R=301]
# Remove trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# Forward request to html file, **but don't redirect (bot friendly)**
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
# Disable Directory Browsing
Options -Indexes
# Disable Hotlinking of Images
# with forbidden or custom image option
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]
# Protect htaccess File
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>
You can transfer parameters with the variable QUERY_STRING.
Consider the following rule:
RewriteRule ^index.html index.php?%{QUERY_STRING}&m=main&a=index
This rule would transform
index.html?something=value
into
index.php?something=value&m=main&a=index
You should use the RewriteEngine.
You could also use a 301 redirect either alone or in conjunction with the RewriteEngine to redirect SEs.
Generally, though redirecting SEs to a different page than what users will see is not a good practice, and may result in your pagerank decreasing. Instead, try migrating all your pages to the second URL format, and consider using 301 redirects to help the transition.
Generally: Use 301 redirects for SE-friendly page changes. See this SO for additional reference.
You can insert this rule just before Forward request to html file rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/])/([^/])/([^/])/?$ $1.php?$2=$3 [L,QSA]
This is quite old but why not do the following:
RewriteEngine On
RewriteRule ^([^?]*) index.php?route=$1 [L,QSA]
Then in your index.php you can handle it like such;
if (isset($_GET['route'])) {
$route = explode('/', $_GET['route']);
if (iconv_strlen((end($parts)), 'UTF-8') == 0) {
array_pop($parts);
}
}
From here your main level would be handled with $route[0], second level $route[1]
For example;
http://example.com/art-gallery/2
$route[0] would equal 'art-gallery'
$route[1] would equal '2'

Resources