1

I have recently localized my php webpage with Gettext in a VPS running LEMP Debian 10 (PHP 7.3.27-1~deb10u1). The localized versions of the pages have the following URLs:

example.com/index.php?lang=es_ES

and

example.com/index.php?lang=en_GB

and so on.

I am trying get Nginx to rewrite the URL requests to fake folders in the following way:

example.com/en/index.php to=> example.com/index.php?lang=en_GB

example.com/es/index.php to=> example.com/index.php?lang=es_ES

and

example.com/en/manage/index.php to=> example.com/manage/index.php?lang=en_EN

example.com/es/manage/index.php to=> example.com/manage/index.php?lang=es_ES

And so on. I have tried other solutions with no success. My Nginx server block configuration is as follows:

server {

    root /var/www/example.com;
    index index.html index.htm index.php;

    server_name example.com;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    }

    location ~ /(.*)$ {
        try_files $uri $uri/ /profiles.php?user-id=$1; #pretty urls for user profiles
    }

    listen 443 ssl;
}

There is already a rewrite in place: example.com/123 => example.com/profiles.php?user-id=123. I'd appreciate some insight on making the desired rewrites to work, without affecting the one already in place. Thanks

Sammitch
  • 30,782
  • 7
  • 50
  • 77
Esquirish
  • 185
  • 1
  • 12
  • In what way did those other solutions not work? – Sammitch May 29 '21 at 00:20
  • @ Sammitch the rewrites are not triggered, for example after adding the following line: `location = / { if ($arg_lang) { return 301 /$arg_lang$uri; } }` , the requests to `example.com/es_ES/index.php` return a 404 error. – Esquirish May 29 '21 at 00:24

2 Answers2

2

You can try this:

map $lang $locale {
    en      en_GB;
    es      es_ES;
}

server {

    root /var/www/example.com;
    index index.html index.htm index.php;

    server_name example.com;

    rewrite ^/(?<lang>en|es)(?<suffix>/.*) $suffix?lang=$locale;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    }

    location ~ /(.*)$ {
        try_files $uri $uri/ /profiles.php?user-id=$1; #pretty urls for user profiles
    }

    listen 443 ssl;
}

I removed location / { try_files $uri $uri/ =404; } because

  • try_files $uri $uri/ =404; is default nginx behavior;
  • location ~ /(.*) will math any request (regex locations have greater priority than prefix ones) and will overtake any request except those ending with .php (regex locations are checked from first to last).
Richard Smith
  • 45,711
  • 6
  • 82
  • 81
Ivan Shatsky
  • 13,267
  • 2
  • 21
  • 37
  • Your solution worked perfectly, thank you. @Richard's solution also worked as intended but marked your answer for the additional insight. – Esquirish May 29 '21 at 10:26
1

Use a rewrite statement to remove the prefix and add the language argument. You probably need two rewrite statements as the language arguments are unique.

There are a number of ways to structure this, for example using separate prefix locations:

location ^~ /en/ {
    rewrite ^/en(/.*)$ $1?lang=en_GB last;
}
location ^~ /es/ {
    rewrite ^/es(/.*)$ $1?lang=es_ES last;
}
Richard Smith
  • 45,711
  • 6
  • 82
  • 81