Forum Moderators: phranque
RewriteCond $1 ^(Digest¦Updates).*
RewriteRule ^(.*) index.php/$1
to rewrite www.domain.com/Digest/<anything> to www.domain.com/index.php/Digest/<anything> and www.domain.com/Updates/<anything> to www.domain.com/index.php/Updates/<anything>.
So far, so good. However, I need to do the same kind of rewriting in several subdirectories. For example, www.domain.com/Dir/News/<anything> to www.domain.com/Dir/index.php/News/<anything>.
I am able to solve this by placing an additional .htaccess file in said subdirectory and using the same code as above with Digest and Updates replaced with News. However, I would prefer it if I could just use a single .htaccess by adding a separate rewrite condition and rule pair for each subdirectory that needs it.
So, my question is: is this possible, and how would I configure the rewrite if so? How could I change
RewriteCond $1 ^(News).*
RewriteRule ^(.*) index.php/$1
to get it to turn www.domain.com/Dir/News/<anything> to www.domain.com/Dir/index.php/News/<anything> while the rule is found in the .htaccess stored under root, not under /Dir/?
You could rewrite that to either
RewriteRule ^((Digest¦Updates)/.*)$ /index.php/$1 [L]
RewriteCond %{REQUEST_URI} ^Digest [OR]
RewriteCond %{REQUEST_URI} ^Updates
RewriteRule (.*) /index.php/$1 [L]
RewriteCond %{REQUEST_URI} ^(Digest¦Updates)
RewriteRule (.*) /index.php/$1 [L]
RewriteCond %{REQUEST_URI} ^Dir/News [OR]
RewriteCond %{REQUEST_URI} ^Dir/Digest [OR]
RewriteCond %{REQUEST_URI} ^OtherDir/Updates
RewriteRule ^([^/]+)/([^/]+.*)$ /$1/index.php/$2 [L]
Note that the last RewriteCond in an [OR]ed list *must not* have an [OR] appended. Note also that you must edit the broken pipe characters and replace them with solid pipes before use - posting on this board modifies them.
Hopefully this answers your question, as there are many "dimensions" to these problems. If you have many, many subdirectories and subcategories you may want to use multiple RewriteRules to first rewrite the subdirectories, and then rewrite the categories. Doing it in two steps can simplify things by eliminating redundant subdirectory tests. But this may not apply to your case; Sometimes the directory architecture of a site heavliy influences the most efficient way to do rewrites in it.
There are some references cited at the end of our forum [url=RewriteCond $1 ^(Digest¦Updates).*
RewriteRule ^(.*) index.php/$1]charter[/url] that might come in handy, too.
Jim
First, I should perhaps clarify my situation further. The 'directories' being rewritten are actually virtual rather than physical directories, part of the URL structure of the software I use for dynamic content on my site. But since I also use static content, I needed to be able to only rewrite the virtual directories. Hence the need for very specific rules.
So ... lets say I have:
1) www.domain.com/Updates/* which needs to become www.domain.com/index.php/Updates/*
2) www.domain.com/Dir1/News/* which needs to become www.domain.com/Dir1/index.php/News/*
3) www.domain.com/Dir2/Announcements/* which needs to become www.domain.com/Dir2/index.php/Announcements/*
And so on. There are, perhaps, 10 or so virtual directories that need this kind of rewriting, a few located right under root and the rest located in two different subdirectories.
Would this then be the best approach, using a specific condition for each virtual directory?
RewriteCond %{REQUEST_URI} ^Updates [OR]
RewriteCond %{REQUEST_URI} ^Dir1/News [OR]
RewriteCond %{REQUEST_URI} ^Dir2/Announcements [OR]
RewriteRule ^([^/]+)/([^/]+.*)$ /$1/index.php/$2 [L]
I can't say "best," but it would probably be the simplest. Simple is good.
Please note my warning about not appending an [OR] to the final RewriteCond in msg#2. This will cause unexpected problems.
Also, you may need to add another RewriteCond to prevent a rewrite loop:
RewriteCond %{REQUEST_URI} !index\.php
Please review the references cited in our charter. Using mod_rewrite without a good understanding of it can be quite dangerous to the health of your site. There are two parts, mod_rewrite itself, and the regular expressions used in mod_rewrite patterns. While both may seem daunting at first, having your own rules and test results at hand as examples will make them progressively clearer.
With the provisos above, I think what you have will work, but there's no substitute for testing.
Jim
RewriteCond %{REQUEST_URI} ^Digest [OR]
RewriteCond %{REQUEST_URI} ^Updates [OR]
RewriteCond %{REQUEST_URI} ^BoD/Announcements [OR]
RewriteCond %{REQUEST_URI} ^BoD/Events [OR]
RewriteCond %{REQUEST_URI} ^BoD/Logs [OR]
RewriteCond %{REQUEST_URI} ^RR/News [OR]
RewriteRule ^([^/]+)/([^/]+.*)$ /$1/index.php/$2 [L]
If I add the RewriteCond %{REQUEST_URI}!index\.php line at the top, then it results in a 404.
I noticed that the documents you suggested that I read talk about Apache 1.3. My host runs Apache 2.0.40, could this be causing the problem?
[edited by: Linda_A at 7:27 pm (utc) on Sep. 7, 2004]
RewriteCond %{REQUEST_URI} ^/Digest [OR]
RewriteCond %{REQUEST_URI} ^/Updates [OR]
RewriteCond %{REQUEST_URI} ^/BoD/Announcements [OR]
RewriteCond %{REQUEST_URI} ^/BoD/Events [OR]
RewriteCond %{REQUEST_URI} ^/BoD/Logs [OR]
RewriteCond %{REQUEST_URI} ^/RR/News
RewriteRule ^([^/]+)/([^/]+.*)$ /$1/index.php/$2 [L]
Doesn't seem to do the trick either, unless I am making another mistake somewhere. If I include RewriteCond %{REQUEST_URI}!index\.php (not sure if that one has to start with a / too, but I tried both with and without it, with no difference) I get 404s, without it I get internal server errors.
Maybe it is my other rewrite rules (the standard setup for protecting graphics from hotlinking) that are conflicting? However, from what I had understood, once you reach a RewriteRule, it stops there, and you should be able to add another?
So the subdirectories are solved, but not those located right under root.
[edited by: jdMorgan at 10:30 pm (utc) on Oct. 5, 2005]
[edit reason] Examplified. [/edit]
# Rewrite subdirectory requests
RewriteCond %{REQUEST_URI} ^/BoD/Announcements [OR]
RewriteCond %{REQUEST_URI} ^/BoD/Events [OR]
RewriteCond %{REQUEST_URI} ^/BoD/Logs [OR]
RewriteCond %{REQUEST_URI} ^/RR/News
RewriteRule ^([^/]+)/([^/]+.*)$ /$1/index.php/$2 [L]
#
# Rewrite root directory requests
RewriteCond %{REQUEST_URI} !index\.php
RewriteCond %{REQUEST_URI} ^/Digest [OR]
RewriteCond %{REQUEST_URI} ^/Updates
RewriteRule ^([^/]+)$ /index.php/$1 [L]
Should, btw, it be RewriteCond %{REQUEST_URI}!index\.php or RewriteCond %{REQUEST_URI}!/index\.php? And is it correct to use that only for the rewrite for the root directories?
Again, thank you. :)
Yes and yes. There are a couple of ways to do it, but the point is to identify index.php no matter what subdirectory it may be requested in, and to avoid rewriting index.php to index.php, creating an "infinite loop."
For this reason, I omitted the start anchor "^" on the index.php pattern as well.
Jim