htaccess: Rewrite - but keep site resources? - .htaccess

I know this is likely a question that is being asked often, I've searched for answers but couldn't come up with anything that answers my case. I'm assuming it's because I'm not figuring out the correct search terms, so I'm sorry If this is redundant... Thank you for your time!
I use .htaccess to rewrite my URLs to a more user friendly format. That's really all I want to do so if there's an entirely better way to do it, I'd be grateful to learn!
Anyway; I rewrite localhost/room/2 to index.php?p=room&id=2. That works like a charm.
RewriteRule ^room/([0-9]*)$ /index.php?p=room&id=$1 [L]
You can probably already tell my problem: I'm creating a virtual folder using room/room_number. So when I - for example - include a picture using an IMG-Tag, that src-Attribute is being rewritten as well to fit the working directory the server assumes to be in. Instead of requesting
localhost/img/image.jpg
It requests
localhost/room/img/image.jpg
which obviously isn't the right location. So my question is; How do I rewrite the URL to something nice and user friendly while simoultaneously re-REdirecting the page's resources to their original path?

Use paths relative to the root directory by prepending the paths with a leading slash:
<img src="/img/image.jpg" />

Another (and fairly standard) solution to this problem is to add a RewriteCond so that the rule is never applied when a resource is requested that really exists.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^room/([0-9]*)$ /index.php?p=room&id=$1 [L]

Related

.htaccess redirect whole website structure but leave some of the old structure intact

I have searched but can't quite find the answer to this exact situation:
My website structure is as follows
www.example.co.uk/old-folder1/old-folder2/old-page-name
I needed to redirect the whole structure to:
www.example.co.uk/new-folder1/old-folder2/old-page-name
I successfully did this with:
RewriteRule ^old-folder1/(.*)$ /new-folder1/$1 [R=302,L]
However, if possible for the moment I still want to serve images from the old structure ie.
www.example.co.uk/old-folder1/old-images-folder/old-image.jpg
At the moment the above is being rewritten as:
www.example.co.uk/new-folder1/old-images-folder/old-image.jpg
Which makes sense but this leads me to my question, is there any way of excluding some of the sub directories in 'old-folder1' from the RewriteRule above so that for example www.example.co.uk/old-folder1/old-images-folder/old-image.jpg is still accessible?
I don't have much experience with this but from research I came up with the following but it doesn't work.
RewriteCond %{REQUEST_URI} !^/old-folder1/old-images-folder/.*$
I am beginning to think this might not even be possible with the approach I have taken with:
RewriteRule ^old-folder1/(.*)$ /new-folder1/$1 [R=302,L]
Thanks
Entire contents of the .htaccess file at the moment is:
Options +SymLinksIfOwnerMatch
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/old-folder1/old-images-folder/.*$
RewriteRule ^old-folder1/(.*)$ /new-folder1/$1 [R=302,L]
Try:
RewriteRule ^old-folder1/(?!old-images-folder)(.*)$ /new-folder1/$1 [R=302,L]
HOwever, what's probably happening is that your images are linked using relative URLs, so they may be relatively linked to the "new" images folder.
You should check your links and make sure they're linked correctly to the old path.

.htaccess - mod_rewrite condition for a filepath with a wildcard folder in the middle?

I essentially want to be able to go through folders within a certain folder and look for a match. I think an example is the easiest way to explain it:
I want to be able to access a file at domain.com/css/style.css
Or even domain.com/[modulename]/css/style.css (which might help keep things more organized, now that I think of it)
But the file is in /application/modules/[modulename]/public/css/style.css and the [modulename] is potentially different each time.
I have RewriteCond %{DOCUMENT_ROOT}/application/modules/$1 -f but that won't work unless I use the url /[modulename]/public/css/style.css - how could I make it look for a wildcard in the middle of the path?
Edit: On second thought, it would have to be domain.com[modulename]/css/style.css because there might be more than one style.css in the entire site.
After working on it for five hours today, I got it working:
RewriteCond %{REQUEST_URI} !^/application/modules/
RewriteRule ^([a-zA-Z0-9\-]+)/(.*)$ /application/modules/$1/public/$2
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}%{REQUEST_FILENAME} [NC,L]

.htaccess RewriteRule not redirecting from real folder

I'm still a bit fuzzy on the working of .htaccess, and I've looked around but I can't find anything to help this specific issue.
EDIT: I realize there are other questions that seem like they cover this issue, but I checked some and they didn't seem to offer any help I could understand, and I didn't want to hijack them with my own issues.
This is what I have:
Options +FollowSymLinks
#RewriteBase /
RewriteEngine on
RewriteRule /mp3/(.*) http://old.domain.com/mp3/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
As you can see from the last line, the string typed after the server name is actually a URL parameter and depending on that parameter, different content is pulled from the database and that page is displayed on the site.
The problem I'm having is that the client has a content page called "podcast", so they would go to site.com/podcast which should quietly redirect to site.com/index.php?=podcast and load the content for that page. Unfortunately, the client also has a real site.com/podcast/ folder on their server. Because of this, the rewrite is ignored and the browser attempts to load that folder. It either shows a file listing or a forbidden error if I disable the listing.
After some research (I'm still new to htaccess), I learned that the two lines prior disable the rewrite if the path points to an actual file or folder. Unfortunately, commenting out the one with !-d doesn't seem to have any effect, and commenting out both gives me a server error.
Admittedly, part of the problem here was lack of foresight. URL rewrites should have been planned before everything else was put together, but it wasn't until the site was basically completed that I was notified that the client wants "Friendly URLs" that don't include the ?p= part. Regardless, perhaps there is a way to fix this.
Is there some .htaccess trickery I can use that will force the rewrite even if the URL entered points to a folder (not a specific file) that actually exists? As stated before, removing the !-d doesn't seem to help, although I'm not sure why. Perhaps I misunderstand its purpose.
Thank you for any help, and please be lenient with me if I overlooked something obvious. This is an issue presenting itself on the client's live site right now so I feel a little rushed in solving it. Thanks again.
OH YEAH, and the solution can't be specific to /podcast. The way the client's site is set up, when they want to create a new subpage for the site, a new name is saved for that content based on their title for the page and it is possible (unlikely, but still possible) that another page can be created with a name that matches an existing folder on the server.
Here is a note from mod_rewrite documentation:
By default, mod_rewrite will ignore URLs that map to a directory on
disk but lack a trailing slash, in the expectation that the mod_dir
module will issue the client with a redirect to the canonical URL with
a trailing slash.
This explains why mod_rewrite ignores the URL /podcast. I would suggest that you rename physical directories so that do do not (accidentally) match article names.
Another option would be to disable the DirectorySlash setting. This will prevent Apache from redirecting /podcast to /podcast/.
DirectorySlash Off
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
Be warned that disabling this setting has side effects. Read through the documentation first.
Change the following line of code:
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
to
RewriteRule ^(podcast([^?]*)) index.php?p=$1 [L,NC]

How to redirect using .htaccess using Apache?

Please help me to redirect using .htaccess like below.
http://info.domainname.com/blog/?Tag=somedynamictag
to
http://domainname.com/tag/somedynamictag
Thanks!
First of all I don't understand the purpose of rewriting http://info.domainname.com/blog/?Tag=somedynamictag to http://domainname.com/tag/somedynamictag when it had to be the other way round. People rewrite URLs to clean them (ie. remove characters like ?,&,=, etc.) but you are adding all these and making the URLs cumbersome.
I think you didn't properly understand the concept of URL rewriting. Let me explain a little.
When any URL is accessed on your website, the URL that the USER types or clicks (in your case http://domainname.com/tag/somedynamictag) is rewritten. But your question tells me that you think the other way. Your understanding is that the visitor clicks http://info.domainname.com/blog/?Tag=somedynamictag and will be rewritten to http://domainname.com/tag/somedynamictag. THIS IS WRONG!!. If you set up your website this way, each and every URL at http://domain.com/ must exist as a separate file or directory which a dynamic website like you seem to be developing is not expected to have. So I assume you have understood that you have either misformed the question or you have you have misunderstood the concept of URL rewriting. Following is the .htaccess code to redirect http://domainname.com/tag/somedynamictag to http://info.domainname.com/blog/?Tag=somedynamictag.
RewriteEngine On
RewriteCond %{HTTP_HOST} domainname.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9]+)\/(.*)$ http://info.domainname.com/blog/?$1=$2 [L,R=301]
If you think you have correctly typed the question and understood url-rewriting right and are sure what you are trying to do is right, then here's the htaccess code (if you want to redirect http://info.domainname.com/blog/?Tag=somedynamictag to http://domainname.com/tag/somedynamictag).
RewriteEngine On
RewriteCond %{HTTP_HOST} info.domainname.com
RewriteRule ^blog\/\?([A-Za-z0-9]+)=(.*)$ http://domainname.com/$1/$2 [L,R=301]
If that doesn't work, in index.php at http://info.domainname.com/blog/, place the following code:
<?php
header("HTTP/1.1 301 moved permanently");
header("Location:http://domainname.com/blog/tag/".$_GET['Tag']);
?>
And thank you for asking this question. While answering it, I learned many things.
Hope that answers your question,
Peace...

Rewrite css/js paths

So I rewrote my paths to something like: URL/really/nice/paths/ using mod_rewrite rules like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
The question is how could I rewrite the paths for js/css/image files too, so when they are requested with a relative path from URL/really/nice/path/ to be served from URL/scripts/, URL/styles/ and URL/images/ folders instead? Can this be done without using RewriteBase?
When URLs are rewritten, the client doesn't know it. So when a client looks at a page at the URL "example.com/some/url/" and the page references an image in "images/image.jpg", the client looks for the image in "example.com/some/url/images/image.jpg" even though the page actually resides in "example.com/some/other/url/". That's the problem you're facing, right?
There are three main solutions to this problem:
Use absolute paths to resources instead of relative ones.
Use the <base> tag to ensure that the client knows the root upon which to build its relative URLs is different from the page's apparent URL.
Add a new rule for "some/url/images/" in your rewrite rules.
Option 1 is probably the best idea, and you'll find that most sites that use URL rewriting use it, including Stack Overflow itself. Option 2 is frowned upon, but works and is relatively easy. Option 3 is the most difficult to maintain, as URL rewriting exceptions and special cases can appear as you're defining new rules.
The most maintainable solution is to use absolute URLs.

Resources