Reputation: 385
I'm going to implement a "pretty rewrite" redirect solution through htaccess and mod_rewrite. What I want to achieve is the following:
example.com/test123 --> example.com/page.php?c=test123
This is easily done with a single RewriteRule
:
RewriteRule ^(.*) page.php?c=$1 [L,NC]
But I want to exclude some urls:
/
(I've got a specific index.php that I don't want to be rewritten)css/(.*)
images/(.*)
CMS/(.*)
js/(.*)
contact/(.*)
prijslijst/(.*)
werk/(.*)
I've tried some regex, but so far with no avail. I would like some help to make sure that the listed directories do not get rewritten, but any other keyword is rewritten.
Some things I've tried:
The following excerpts cancel any rewriting:
The first one:
RewriteCond %{QUERY_STRING} "^!prijslijst/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!werk/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!js/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!css/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!CMS/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!images/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "^!contact/{0,1}(.*)"
RewriteRule ^(.*) page.php?c=$1 [L,NC]
The second one:
RewriteCond %{QUERY_STRING} "^!(prijslijst|werk|js|css|CMS|images|contact)/{0,1}(.*)"
RewriteRule ^(.*) page.php?c=$1 [L,NC]
The third one:
RewriteRule ^!(prijslijst|werk|js|css|CMS|images|contact)/{0,1}(.*) page.php?c=$1 [L,NC]
A slight adjustment of the top one resulted in everything being rewritten, even the stuff I wanted to exclude:
RewriteCond %{QUERY_STRING} "!prijslijst/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!werk/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!js/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!css/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!CMS/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!images/{0,1}(.*)"
RewriteCond %{QUERY_STRING} "!contact/{0,1}(.*)"
RewriteRule ^(.*) page.php?c=$1 [L,NC]
(^
was removed from the start of every second parameter of RewriteCond
)
EDIT
I've submitted an answer of my own to document the final solution. @ndn's answer was of great influence, it gave me a push in the right direction. Many thanks!
Upvotes: 0
Views: 1647
Reputation: 385
My solution (with thanks to @ndn)
@ndn gave me a starting point to find the right solution. I'd like to thank him for giving me a pointer in the right direction!
In the end, I reduced the amount of RewriteCond
s. Unlike @ndn sugggested, I did not go for a negative regex in the RewriteRule
. I think it gives a better overview to use RewriteCond
s for constraining the rewriting, but it can be done within both RewriteRule
and RewriteCond
, it's a matter of preference.
So what did I end up with? Here it is:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /ut-taertje/
RewriteCond %{REQUEST_URI} !^/ut-taertje/(?:.{0}$|css|CMS|js|images|prijslijst|contact|werk)(?:$|/.*)?$
RewriteCond %{REQUEST_URI} !^/ut-taertje/(?:page\.php|index\.php)$
RewriteRule ^(.*)$ page.php?c=$1 [L,NC]
</IfModule>
I'll explain it shortly. I did not include the RewriteBase
in the question, but given the fact it plays a part in the RewriteCond
, it would clarify it better. Replace the subdirectory /ut-taertje/
with /
to make it apply to the root.
So I put my rewriting constraints into two RewriteCond
s. The upper one is a regex group to exclude the various directories I wanted to exclude. Note that the group includes .{0}$
, as it should also exclude the root of the directory itself, which does not have anything after the leading /
of the request URI. Next to that, I have a second regex group ((?:$|/.*)?
) which enables me to exclude not only the directories themselves, but also anything that comes after the slash (not only js/
, but also js/codebase.js
or js/jquery/
).
The second RewriteCond
is to exclude an edge case. When testing, I used 301
redirects, rather than "invisible" redirects. It appeared that rewriting to page.php?c=<the original request URI>
triggered an infinite loop of redirect requests from the server. Why? Because it was not part of the exclusion from the first RewriteCond
!
So that's it. The RewriteRule
is rather simple, it rewrites anything that passes the conditional filters from both RewriteCond
s.
Upvotes: 0
Reputation: 36110
RewriteRule ^(?!/$|css/|images/|CMS/|js/|contact/|prijslijst/|werk/)(.*) page.php?c=$1 [L,NC]
Basically, I just took your original rewrite and added negative lookahead for the list of things you wanted skipped (?!/$|css/|images/|CMS/|js/|contact/|prijslijst/|werk/)
.
Upvotes: 3