Rewrite Rule for 301 redirections structure - wordpress

I have developed a project where url structure has changed from the old webpage and I need to create 301 redirects to avoid SEO penalization. After reading a lot I can't find how to do this rewrites.
Old URL
/es/madrid/comprar/893134/prop-712/
New URL
/es/property/prop-712/
Idea approach
RewriteRule ^/$1/property/$5 /$1/$2/$3/$4/$5/
What I need is using only the first path as param (/es/) and the last (/prop-712/) to restructure the URL /$first/property/$second and remove the $2, $3 & $4.
As you will see we share the last param (prop-712) of the URL. Any idea if this is possible?

Try the following at the top of the root .htaccess file using mod_rewrite:
RewriteRule ^([a-z]{2})(?:/[\w-]+){3}/([\w-]+?)/?$ https://example.com/$1/property/$2/ [R=301,L]
This will redirect a URL of the form /<lang>/<one>/<two>/<three>/<prop>/ (trailing slash optional) to https://example.com/<lang>/property/<prop>/. Where <lang> is any two lowercase letter language code and example.com is your canonical hostname. This matches exactly 3 path segments in the middle that are removed.
The regex [\w-]+ matches each path segment, including the property (last path segment). This matches characters in the range a-z, A-Z, 0-9, _ (underscore) and - (hyphen).
Only the first and last path segments are captured and later referenced using the $1 and $2 backreferences respectively. The parenthesised subpattern in the middle (ie. (?:/[\w-]+){3}) that matches the 3 inner path segments is non-capturing (indicated by the (?: prefix).
You do not need to repeat the RewriteEngine directive, since this already occurs later in the file inside the WordPress code block.
Test first with a 302 (temporary) redirect to prevent potential caching issues. Only change to a 301 (permanent) redirect when you are sure it is working as intended.
A quick look at your "idea":
RewriteRule ^/$1/property/$5 /$1/$2/$3/$4/$5/
In .htaccess files, the URL-path that the RewriteRule pattern matches against, does not start with a slash.
Backreferences of the form $n are used to reference capturing groups in the RewriteRule pattern (first argument). Backreferences can only be used in the substitution string (second argument)*1. You can't use backreferences in the RewriteRule pattern itself (which is a standard regex) - the $ carries special meaning here as an end-of-string anchor (regex syntax).
(*1 ...and the TestString (first) argument of any preceding RewriteCond directives, but this does not apply here.)
Reference:
https://httpd.apache.org/docs/2.4/rewrite/intro.html
https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

Related

nginx rewrite regex matching first group instead of all

I'm working on an nginx rewrite rule to redirect:
/collections/collection-name/products/product-handle-with-dashes
to:
/products/product-handle-with-dashes
I've got it almost working, the only issue I have right now if my rule to match the product handle is only returning the first string before the first hyphen.
My rule:
rewrite ^(/collections/.*)/products/(\w+)\.?.*$ /products/$2 permanent;
With this rule if I hit the following path: /collections/collection-name/products/some-product-handle it will redirect me to /products/some
what am I missing on my regex to allow it my second variable to capture the entire handle with dashes.
\w metacharacter of the PCRE/PCRE2 regex patterns include characters from ranges a-z, A-Z, 0-9 and underscore. It does not include a hyphen. You probably want [-\w] instead. The whole rewrite rule can be the
rewrite ^/collections/[^/]+(/products/[-\w]+)(\.\w+)?$ $1 permanent;

Nginx rewrite with and without trailing slash

I'm trying to create a set of rules that match a url with and without a trailing slash
Most of the answers were pointing me to use something similar to this.
location /node/file/ {
rewrite ^/node/file/(.*)/(.*)$ /php/node-file.php?file=$1&name=$2;
rewrite ^/node/file/(.*)/(.*)/?$ /php/node-file.php?file=$1&name=$2; │
}
But this does not match the trailing slash url.
How can I write a rule that matches urls that look like
http://example.com/node/file/abcd/1234/
http://example.com/node/file/abcd/1234
The first rewrite statement includes (.*) as the last capture, which will match any string, including one with a trailing slash.
Use the character class [^/] to match any character except the /:
rewrite ^/node/file/([^/]*)/([^/]*)$ /php/node-file.php?file=$1&name=$2;
rewrite ^/node/file/([^/]*)/([^/]*)/?$ /php/node-file.php?file=$1&name=$2;
Now you will notice that the first rewrite statement is unnecessary, as the second rewrite statement matches URIs both with and without a trailing /.
So all you need is:
rewrite ^/node/file/([^/]*)/([^/]*)/?$ /php/node-file.php?file=$1&name=$2;

Nginx Regular expression to match first segment of a url

I have some urls like these:
domain.com/article/1234-newstitle
domain.com/article/1234-newstitle/
domain.com/article/1234-newstitle/abc
domain.com/article/1234-newstitle/xpto/abc
domain.com/article/1234-newstitle/qwerty/abc/xyz
I want to catch only the /1234-newstitle/ to redirect these urls and ignore everything after the 1º slash (whatever the number of segments) so I can have:
domain.com/news/newstitle-1234/
The best I could get is:
rewrite ^article/(\d+)-(.*)[^\/]* /new/$2-$1/ permanent;
but $2 matches everything after 1234-
How am I able to match only the first segment "1234-newstitle" and ignore the rest?
Looks like you've got a greedy match after the hyphen. Try this:
rewrite ^/article/(\d+)-([^/]+) /new/$2-$1/ permanent;

Limitations on regex in nginx?

I had a rewrite rule on Apache for /year/month/date links in a form that specifically defined 4 digits, then 2 digits, then 2 digits, that looked like this:
^([0-9]{4})/([0-9]{2})/([0-9]{2})/$
On nginx this regex causes an error that says the whole line is not terminated by a ; sign, until i remove the {} brackets and leave the regex like this:
^/([0-9]+)/([0-9]+)/([0-9]+)/$
Is this limitation intentional on nginx's part or some mistake on my part?
The whole line from Apache:
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/$ index.php?page=date&year=$1&month=$2&day=$3
The whole (working) line from nginx:
rewrite ^/([0-9]+)/([0-9]+)/([0-9]+)/$ /index.php?page=date&year=$1&month=$2&day=$3;
If a regular expression includes the “}” or “;” characters, the whole expressions should be enclosed in single or double quotes.
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

How to redirect post feed to main blog feed with htaccess?

i have one question: How to redirect post feed to main blog feed with htaccess?
for example: myblog.com/18364552/post-name/feed/ to myblog.com/feed/
thank
The rewriterule you are looking for looks something like this:
RewriteRule ^[0-9]{4}/[0-9]{1,2}/[^/]+/feed/?$ /feed [R,L]
It should be self-explenatory. Please refer to the documentation if you don't understand some of the syntax.
Regex explaination
[0-9] means match a character that is in the range of 0 to 9 (e.g. any number).
[0-9]{4} means match 4 numbers.
Similary [0-9]{1,2} means match 1 or 2 numbers.
[^/] means match any character but the / character.
[^/]+ means match 1 or more characters that are not a /.
/? means match 0 or 1 / character.
^...$ means match the beginning of the string (^) and the end of the string $, forcing it to match the entire string, even if this regex could match a substring of the entire string.

Resources