# Rewrite don't work in a multilanguage MVC site

**URL:** <https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175>\
**Category:** NGINX\
**Created:** [October 25, 2011, 6:57pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175 "2011-10-25T18:57:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [October 25, 2011, 6:57pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/1 "2011-10-25T18:57:03Z")

</div>

Hi!Im trying to move from Apache to nginx (v1.1.6), but you know,  
rewrite newbie here… In my site when a user types [http://site.com](http://site.com) he’s  
redirected to [http://site.com/en/](http://site.com/en/), and all the other URLs are internally  
handled by an index.php. This is my actual Apache htaccess:  
RewriteEngine On  
RewriteCond %{HTTP:Accept-Language} ^en [NC] RewriteRule ^$ /en/  
[L,R=301]  
RewriteCond %{HTTP:Accept-Language} ^es [NC] RewriteRule ^$ /es/  
[L,R=301]  
RewriteCond %{REQUEST\_FILENAME} !-f RewriteCond  
%{REQUEST\_FILENAME} !-d RewriteRule (._) index.php?ctr=$1 [QSA,L]  
And this my translation to nginx:  
location / { if (-f $request\_filename) {  
expires 30d; break; }  
if ($http\_accept\_language ~_ “^es”) {  
rewrite ^/$ /es/ permanent; break; }  
if ($http\_accept\_language ~\* “^en”) {  
rewrite ^/$ /en/ permanent; break; }  
if (!-e $request\_filename) { rewrite  
(.\*) /index.php?ctr=$1 last; } } location ~ .php$  
{ fastcgi\_param SCRIPT\_FILENAME  
$document\_root$fastcgi\_script\_name; …  
With this, when I type [http://site.com](http://site.com) I’m being redirected to  
[http://site.com/en/](http://site.com/en/), great, but I get a 404 error, and in the error.log  
I have this line:  
“/bla/bla/html/en/index.php” is not found  
So, why is not nginx looking for the URI /index.php?ctr=/en/?

---

<div class="post-metadata">

**Author:** ![SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6a8cbe/32.png) [@SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/u/SSFernando_GarcS_a_S)\
**Post date:** [October 25, 2011, 7:16pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/2 "2011-10-25T19:16:14Z")

</div>

On 25 Out 2011 17h56 WEST, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> [1 \<multipart/alternative (7bit)\>]  
> [1.1 \<text/plain; iso-8859-1 (quoted-printable)\>]
> 
> Hi!Im trying to move from Apache to nginx (v1.1.6), but you know,  
> rewrite newbie here… In my site when a user types [http://site.com](http://site.com)  
> he’s redirected to [Login | HSTS Redirection Community](http://site.com/en/), and all the other URLs are  
> internally handled by an index.php. This is my actual Apache

Try this:

At the http level.

map $http\_accept\_language $is\_english {  
default 0;  
~^en 1;  
}

map $http\_accept\_language $is\_spanish {  
default 0;  
~^es 1;  
}

location / {

expires 30d;

if ($is\_english) {  
return 301 /en;  
}

if ($is\_spanish) {  
return 301 /es;  
}

location /es {}

location /en {}

try\_files $uri $uri/ /index.php?ctr=$uri;  
}

location ~.php$ {

# PHP stuff

}

— appa

---

<div class="post-metadata">

**Author:** ![SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6a8cbe/32.png) [@SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/u/SSFernando_GarcS_a_S)\
**Post date:** [October 25, 2011, 8:18pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/3 "2011-10-25T20:18:41Z")

</div>

Tried, and same results, redirect OK but 404 response.  
Thanks!!

---

<div class="post-metadata">

**Author:** ![SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6a8cbe/32.png) [@SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/u/SSFernando_GarcS_a_S)\
**Post date:** [October 25, 2011, 9:01pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/4 "2011-10-25T21:01:24Z")

</div>

> Show your complete config.
> 
> — appa

Here we go. Those includes are the standard locations por PHP-FPM and  
static content:  
map $http\_accept\_language $is\_english { default 0; ~^en 1;}  
map $http\_accept\_language $is\_spanish { default 0; ~^es 1;}  
server { listen 80; server\_name localhost; root blah/blah;  
location / { auth\_basic “Restricted”; auth\_basic\_user\_file  
htpasswd; index index.php index.html;  
expires 30d;  
if ($is\_english) { return 301 /en; }  
if ($is\_spanish) { return 301 /es; }  
location /es {}  
location /en {}  
try\_files $uri $uri/ /index.php?ctr=$uri; }  
include /usr/local/nginx/conf/staticfiles.conf; include  
/usr/local/nginx/conf/php.conf; include  
/usr/local/nginx/conf/drop.conf;}

---

<div class="post-metadata">

**Author:** ![SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6a8cbe/32.png) [@SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/u/SSFernando_GarcS_a_S)\
**Post date:** [October 25, 2011, 8:34pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/5 "2011-10-25T20:34:08Z")

</div>

On 25 Out 2011 19h17 WEST, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Tried, and same results, redirect OK but 404 response.  
> Thanks!!

Show your complete config.

— appa

---

<div class="post-metadata">

**Author:** ![SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/6a8cbe/32.png) [@SSFernando\_GarcS\_a\_S](https://www.ruby-forum.com/u/SSFernando_GarcS_a_S)\
**Post date:** [October 25, 2011, 10:23pm UTC](https://www.ruby-forum.com/t/rewrite-dont-work-in-a-multilanguage-mvc-site/213175/6 "2011-10-25T22:23:44Z")

</div>

On Tue, Oct 25, 2011 at 06:56:05PM +0200, Fernando Garca Torres wrote:

Hi there,

> ```
> RewriteEngine On
> RewriteCond %{HTTP:Accept-Language} ^en [NC] RewriteRule ^$ /en/ 
> 
> ```

[L,R=301]

> ```
> RewriteCond %{HTTP:Accept-Language} ^es [NC] RewriteRule ^$ /es/ 
> 
> ```

[L,R=301]

> ```
> RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d 
> 
> ```

RewriteRule (.\*) index.php?ctr=$1 [QSA,L]

If I read this right, it only redirects the request for “/” to “/en/” or  
“/es/” if the Accept-Language header begins with one of those strings;  
otherwise, if the file-or-directory exists, serve it; otherwise,  
redirect  
to index.php?ctr=(the original request).

Note that nginx and apache differ in the leading / of the url, so you’ll  
want to make sure that you allow for that. I’m going to assume that you  
want to redirect to /index.php for all otherwise-404s.

Also note that you’ll want to check whether apache writes  
index.php?ctr=request or index.php?ctr=/request. The check what you  
configure nginx to write, and see if it works too.

And as a final note – checking the first two characters of  
Accept-Language is not the right way to process that header. But it’s  
your site, and you get to do what you want on it.

> And this my translation to nginx:  
> location / { if (-f $request\_filename) {  
> expires 30d; break; }  
> if ($http\_accept\_language ~\* “^es”) { rewrite ^/$  
> /es/ permanent; break; }  
> if ($http\_accept\_language ~\* “^en”) { rewrite ^/$  
> /en/ permanent; break; }  
> if (!-e $request\_filename) { rewrite (.\*)  
> /index.php?ctr=$1 last; } }

I suggest writing this as two locations:

```
    location = / {
      if ($http_accept_language ~* "^en") {
         return 301 /en/;
      }
      if ($http_accept_language ~* "^es") {
         return 301 /es/;
      }
    }

    location / {
      try_files $uri $uri/ /index.php?ctr=$uri;
    }

```

> location ~ .php$ { fastcgi\_param SCRIPT\_FILENAME  
> $document\_root$fastcgi\_script\_name; …

I would be more explicit, unless you have more php scripts:

```
    location = /index.php {
      fastcgi_pass unix:php.sock;
    }

```

with

```
    include fastcgi.conf;

```

at server level. But however you want to handle php is probably fine.

> With this, when I type [http://site.com](http://site.com) I’m being redirected to  
> [Login | HSTS Redirection Community](http://site.com/en/), great, but I get a 404 error, and in the error.log I have  
> this line:  
> “/bla/bla/html/en/index.php” is not found

I get a 403 Forbidden, not a 404, so I must have some other  
configuration  
difference from you.

> So, why is not nginx looking for the URI /index.php?ctr=/en/?  
> Per the config, if the directory exists, it is served.

In my tests /en/ exists and returns 403, /ex/ doesn’t and returns the  
same content as /index.php?ctr=/ex/ does, apart from REQUEST\_URI being  
different.

Good luck with it,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
