skyler
skyler

Reputation: 8348

Nginx rewrite with conditional destination

I have a site with two RESTful URL schemes:

foo.com/model/id and foo.com/model/id/action

The actual pages served by these URLs are in the form of

$model.php?id=$id and $model_$action.php?id=$id respectively.

I have a single regular expression that will match both cases ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ and I'd like to use a single Nginx rule to rewrite for both types of URLs, but I'm not sure how to do this. In pseudocode I imagine the rule would look something like this

rewrite ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ /(($3) ? $1_$3.php?$id=$2 : $1.php?$id=2)

This isn't valid syntax (so far as I know), but can something like this be done in Nginx?

Upvotes: 1

Views: 2637

Answers (1)

Dayo
Dayo

Reputation: 12795

Rewrite the possible urls in turn starting with the longest to the shortest to that overlapping matching strings, "/model/id" in this case, would be matched in the longer url string first.

location / {
    # For "/model/id/action" to "$model_$action.php?id=$id"
    rewrite ^/(.+)/(.+)/(.+)(/?)$ $1_$3.php?id=$2 last;

    # For "/model/id" to "$model.php?id=$id"
    rewrite ^/(.+)/(.+)(/?)$ $1.php?id=$2 last;
}
location ~ .+\.php$ {
    # Handle PHP
}

The "(/?)" is just in case the urls sometimes come with an ending slash. If they never do, it can be removed. In this case, it will probably be best to specifically always add a closing slash and have "(/?)" as "/".

Upvotes: 1

Related Questions