Remove numbers from url with mod_rewrite - apache

I have just migrated a site from Joomla to WordPress, everything works, but I need a rule to remove date+time block from url.
Old URLs were like this
domain.tld/201009081045/category/subcategory/article.html
I have removed .html part with this:
#BEGIN sjebani linkovi fix
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
#301 da izbaci html
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
RewriteRule ^(.*)\.html$ /$1 [R=301,L]
#END sjebani linkovi fix
And I tried removing the first number block with this:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /^[0-9]{6-13}$ /$1 [R=301,L]
My logic is to find string that has only numbers is longer than 6 chars and shorter than 13, because I need date archives active (domain.tld/2008/12/01, etc...).
How can I remove first number block with mod_rewrite?

Your regex is a little wonky and you need to match everything that's after the date in order for your $1 backreference to work:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[0-9]{6,13}/(.*)$ /$1 [R=301,L]

Related

.htaccess rewrite to add country code (if missing)

I am using a .htaccess file in the subdirectory /cms and using this subdirectory as RewriteBase. The redirections go to 'backend.php' and send the variables I want. It is a dual language site (nl|en), dutch and english. Everything works fine, as long as the %{REQUEST_URI} starts with (nl|en).
But I need a fallback to the default dutch language when nl|en is omitted, but can I add this to the following .htacces file. I have been trying and searching but cannot find the right syntax to make this happen:
RewriteEngine On
RewriteBase /cms/
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteCond %{REQUEST_URI} !(^(nl|en)/)
#RewriteRule (.*) This is where the solution should be used ?
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !\.[a-zA-Z]{2,4}$
RewriteRule ^(nl|en)/([^/]+)/$ backend.php?page=$2&language=$1 [QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !\.[a-zA-Z]{2,4}$
RewriteRule (nl|en)(.*)/(\d+)/$ backend.php?page=$2&id=$3&language=$1 [QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !\.[a-zA-Z]{2,4}$
RewriteRule (nl|en)(.*)/(\d+)/(.+)/$ backend.php?page=$2&id=$3&task=$4&language=$1 [QSA,NC,L]
One way to handle this is a rewrite with the dutch language prepended. This will silently change direction to the proper page.
RewriteCond %{REQUEST_URI} !^/cms/(?:nl|en)/
RewriteRule ^(.*)$ nl/$1 [L]
If you want the client to notice and change the URL, you must do a R|redirect instead
RewriteCond %{REQUEST_URI} !^/cms/(?:nl|en)/
RewriteRule ^(.*)$ nl/$1 [R,L]
Your default rule can be this one:
# This is where the solution should be used ?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(nl|en)/ [NC]
RewriteRule ^([^/]+)/?$ backend.php?page=$1 [QSA,L]

Apache .htaccess to redirect all URLs except for files and directories

I am developing a web site currently located at a subdomain. In the .htaccess file I have the following:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-zA-Z_\-]+)/?$ /index.php?url=$1 [L,NC]
RewriteRule ^([a-zA-Z_\-]+)/(.+)/?$ /index.php?url=$1&$2 [L,NC]
When I try to load an existing css file e.g. http://subdomain/path/to/existing/file.css Apache still redirects it to index.php. Is it possible to redirect all URLs to index.php except for existing files and directories?
The problem with your code is that the last rule is not conditioned, as you can only have one RewriteRule per condition or set thereof.
There's more than likely a better way to do this (perhaps using the skip flag S), but you can repeat your conditions in the meantime.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-z_-]+)/?$ index.php?url=$1 [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-z_-]+)/(.+)/?$ index.php?url=$1&$2 [L,NC]
Also, and as you have specified the NC flag, you need not specify A-Z in the pattern. Also, no need to escape the hyphen -.
Update: You could also try setting an environment variable, per this answer:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# If the conditions above are true, then set a variable to say so
# and continue.
RewriteRule ^ - [E=TRUE:YES]
RewriteCond %{ENV:TRUE} = YES
RewriteRule ^([a-zA-Z_\-]+)/?$ /index.php?url=$1 [L,NC]
RewriteCond %{ENV:TRUE} = YES
RewriteRule ^([a-zA-Z_\-]+)/(.+)/?$ /index.php?url=$1&$2 [L,NC]

Tricky 301Redirect Rule

I want link to be redirected in a manner such that url with not slash at the end should be redirected to the url with the slash at the end.
example 1:
http://example.com/quiz/funny-riddles-with-answers
should be redirect to
http://example.com/quiz/funny-riddles-with-answers/
example 2
http://example.com/quiz/math-riddles-with-answers
should be redirected to
I have no idea how to do it.
my current screen shot of .htacess is
RewriteEngine On
RewriteBase /quiz/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)?$ mypage.php?param1=$1&param2=$2 [L,QSA]
Try these rules in /quiz/.htaccess:
RewriteEngine On
RewriteBase /quiz/
# add a trailing slash for non-directories
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?[^/])[?\s]
RewriteRule ^ %1/ [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ mypage.php?param1=$1&param2=$2 [L,QSA]
You can easily rewrite to a trailing slash using:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
Place above your already existing rewrites.
You need to change your current rule's pattern to: ^([^/]+)/([^/]+)?/?$
then add this right under RewriteBase /quiz/:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /$1/$2/ [L,R=301]

mod_rewrite rule keeps in loop

I am doing a quite simple rule for mod_rewrite yet I get a loop
Here are the rules:
first if I have a request like
index.php/SOMETHING.(txt,jpg,php)
I need to first check if /SOMETHING.(txt,jpg,png) exists and display it
if the file is not an index.php/SOMETING and is a real path that exists display it
if not...pass it on to the index.php/SOMETHING.(txt,jpg,php) and show index.php
It all works but the last rule if I have a unexistent txt,jpg,php
example : http://domain.com/index.php/robots1.txt
File does not exist: /Applications/XAMPP/xamppfiles/htdocs/testredir/robots1.txt
works for any other extension...
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^index.php/.+$
RewriteRule ^index.php/(.+)\.jpg$ $1.jpg [NC,L]
RewriteRule ^index.php/(.+)\.txt$ $1.txt [NC,L]
RewriteRule ^index.php/(.+)\.php$ $1.php [NC,L]
#here I am missing a rule but if i put the following it will loop
#RewriteCond %{REQUEST_URI} -f
#RewriteRule .* index.php/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^index.php/.+$
RewriteRule .* index.php/$0 [PT]
The %{REQUEST_URI} variable always starts with a /, and you're matching against it using ^index.php/.+$, so that condition will always be false.
It looks like you want something like this:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \ /index\.php/(.+)\.(jpg|txt|php)
RewriteRule ^ /%1.%2 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L,PT]

Order of rules in .htaccess file

I have an .htaccess file like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
but when I go to a URL starting with foo in that folder, the browser still gets redirected to the fallback.cgi script. If I remove the second rule, the 'foo' line works OK.
According to my understanding, the first rule should take precedence, and the [L] should prevent any other rules from happening.
You are right, the 1st rule should be applied first and I think it is. The problem might be the 2nd rule is also being applied, so the code should be like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L,NC]
RewriteCond %{REQUEST_URI} !/cgi/(foo|fallback)\.cgi [NC]
RewriteCond %{REQUEST_URI} !/foo [NC]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
The ^ means beginning of string.
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
So that rules ONLY matches /foo followed by zero or more characters.
To match a file beginning with "foo" use this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^|/)foo.*$ /cgi/foo.cgi [L]
It matches:
/foo
/foo.php
/food.php
/foolish/dog
It does not match:
/kung-foo.cat
/FOO.php
Update
Remember that some browsers do redirect caching. I was testing this on my own server and had performed a redirect that was cached. Made me confused for a bit when my new rules weren't working.
It is applying 2nd rule because;
In 2nd rule your are matching .* (means everything)
RewriteCond lines are only being applied to 1st rule only
Correct code would be:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't do anything for a file, dir or symlnk
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]
RewriteRule (^|/)foo /cgi/foo.cgi [L,NC]
RewriteRule ^ /cgi/fallback.cgi [L]