views:

118

answers:

2

I've come across a bug in my site: basically, it won't allow page names with full stops (periods) in them. I know the root of the problem is in my .htaccess file.

RewriteEngine on
RewriteRule ^([^/\.]+)/?$ index.php?section=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?section=$1&page=$2 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ index.php?section=$1&page=$2&split=$3 [L]

Here the regex will not match anything with a period, this is intentional if a user is trying to directly access a file.

Here are some examples of common URLs.

games/Spider:+The+Secret+of+Bryce+Manor
games/Orbital
features/Interviewed:+Dennis+Sijnen+from+No+Monkeys
news/all/4

The split portion of the URL is usually only used for pagination. The page portion of the URL is where I would want to place full stops, for example:

games/Must.Eat.Birds

As I'm not particularly good at either mod rewrite or regex I'd just like a solution that allows full stops. I know it could potentially be a more complex regex and here I'm out of my depth.

Thanks for any help.

+2  A: 

Replace every [^/\.] with [^/] -- that way they will match everything that is not a '/' instead of everything that is not a '/' and not a '.'

If you don't want to allow dots at certain positions just don't change the old regex at those locations.

Simon Groenewolt
Thanks, I got it working. :-)
different
+2  A: 

Simons response will solve your problem, just replace the "page" portion with [^/] instead of [^/\.] which btw, you don't need to escape periods in sets.

A little bit of mod_rewrite magic you may be interested in based on the text of your question: This portion of rewrite will match any real files, links, or directories in your DocumentRoot - if this happens first, it wont match your later rules - therefore ensuring /css/main.css goes to the real file. Then anything else gets rewritten and dumped into index.php.

# -s = File Exists
RewriteCond %{REQUEST_FILENAME} -s [OR]
# -l = Is a SymLink
RewriteCond %{REQUEST_FILENAME} -l [OR]
# -d = Is a Directory
RewriteCond %{REQUEST_FILENAME} -d
# if we match any of the above conditions - serve the file.
RewriteRule ^.*$ - [NC,L]

# adding your rules with the slight modifications pointed out above and by simon.
# only allows '.' in the "page" portion.
RewriteRule ^([^/.]+)/?$ index.php?section=$1 [L]
RewriteRule ^([^/.]+)/([^/]+)/?$ index.php?section=$1&page=$2 [L]
RewriteRule ^([^/.]+)/([^/]+)/([^/.]+)/?$ index.php?section=$1&page=$2&split=$3 [L]
gnarf
Indeed, Simon's answer doesn't take into account real files, which was one of my concerns in the first place. Thanks very much. :-)
different
dosen't `[^/.]` mean "match all characters that aren't '/' or *any character (.)*?
Eric
The `.` in a set (`[]`) is just a `.`, test for yourself
gnarf