Reputation: 115
I have a multilanguage website. I want the URL's to be like: http://example.com/en/blog_post/2
where blog_post
is the name of the file blog_post.php
and 2
is value of the parameter id.
I have this .htaccess code now
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/(.*)$ /$2?lang=$1 [L]
RewriteRule ^(bg|en)/(.*)/([^/.]+)$ /$2?lang=$1&id=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
I tried with this line, but it doesn't work:
RewriteRule ^(bg|en)/(.*)/([^/\.]+)$ /$2?lang=$1&id=$3 [L]
Can you help me please :)
Upvotes: 5
Views: 235
Reputation: 45829
As mentioned above, the order of these directives is important. The more specific rules should come before the more general rules and this is a key problem with the above. However, the pattern also needs to be changed (made more specific) to prevent other malformed URLs triggering a 500 Internal Server Error and breaking your site. eg. /en/blog_post/2/3
(an additional - erroneous - /something
) would still trigger a 500 error in the "fixed" code above.
So, this could be written as:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/([^/.]+)$ /$2?lang=$1
RewriteRule ^(bg|en)/([^/.]+)/([^/.]+)$ /$2?lang=$1&id=$3
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*) /$1.php [L]
The generic (.*)
pattern has been replaced with ([^/.]+)
to only match path segments (excluding a slash). By doing this it also means that the order no longer matters and /en/blog_post/2/3
will simply result in a 404.
I've also removed the L
flag on the initial RewriteRule
directives, since you need to continue anyway to append the .php
extension.
The RewriteRule
substitutions should also be kept as root-relative, ie. starting with a slash. (Or you should include the RewriteBase
directive.)
I've also added another RewriteCond
directive to make sure that <file>.php
actually exists before appending the file extension. If you don't do this and <file>.php
does not exist then you will get another 500 error.
You could combine the two RewriteRule
s into one if you don't mind having an empty id=
parameter (which presumably your script handles anyway):
RewriteRule ^(bg|en)/([^/.]+)(?:/([^/.]+))?$ /$2?lang=$1&id=$3
This handles both /en/blog_post
and /en/blog_post/2
requests.
Upvotes: 1
Reputation: 115
I did it. It works with these lines. Thanks to everyone :)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/post/([^/\.]+)$ blog_post.php?lang=$1&id=$2 [L]
RewriteRule ^(bg|en)/(.*)$ $2?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
Upvotes: 1