Nginx redirect all subfolders but the folder itself

nginxrewrite

I have a weird clash of names for a WordPress installation, and I need to write a couple of Nginx rules to fix it.

I used to have my software projects listed in the WordPress page /projects, with links to sub-pages /projects/aprojectname, /projects/anothername, etc.

Recently, I bought a theme with a custom post type for portfolio items.
It is called project (note the missing s).

At /project, I access the default WordPress listing of all the project posts. Then, I can access the posts using /project/aprojectname, /project/anothername, etc.

So far, so good. The issue is that I would like to use the new /project structure preserving any previous link to my /projects/something. Also, I would like to keep the /projects page only (no redirect).

This is what I would like to accomplish.

  1. The URL /project only should redirect to /projects, so that I can show a WordPress page instead of the "ugly" WordPress listing of posts.

  2. Consequently, The URL /projects only should not be processed. It should display the corresponding WordPress page.

  3. However, all URLs in the form /projects/something should redirect to /project/something

This is my nginx rule so far.

location ~ ^/projects/(.*) {
   return 301 http://$server_name/project/$1;
}

This works good for 3.: /projects/aprojectname -> /project/aprojectname.

It does not work for 2., because it rewrites /projects to /project

I have no clue how to implement 1., as any attempt will affect the previously written rule.

Best Answer

location ~ ^/projects/(.+) {
    rewrite ^ http://$server_name/project/$1 permanent;
}

The .+ instead of .* fixes the issue, since .+ matches 1 or more characters, while .* matches 0 or more characters. Therefore the /projects/ folder is not touched by the rule.

For 1, the following should work:

location = /project {
    rewrite ^ http://$server_name/projects permanent;
}

location = is the exact matching directive for nginx, so it only matches if the URI is exactly /project.

I also replaced the return 301 directive with rewrite -directive, as that is preferred way of doing rewrites.

  • Tero