Sergio Manzi
Regular Pleskian
... or, paraphrasing the old saying, "quite a big leap for me, but a really small step for mankind".
I've passed the last few days fighting my battle with Plesk, Joomla and nginx. The objective was to have Joomla to run natively (not in "proxy mode") under Plesk's nginx.
Joomla, as most CMS I think, want to handle every URL through its main entry point, /index.php, and that seems quite reasonable. Excluded from this must of course be real "static resources", such as images, CSS files, scripts, fonts, etc...
Joomla can (basically, with some more variants in between...) be used with two type of URLs:
In Apache this is done by putting the following directives in .htaccess:
Of course the above means "If the URI is not a file, not even a directory and it doesn't start with /index.php, then redirect the damn thing to /index.php".
This has worked, for ages, with Apache and Joomla.
It is common knowledge (Nginx - Joomla! Documentation and Enabling php-fpm + nginx and link rewrite or All URLs Display Homepage Content on a Joomla Website Powered by NGINX | itoctopus among the many I found around) that in nginx you should "translate" the above with the following nginx configuration block:
or the simpler form (which doesn't bother of the "$args" and seems to perfectly work):
The above should do about the same (see if it is a file or directory and if not try /index.php) and it mostly works.
But it doesn't always works: enter "Joomla multilingual"!
In multilingual Joomla installations using SEF URLs, the language is expressed by a "language code" used as a prefix in the URL:
Well, for some yet-to-fully-understand reason the above URLs do not work and you get instead a nice "nginx 404" error, even for the "home pages".
This apparently doesn't make any sense: Joomla handle 404s by itself and doesn't let them to "percolate" to the nginx level... but... it happens, methodically, always.
P.S.: Read some posts below: the general issue is with URLs ending with a slash.
"Multilingual" is just a particular case, where Joomla language switcher uses URLs ending with a slash (/en/, /it/, etc...)
In such conditions (if you're an experimenter) try to create the "en" and "it" directories and put /index.html files inside: they are displayed!!!!
From a logcial point of view there are two possibilities to explain the above:
The solution:
In any case, if it works with Apache, by Jove, it must also work with nginx!
So I did the simplest of the things and "translated" the Apache .htaccess directives in nginx parlance (inverting the logic for implementation simplicity).
put this in your subscription "Apache & nginx Settings" in the "Additional nginx directives".
At this point I have the strange feeling of having @trialotto teeth at my throat, grinnning: "if" in nginx is EVIL!
I know... but... ehi, the above works, always!!
hoping that someone else can find an even simpler and "if-less" solution, if you have Joomla-nginx-multilingual-blues, please give the above a try: for me it works, flawlessly.
Hope the above can help someone...
I've passed the last few days fighting my battle with Plesk, Joomla and nginx. The objective was to have Joomla to run natively (not in "proxy mode") under Plesk's nginx.
Joomla, as most CMS I think, want to handle every URL through its main entry point, /index.php, and that seems quite reasonable. Excluded from this must of course be real "static resources", such as images, CSS files, scripts, fonts, etc...
Joomla can (basically, with some more variants in between...) be used with two type of URLs:
- non-SEF URLs, in which index.php is directly "named" in the URL, such as:
https://example.com/index.php?option=com_content&view=article&id=1:article&catid=8&Itemid=102 - SEF URLs in which "aliases" are used to build an "URL path" which will be parsed by Joomla, like e.g.:
https://example.com/8-category/1-article
In Apache this is done by putting the following directives in .htaccess:
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule .* index.php [L]
Of course the above means "If the URI is not a file, not even a directory and it doesn't start with /index.php, then redirect the damn thing to /index.php".
This has worked, for ages, with Apache and Joomla.
It is common knowledge (Nginx - Joomla! Documentation and Enabling php-fpm + nginx and link rewrite or All URLs Display Homepage Content on a Joomla Website Powered by NGINX | itoctopus among the many I found around) that in nginx you should "translate" the above with the following nginx configuration block:
Code:
location / {try_files $uri $uri/ /index.php?$args;}
Code:
location / {try_files $uri $uri/ /index.php;}
The above should do about the same (see if it is a file or directory and if not try /index.php) and it mostly works.
But it doesn't always works: enter "Joomla multilingual"!
In multilingual Joomla installations using SEF URLs, the language is expressed by a "language code" used as a prefix in the URL:
Code:
https://example.com/en/
https://example.com/en/8-category-en/1-article
https://example.com/it/
https://example.com/it/9-category-it/2-articolo
Well, for some yet-to-fully-understand reason the above URLs do not work and you get instead a nice "nginx 404" error, even for the "home pages".
This apparently doesn't make any sense: Joomla handle 404s by itself and doesn't let them to "percolate" to the nginx level... but... it happens, methodically, always.
P.S.: Read some posts below: the general issue is with URLs ending with a slash.
"Multilingual" is just a particular case, where Joomla language switcher uses URLs ending with a slash (/en/, /it/, etc...)
In such conditions (if you're an experimenter) try to create the "en" and "it" directories and put /index.html files inside: they are displayed!!!!
From a logcial point of view there are two possibilities to explain the above:
- "try_files" has an idiosyncrasy for Joomla language codes and handles them in a different way, like they always exists as files/directories even when this is not the case
- The Joomla router component responsible for parsing language codes (I think it is the "language filter" plugin) has some bug and redirects in such a way to confound nginx.
I'm slightly inclined to suspect this latter might be the cause.
The solution:
In any case, if it works with Apache, by Jove, it must also work with nginx!
So I did the simplest of the things and "translated" the Apache .htaccess directives in nginx parlance (inverting the logic for implementation simplicity).
put this in your subscription "Apache & nginx Settings" in the "Additional nginx directives".
Code:
set $rewrite 1;
if (-f $request_filename) {set $rewrite 0;}
if (-d $request_filename) {set $rewrite 0;}
if ($uri ~* "^/index\.php") {set $rewrite 0;}
if ($rewrite) {rewrite /.* /index.php last;}
At this point I have the strange feeling of having @trialotto teeth at my throat, grinnning: "if" in nginx is EVIL!
I know... but... ehi, the above works, always!!
hoping that someone else can find an even simpler and "if-less" solution, if you have Joomla-nginx-multilingual-blues, please give the above a try: for me it works, flawlessly.
Hope the above can help someone...
Last edited: