Forum Moderators: phranque
<http://domain.com/topic> should load the content stored at </domain.com/subdir/topic.html>, but still show <http://domain.com/topic> in the address bar.
And at the same time:
<http://domain.com/subdir/topic.html> should change to <http://domain.com/topic> in the address bar.
The problem is that each directs to the other so there would be a loop. jdMorgan proposed the following solution which worked initially. This is what I have in my </.htaccess> file:
# REWRITE REQUESTS FOR THE SUBDIR
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule subdir/topic\.html [domain.com...] [R=301,L]
# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$http://domain.com/subdir/topic.html [L]
But now when I go to <http://domain.com/subdir/topic.html>, the page loads but the address bar doesn't change.
After a lot of troubleshooting I found that I could get it to work if I removed the secondary htaccess file at </subdir/.htaccess>. Exploring further I discovered that what killed it was having even a single RewriteRule command in that secondary .htaccess file, *even if that command had nothing to do with the request*. For example, this line in the secondary .htaccess file kills the whole deal:
RewriteRule apx [domain.com...] [R=301,L]
Incidentally, the reason I have a second .htaccess file is that I'm trying to improve performance. When I want to run certain rewriting code only for requests to a specific folder, I like to put the .htaccess file in that folder so the rewriting code doesn't have to get evaluated for requests to other directories.
So, the burning question is: Is there any way to get my URL rewriting to work when I have a secondary .htaccess file that contains RewriteRule commands? Thanks for your help.
Also, not sure if this is expected behavior, but if I put [i]RewriteEngine on before RewriteOptions inherit then I get an Internal Server Error. If I leave RewriteEngine on out completely then the RewriteRule in that secondary .htaccess file executes fine, but I still have the original problem with the url not being rewritten to remove /subdir/ from the address bar.
I hope I haven't stumped jdMorgan, because otherwise I don't know who else would be able to figure this one out....
# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$http://domain.com/subdir/topic.html [L]
The proper form for an internal (silent) rewrite is:
# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$ /subdir/topic.html [L]
Jim
I also took out the protocol and domain from my RewriteRules. Same problem: </subdir/topic> does not rewrite to </topic> if </subdir/.htaccess> contains even a single, unrelated Rewrite command.
This is sure crazy.
Primary .hatccess:
# REWRITE REQUESTS FOR THE SUBDIR
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule subdir/topic\.html http://domain.com/topic [R=301,L]
# REWRITE REQUESTS FOR THE SHORTCUT
RewriteRule ^topic$ /subdir/topic.html [L]
Secondary .htaccess:
RewriteEngine on
RewriteOptions inherit
RewriteRule apx http://domain.com/topic2/appendix.html [R=301,L]
You correctly received a 500 error when this was added before, because the rewrite from the original *was* inherited, and the inherited rule caused an external (original request) redirect (matching THE_REQUEST), which was then rewritten in the main .htaccess to the new URL, which was then redirected externally (original request) in the secondary (inherited) rewrite, over and over and over...
The reason your rewrite does not work without inherit, is even though the .htaccess does not specifically mention the location you are redirecting, the secondary .htaccess overrides all previous .htaccess files *unless* the options are set to inherit somewhere, either in a per directory location or at the server root...
Added: So, unless you were to explicitly rewrite the location in the secondary .htaccess, no rewrite will be processed, because the first .htaccess file effectively does not exist, eliminating the original rule.
Hope this helps.
Justin
What do you mean "after you corrected your rule"? Corrected how? What was there to correct? Adding the space? (Like I said, there's always been a space there, it just didn't show up in the post.) Removing the method and domain from the RewriteRule? Your own code includes the method and domain. In any event I removed the method and domain and tried it with RewriteOptions Inherit but I still have the same problem.
About your "Added:" comment, are you saying that it's impossible to get this to work unless I duplicate the Rewrite command in the secondary .htaccess file? Meaning that it works fine as long as the secondary htaccess file contains no Rewrite commands, but as soon as it includes *any* Rewrite command, then I have to duplicate the Rewrite commands from the primary htaccess file?
The above rule is the one I was referring to... In the main .htaccess.
I have to duplicate the Rewrite commands from the primary htaccess file?
You either have to have the options inherit, or duplicate the rules, no other way around it. If the rewrite does not work when there is any information in the secondary .htaccess the option is set to off, IOW will not inherit - If you cannot get the inherit to work, yes, you will have to duplicate (or move) the rule.
Justin
Jim
jdMorgan, I thought that what you're advising is exactly what I'm trying to do, which doesn't work. What is different about what you're suggesting?
After some more tinkering, this seems to work:
In the root .htaccess file
RewriteEngine On
RewriteRule topic$ /subdir/topic.html [L]
In the subdir's .htaccess file
RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule topic\.html /topic [R=301,L]
Is there any reason I shouldn't proceed with this?
The only change I'd make is to use a canonical substitution URL in redirects (not rewrites), and to anchor the patterns where possible:
In the subdir's .htaccess file
RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /subdir/topic\.html
RewriteRule ^topic\.html$ http://%{HTTP_HOST}/topic [R=301,L]
Jim
Because it's documented that way...
Canonical [google.com]; here meaning "the generally-accepted, standard form" for a complete URL.
Jim
When referring to programming, canonical means conforming to well-established patterns or rules. The term is typically used to describe whether or not a programming interface follows the already established standard.
SOURCE: webopedia.com
jdMorgan gave you the plain english answer to his statement - here is another version of what he said: 'to use a [well-established pattern, which follows the already established standard] of substitution URL in redirects (not rewrites), and to anchor the patterns where possible:'
Hope you get everything working.
Justin
Thanks again for your help, both of you.