11

i'm stuck with some problem with .htaccess my simplified file server structure is the following:

/index.php
/signup.php

i need to work with virtual urls for handling the language switch:

www.mydomain.com/en/signup.php   
www.mydomain.com/de/signup.php

so my .htaccess should check if url contains /en/ or /de/ and translate it to eg. /signup.php?language=de

basically spoken, it should strip the language tag but keep the rest of the folder structure.

it should work on both my local xampp and on my live server. any ideas? thanks

Fuxi
  • 329
  • 2
  • 6
  • 15

1 Answers1

16

What have you tried so far? Something like the following should work:

RewriteRule ^/(en|de)/(.*)$  $2?language=$1 [L]

The meaning is rather obvious: take the second match ($2), that is what comes after the second slash in the URL, postpone a ?language= after it, and then the first match ($1), that is, what's between the first two slashes - provided it's one of en or de. If you wanna match anything (not only en or de) as language, then change the rule to:

RewriteRule ^/(.+?)/(.*)$  $2?language=$1 [L]

Please note: the ? in the first group will make the match stop at first slash, so that you won't rewrite eg.

/en/subdir/pippo.php

to

pippo.php?language=en/subdir

but rather to

subdir/pippo.php?language=en

In case of doubts, there is an excellent documentation in the Apache website.


Edit: default language

To make all other requests (that is, URLs not starting with /en/ or /de/) redirect to a default language (say en), first you have to know the language prefixes you want to recognize, and then use the following rules - below, I'm assuming there are three -3- languages, with codes en,de and fr:

RewriteEngine On
RewriteBase /

RewriteRule ^(en|de|fr)/(.*)$  $2?language=$1 [L,QSA]
RewriteRule ^(.*)$  $1?language=en [L,QSA]

If you don't define the exact language set in the first RewriteRule (eg using my previous "any language" solution), language detection could fail on nested pages. It's important that the rules are in this order because the first one will match pages with the language code and then exit, whilst the second one will be applied only if the first does not match.

Paolo Stefan
  • 10,112
  • 5
  • 45
  • 64
  • this looks pretty good :) how can i set my language default to EN? like if no language tag is defined -> redirect to mydomain.com/en/ ? – Fuxi May 31 '13 at 10:28
  • Since all these rules are flagged `[L]` (last rule checked), you could write a redirect to English after them all: `RewriteRule ^(.*)$ $1?language=$1 [L]`This rule MUST be last though. – Glitch Desire May 31 '13 at 10:34
  • @Fuxi do you want mydomain.com -> mydomain.com/en/ only, or all mydomain.com/stuff to go to mydomain.com/en/stuff? the second is a bit more complicated – Paolo Stefan May 31 '13 at 10:37
  • hi paolo - yes i need the 2nd option :/ – Fuxi Jul 12 '13 at 12:54
  • For me the second rule didnt work as expected. My css, js and images were not redirected correctly, althought I have had RewriteCond %{REQUEST_FILENAME} !-f and RewriteCond %{REQUEST_FILENAME} !-d statements before the rewrite rules. But it is working when I change the second rewrite rule to: RewriteRule ^(.+?)?/$ index.php?url=$1&lang=de [L,QSA] – Erik Čerpnjak Jan 25 '16 at 15:27
  • How to do this when using a public folder? – TheCrazyProfessor Apr 02 '17 at 10:27
  • @TheCrazyProfessor what do you mean? Please elaborate a bit. – Paolo Stefan Apr 03 '17 at 10:30
  • @PaoloStefan i mean: if You use a folder anmeld `Public` and one named `App` like the framework Laravel, Then You need to set so the website "belive" that the `public` is the root. I did that and it kinda work if i type example.com/en/home but NOT if i type example.com/da/home. Then it fail and the URL miss up to end look like `example.com/public/home?lang=da` – TheCrazyProfessor Apr 03 '17 at 10:42
  • @PaoloStefan Exactly what this guy are asking about http://stackoverflow.com/q/43159674/4691734. I have that weird problem that the url mess up sometimes when you type another language in the url – TheCrazyProfessor Apr 03 '17 at 18:26
  • @TheCrazyProfessor you could use eg: `RewriteRule ^(en|de|fr)/(.*)$ public/$2?language=$1 [L,QSA]` and then for the default language `RewriteRule ^(.*)$ public/$1?language=en [L,QSA]`.This way you don't expose the `public/` dir in the URL. – Paolo Stefan Apr 04 '17 at 11:36
  • this will mess up the query string if there are other variables: `/en/signup.php?user=john` would be sent to `/signup.php?user=john?language=en` – Abraham Murciano Benzadon Jun 04 '18 at 23:47