1

I have some old url pattern to redirect to new location in nginx.

A typical clean url looks like example.com/2021/06/13/78676.html?..

Im roughly trying to match number of digit in each block like:

location ~ "^[0-9]{4}/[0-9]{2}/[0-9]{2}/([0-9]+).html" {
   rewrite ^ /archive.php?q=$1;
}

Where exactly Im going wrong please..

2
  • 1
    What is the problem you are having? Jun 13, 2021 at 0:12
  • 1
    Oops! forgive me. I forgot to comment out Certbot's 'return 404' directive at the end of file. I was applying this redirection for non https pages. everything works fine. Thank you
    – TELA
    Jun 13, 2021 at 0:39

2 Answers 2

2

The first issue is that all Nginx URIs begin with a leading /. So your regular expression will never match.

The second issue is that numeric captures are overwritten whenever a new regular expression is evaluated. So in your configuration, $1 will always be empty.

You could use a named capture:

location ~ "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/(?<value>[0-9]+)\.html" {
    rewrite ^ /archive.php?q=$value last;
}

Alternatively, place the numeric capture in the rewrite statement:

rewrite "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/(?<value>[0-9]+)\.html" /archive.php?q=$1 last;

Or use a try_files statement instead of rewrite:

location ~ "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/([0-9]+)\.html" {
    try_files nonexistent /archive.php?q=$1;
}
3
  • I found there is an issue with named capture too if someone pass a GET variable 'q' along with the request url like /2021/06/13/78676.html?a=1&q=asdf . In that case even named value seems overwritten by new $q = asdf. Any workaround ?
    – TELA
    Jun 13, 2021 at 22:08
  • If you want to keep the other parameters (like a=1) it gets tricky. Otherwise, use a trailing ? in the replacement value in the rewrite statement and the original arguments will not be appended. For example: rewrite ^ /archive.php?q=$value? last; - see this document. Jun 14, 2021 at 6:36
  • Btw repeating a point discussed elsewhere, ensure you use double quotes on such regex strings that contain curly brackets otherwise it will not work... also there should be no need to end the string with any $ sign either. May 12, 2022 at 8:49
1

This is a bit niche, but I thought it might help someone and it was too long to comment:

## noindex date archives ##
location ~ "^(.*)/[0-9]{4}/([0-9]{2}/)?([0-9]{2}/)?$" {
    try_files $uri $uri/ /index.php?$args;
    set $robots "noindex, nofollow, nosnippet, noarchive";
}

We had been trying to force noindex "date archives "in WordPress for our SlickStack project, and after a lot of testing this seems to do the trick perfectly.

The problem is that we didn't want to noindex potential blog posts like:

https://example.com/2020/03/25/interesting-story-about-ducks/

So, in this case the $ at the end of the location match regex is crucial, otherwise it would noindex any blog post or content that is prefixed by those date parameters! Also the ? right after the (groupings) mean that they are optionally matched, which makes this snippet pretty powerful.

It will noindex URLs like these:

https://example.com/2020/
https://example.com/2020/03/
https://example.com/2020/03/25/

...but not URLs like the example blog post above, which might have these prefixes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .