homepage Welcome to WebmasterWorld Guest from 54.196.198.213
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe and Support WebmasterWorld
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Redirect all requests to public folder
MVC pattern
migthegreek




msg:4189717
 11:50 am on Aug 20, 2010 (gmt 0)

I'm having trouble writing the htaccess rewrite rules for an MVC pattern, so that all requests get redirected to a public folder.

http://www.example.com should go to http://www.example.com/public/index.php

http://www.example.com/mypage should go to
http://www.example.com/public/index.php?url=mypage

And requests for images, JS, CSS, etc. should be like:

http://www.example.com/css/stylesheet.css but really goes to http://www.example.com/public/css/stylesheet.css

Can someone please suggest appropriate rules for this? I'm getting infinite redirects mainly. Alternatively, I am interested to hear best practices on this kind of redirecting for MVC.

 

jdMorgan




msg:4189738
 12:29 pm on Aug 20, 2010 (gmt 0)

What have you tried so far?

The only difficulty here is to exclude the target path "/public/" so that requests, once rewritten to that subdirectory, don't get rewritten again, causing a loop. A negative-match RewriteCond testing a back-reference to the RewriteRule pattern or %{REQUEST_URI} would do nicely.

Please post your best-effort code as a basis for discussion.

Also, to avoid confusion among our diverse readers, it would be helpful to know with some certainty what you mean by "MVC."

Thanks,
Jim

migthegreek




msg:4189784
 2:08 pm on Aug 20, 2010 (gmt 0)

Thanks JD.

Well the important parts of my application structure is as follows:

- application
------ config
------ controllers
------ models
------ views
- library
- public
------ css
------ img
------ js
------ index.php
- .htaccess file


All publically viewable files are stored in the /public/ directory, and only these files should be accessible through the browser. All requests for pages therefore need to get directed to /public/index.php?url=REQUEST_URI in the background (although the user doesn't see their URL change).

Obviously I need to include images, JS and CSS in my templates by http://www.example.com/img/picture.png, and another thing is that I need any original query string to be preserved and sent over to the rewritten URL as well.

Something like this?

RewriteCond %{REQUEST_URI} !public/
RewriteRule ^(.*)$ public/index.php?url=$1 [R,L]


But I don't know what to add as a RewriteCond really. If I go to the site, this is what I get (on shared hosting btw):

http://www.example.com/path/to/myaccount/web/public/index.php?url=path/to/myaccount/web/public/index.php

Not sure why it's writing the entire server path in.

jdMorgan




msg:4189943
 6:24 pm on Aug 20, 2010 (gmt 0)

It is redirecting (asking the browser to change its address bar and make a new HTTP request) because you explicitly specified an external URL-to-URL redirect.

It is inserting the full filepath because a rule executed previous to this one has already rewritten the URL to a filepath, and you did not use an [L] flag on that rule. If you ever allow more than one rule to match a request, this is the result.

The rule itself should look like this:

# Internally rewrite all requested URLs to /public filepath unless already done
RewriteCond $1 !^public/
RewriteRule ^(.*)$ public/index.php?url=$1 [L]

You must insert this rule after all external redirect RewriteRules, and before any less-specific "catch-all" internal RewriteRules. You must not use mod_alias "Redirect" or "RedirectMatch" directives along with your RewriteRules -- if you use mod_rewrite for anything, use it for everything.

See the concurrent thread "Proper Order for htaccess [webmasterworld.com]", also in this forum for a lot more info on this subject. This will help you avoid some potentially-very-serious self-inflicted problems.

Jim

migthegreek




msg:4191352
 9:56 am on Aug 24, 2010 (gmt 0)

Ah, thank you so much. I really appreciate the help, and thanks for the link.

migthegreek




msg:4192226
 11:03 pm on Aug 25, 2010 (gmt 0)

OK, I have a follow-up question. I cannot get any of my CSS, JS or images to link in my HTML.

The paths in the HTML are like this:

http://www.example.com/css/global.css

But none of these links are being found. I need to modify the original rewrite so that requests for CSS/images/JS are simply forwarded to the public folder, but requests for anything else are rewritten to public/index.php?url=$1 as above.

Thanks.

migthegreek




msg:4192426
 9:13 am on Aug 26, 2010 (gmt 0)

OK, nevermind. Once again the mysterious htaccess caching problems I've been experiencing seem to have randomly made up their mind.

[webmasterworld.com ]

jdMorgan




msg:4192516
 1:57 pm on Aug 26, 2010 (gmt 0)

I doubt that it was the caching problem making the code "not work." Rather, I think it's possible that the caching problem may be making the code appear to work, when in fact, it's still not right.

Exclude the paths you don't want rewritten to the script, either by directory-path or by filetype (this is your choice depending on which one will be easier for you to maintain).

# Internally rewrite all requested URLs to /public filepath unless already done
# Exclude by directory-path
RewriteCond $1 !^(public|images|css|js)/
# Exclude by filetype (optional)
RewriteCond $1 !\.(gif|jpe?g|png|bmp|ico|css|js)$
RewriteRule ^(.*)$ public/index.php?url=$1 [L]

Jim

migthegreek




msg:4211499
 9:15 am on Oct 5, 2010 (gmt 0)

Hi Jim,

On the last rule you posted, are you sure that will work? I have a feeling it might need two separate rules. If we use an example (and refer to the directory structure in the third post of this thread):

http://www.example.com/mypage

Should be rewritten to:

http://www.example.com/public/index.php?url=mypage

But for images, CSS, JS, etc:

http://www.example.com/css/global.css

Should be rewritten to:

http://www.example.com/public/css/global.css


Finally, I wanted to modify the original rule to keep any original query string parameters and add them to the rewritten one:

http://www.example.com/mypage?id=235&action=edit

Should be rewritten to:

http://www.example.com/public/index.php?url=mypage&id=235&action=edit

Is this possible?

Thanks in advance.

jdMorgan




msg:4211589
 12:21 pm on Oct 5, 2010 (gmt 0)

Having figured out that you need two rules, it will likely be faster to code it up and test it than to ask here and wait for a response.

Rewrite the requests that need to be passed to your script first (with the rule discussed so far in this thread), then follow that rule with a more-general rule that rewrites "everything else" to insert the "/public" path, remembering to include the RewriteCond for "loop prevention."

Jim

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved