2

I have a hard time to create rewrite rule for a redirect using part of an old URL for WP. Example:

Old URL:

http://www.example.com/news/index.php/2014/11/07/my-blog-post-from-old-site

or

http://www.example.com/news/index.php/2014/11/07/my_blog_post_from_old_site

New URL:

http://www.example.com/2014/11/07/my-blog-post

New URL should to have only dates and first three elements of a permalink after stripping from dashes.

My solution came after combining answers from here https://stackoverflow.com/a/32852444/1090360 and here https://stackoverflow.com/a/1279758/1090360

Somehow part for replacing underscores with dashes creates infinite redirect and a server freezes. If I will remove part with replacing underscores to dashes all the rest works as should.

Here are my .httaccess rules

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

#replace underscores with dashes
RewriteRule ^(/news/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]
RewriteRule ^(/news/.*/[^/]*?)_([^/_]*)$ $1-$2 [R=301,L,NC]

#redirect to new URL
RewriteRule ^news/index\.php/([^-]+-[^-]+-[^-]+).* /$1 [R=301,L,NC]

#WP standard stuff
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Community
  • 1
  • 1
JackTheKnife
  • 3,795
  • 8
  • 57
  • 117

1 Answers1

2

I think, this is an expensive way to replace underscores with dashes. But this works at least in my test environment. The first rule replaces dashes one by one. The second rule then removes the prefix from the requested URL.

RewriteBase /

# replace underscores with dashes 
RewriteRule ^(news/index.php/.+?)_(.*) $1-$2 [L]

# strip "news/index.php"
RewriteRule ^news/index.php/(.*) /$1 [R=302,L]

I played a bit more with your original approach using the N|next flag and crashed my server too. Looking into the error.log, it seems this infinite loop is created by Apache by adding a "path info postfix", which enlarges the URL with the original URL. And so it keeps replacing underscores with dashes on and on.

You can prevent this path info postfix with another flag DPI|discardpath, which gives the following rule

RewriteRule ^(news/index.php/.+?)_(.*) $1-$2 [N,DPI]

This seems to work too. Although I must admit, I don't really understand this "path info postfix" thing. There's also an entry in Apache's Bugzilla, Bug 38642: mod_rewrite adds path info postfix after a substitution occured


Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

Community
  • 1
  • 1
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • How can I get this to work when there is trailing underscore in URI something like `2014/11/07/my-blog-post-from-old-site_`? Remove last character if it is underscore – JackTheKnife Sep 30 '15 at 17:25
  • Just replace the final `(.+)` with `(.*)`. This will match also an empty string. See also the modified answer. This will be a bit more efficient, because it doesn't do a redirect on every replace. – Olaf Dietsche Sep 30 '15 at 19:40
  • Is there any way to skip replacing underscores with dashes on images (.jpg, .png)? – JackTheKnife Oct 01 '15 at 14:47
  • Added that rule before rewrite `RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png)$ [NC]` and it works – JackTheKnife Oct 01 '15 at 15:02