How to handle a pretty URL in nginx that is not calling index.php from the root folder?

So if we did the following in the location block of the nginx.conf:

try_files $uri $uri/ /index.php?$args;

That calls the index.php file from the root folder of the web server if we did something like https://www.example.com/john.

How would we write that so the index.php file it calls is the one in its parent folder?

For example: https://www.example.com/thisparent/john

That would use the index.php file from this location: https://www.example.com/thisparent/

This must work for any location of the web server where the pretty URL will be from the parent of the requested URL.


Solution 1:

In order to internally redirect the URI path /parent/child to /parent/index.php, you need to compute the path to the parent directory /parent, since nginx does not provide a variable for the parent directory.

For example you can use:

location ~ \.php$ {
    # PHP FASTCGI configuration
}
# Matches are eager, so the first group matches everything
# up to the last '/'. We capture it into the $parent named variable.
location ~ ^(?<parent>.*)/ {
    try_files $uri $parent/index.php$is_args$args;
}

The regular expression in the last location matches every possible URI path, so it has to be the last one in the server block and will take precedence over all normal prefix locations (except those with ^~ and exact locations).

A solution that is less aggressive is to use a named location as the fallback of the try_files directive:

location / {
    try_files $uri @parent_index;
}

location ~ \.php$ {
    # PHP FASTCGI configuration
}

location @parent_index {
    rewrite ^(?<parent>.*)/ $parent/index.php;
}