I have an NGINX rewrite/return block as follows:
if ($request_uri ~ /product-category/(.*)/$) {
return 301 /shop/?categories[]=$1;
}
This correctly matches https://example.com/product-category/cat-1/
and redirects that to https://example.com/shop/?categories[]=cat-1
.
But, I have a few URLS that have a variable number of directories between the product-category
and final cat-1
, i.e.
https://example.com/product-category/parent/cat-1/
https://example.com/product-category/gparent/parent/cat-1/
https://example.com/product-category/distant-relative/gparent/parent/cat-1/
...
I am looking for a rewrite
or return
rule that would match any URL that starts with product-category
after the domain, extracts the very last directory name, and compiles my redirect like in the first example.
Said another way, I need some way for all of the URLs in my second example above to redirect to https://example.com/shop/?categories[]=cat-1
no matter how many ancestor directories may exist between the product-category
and final directory.
Any advice would be super appreciated.
Try: ^/product-category/(?:.*/)?([^/]+)/$
The $request_uri
variable contains the path and query parts of the original URL.
In your examples, it always begins with /product-category/
and ends with /
and may contain any number of path segments in between.
The solution breaks down as follows:
^/product-category/
(?:.*/)?
([^/]+)
/$
Step (1) matches the path segment at the beginning (hence the start of string anchor ^
).
Step (2) is a non-capturing group that matches any text that ends with a /
, including text containing multiple /
s, and will therefore consume one or more path segments. We add a trailing ?
to make it optional, so it also matches zero path segments.
Step (3) captures $1
, which is the text between two /
s.
Step (4) completes the expression with the final /
and the end of string anchor.
This solution assumes that there is no query string or separating ?
.