I use the RewriteEngine
with the following htaccess
rules to remove accented and capitalized letters from urls:
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(A|Á|á|Â|â|Æ|æ|À|à|Å|å|Ã|ã|Ä|ä)(.*?)$
RewriteRule . %1a%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(B)(.*?)$
RewriteRule . %1b%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(C|Ç|ç)(.*?)$
RewriteRule . %1c%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(D)(.*?)$
RewriteRule . %1d%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(E|É|é|Ê|ê|È|è|Ð|ð|Ë|ë)(.*?)$
RewriteRule . %1e%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(F)(.*?)$
RewriteRule . %1f%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(G)(.*?)$
RewriteRule . %1g%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(H)(.*?)$
RewriteRule . %1h%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(I|Í|í|Î|î|Ì|ì|Ï|ï)(.*?)$
RewriteRule . %1i%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(J)(.*?)$
RewriteRule . %1j%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(K)(.*?)$
RewriteRule . %1k%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(L)(.*?)$
RewriteRule . %1l%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(M)(.*?)$
RewriteRule . %1m%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(N|Ñ|ñ)(.*?)$
RewriteRule . %1n%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(O|Ó|ó|Ô|ô|Œ|œ|Ò|ò|Ø|ø|Õ|õ|Ö|ö)(.*?)$
RewriteRule . %1o%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(P|ß|Þ|þ)(.*?)$
RewriteRule . %1p%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(Q)(.*?)$
RewriteRule . %1q%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(R)(.*?)$
RewriteRule . %1r%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(S)(.*?)$
RewriteRule . %1s3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(T)(.*?)$
RewriteRule . %1t%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(U|Ú|ú|Û|û|Ù|ù|Ü|ü)(.*?)$
RewriteRule . %1u%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(V)(.*?)$
RewriteRule . %1v%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(W)(.*?)$
RewriteRule . %1w%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(X)(.*?)$
RewriteRule . %1x%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(Y|Ý|ý|Ÿ|ÿ)(.*?)$
RewriteRule . %1y%3 [R=301,L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(Z)(.*?)$
RewriteRule . %1z%3 [R=301,L]
How can I improve or make this code shorter whitout using RewriteMap
or mod_speling
as suggested in this reference: http://www.askapache.com/htaccess/rewrite-uppercase-lowercase.html
UPDATE ANSWER According to Samurai8's answer I have set an environment variable in order to prepare all changes first and redirect at the end. Here is the htaccess
save as UTF-8
:
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(A|Á|á|Â|â|Æ|æ|À|à|Å|å|Ã|ã|Ä|ä)(.*)$ $1a$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(B)(.*)$ $1b$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(C|Ç|ç)(.*)$ $1c$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(C|Ç|ç)(.*)$ $1c$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(D)(.*)$ $1d$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(E|É|é|Ê|ê|È|è|Ð|ð|Ë|ë)(.*)$ $1e$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(F)(.*)$ $1f$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(G)(.*)$ $1g$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(H)(.*)$ $1h$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(I|Í|í|Î|î|Ì|ì|Ï|ï)(.*)$ $1i$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(J)(.*)$ $1j$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(K)(.*)$ $1k$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(L)(.*)$ $1l$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(M)(.*)$ $1m$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(N|Ñ|ñ)(.*)$ $1n$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(O|Ó|ó|Ô|ô|Œ|œ|Ò|ò|Ø|ø|Õ|õ|Ö|ö)(.*)$ $1o$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(P|ß|Þ|þ)(.*)$ $1p$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(Q)(.*)$ $1q$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(R)(.*)$ $1r$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(S)(.*)$ $1s$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(T)(.*)$ $1t$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(U|Ú|ú|Û|û|Ù|ù|Ü|ü)(.*)$ $1u$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(V)(.*)$ $1v$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(W)(.*)$ $1w$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(X)(.*)$ $1x$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(Y)(.*)$ $1y$3 [E=Redirect:1,N,R=301]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(Z)(.*)$ $1z$3 [E=Redirect:1,N,R=301]
RewriteCond %{ENV:Redirect} =1
RewriteRule ^ - [R,L,E=!Redirect]
HELPFUL REFERENCES
The way I got it to work is by saving the .htaccess
file as utf-8. An explanation on how to do that can be found here for vim. If you use an other editor, you'll need to search a bit. If the .htaccess
file isn't saved as an utf-8 file, but as an ascii file instead, the RewriteRules will leave 'strange characters'. localhost/à
would be rewritten to localhost/a¡
for example. I can only guess the reason for that, but I assume this is because Apache assumes strings to have an other character encoding than they actually have.
If everything works as expected, you can change [R]
to [R=301]
to make the redirect permanent. Permanent redirects are cached by the browser, reducing the load on the server for future requests, but they mess up rewrites if you are still testing, because an old rewrite could be cached.
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(Á|á|Â|â|Æ|æ|À|à|Å|å|Ã|ã|Ä|ä|A)(.*)$ $1a$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(B)(.*)$ $1b$3 [E=Redirect:1,N,R]
#etc...
RewriteCond %{ENV:Redirect} =1
RewriteRule ^ - [R,L,E=!Redirect]
I've been trying to get this to work on a Bitnami installation of WordPress, which requires I put any changes to the htaccess files in a file called htaccess.conf. But when I do that, I get these Apache errors (this example is trying to switch out the letter i with an accent and replace it with a plain i):
[Wed Sep 26 16:15:47.786531 2018] [rewrite:error] [pid 11074:tid 140324793952000] [client 51.9.252.217:51184] RewriteRule '^(.)(\xc3\xad)(.)$' and URI '/blah/blah/Br\xc3\xadd Hehir' exceeded maximum length (16380)
The full code I'm putting in the conf file is:
<Directory "/opt/bitnami/apps/wordpress/htdocs/">
# BEGIN special characters
# RewriteCond %{REQUEST_METHOD} !=POST
# RewriteRule ^(.*)(‑)(.*)$ $1-$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(')(.*)$ $1$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(á)(.*)$ $1a$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(é)(.*)$ $1e$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(í)(.*)$ $1i$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(ø|ó|ö)(.*)$ $1o$3 [E=Redirect:1,N,R]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteRule ^(.*)(ü)(.*)$ $1u$3 [E=Redirect:1,N,R]
RewriteCond %{ENV:Redirect} =1
RewriteRule ^ - [R,L,E=!Redirect]
# END special characters
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Wordfence WAF
<Files ".user.ini">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</Files>
# END Wordfence WAF
</Directory>
When I run this solution on another web server in .htaccess as normal, it's fine. Can anybody help? I can't change the Bitnami setup unfortunately...
Thanks!