Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx clean urls, how to rewrite a folder as an argument with try_files

I'm writing a simple CMS in PHP. Pages (markdown files) and images are accessed like this (respectively):

example.org/?q=about.md
example.org/?i=photo.jpg

Optionally, I would like to use clean URLs with Nginx, to make the same requests look like this:

example.org/about
example.org/photo.jpg

I rather use try_files than if and rewrite but after experimenting for hours, I can't get it to work.

location / {
    try_files $uri $uri/ /?q=$uri.md =404;
}

location ~ \.(gif|jpg|png)$ {
    try_files $uri /?i=$uri =404;
}

I don't understand why the above code doesn't work (urls with argument work fine but the pretty ones give 404 errors).

Is there something wrong with passing the folder name as an argument using $uri?
Do I need to escape some weird characters (apart from my landlord)?


To be thorough, I'm running Nginx 1.6.2, using the standard nginx.conf. Here's the rest of my server block:

server_name example.org;
root /srv/example/;
index index.html index.htm index.php;

(...)

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;    
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
}

and fastcgi.conf is also standard.

like image 297
wilks Avatar asked Apr 13 '15 14:04

wilks


People also ask

What does Try_files do in Nginx?

The try_files directive exists for an amazing reason: It tries files in a specific order. NGINX can first try to serve the static content, and if it can't, it moves on. This means PHP doesn't get involved at all.

How do you write rewrite rules in Nginx?

The syntax of rewrite directive is: rewrite regex replacement-url [flag]; regex: The PCRE based regular expression that will be used to match against incoming request URI. replacement-url: If the regular expression matches against the requested URI then the replacement string is used to change the requested URI.

What is return 301 in Nginx?

On the other hand, a permanent Nginx redirect informs the web browser that it should permanently link the old page or domain to a new location or domain. To map this change, the redirects response code 301 is used for designating the permanent movement of a page.


1 Answers

I was able to get your example to work by simply omitting the =404:

location / {
    try_files $uri $uri/ /?q=$uri.md;
}

location ~ \.(gif|jpg|png)$ {
    try_files $uri /?i=$uri;
}

Quoting the manual:

Checks the existence of files in the specified order and uses the first found file for request processing; [...] If none of the files were found, an internal redirect to the uri specified in the last parameter is made.

You want that internal redirect, which is only happening if none of the files are found, but =404 is always found.

like image 191
Siguza Avatar answered Oct 17 '22 20:10

Siguza