I have a site with files contained in a /pages/ dir.
I'm trying to hide the /pages/ directory from URLs but still have them in the directory, so basically I am trying to achieve this:
www.example.com/sub/
should load:
www.example.com/pages/sub/
or
www.example.com/sub/file.php
should load:
www.example.com/pages/sub/file.php
-- the aim here is to remove /pages/ from all urls
thanks in advance
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ pages/$1 [QSA,L]
If file or directory doesn't exist, then try in pages folder.
QSA adds url parameters if any (like ?param1=val1¶m2=val2)
Apache Re-write: http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
Learn it.
Live it.
Hate it?
edit: its a first in first evaluated, last in last evaluated process, so be considerate when specifying rules, as even if one is established correctly, a broader, more general one which also meets the same pattern (depending on wildcards) has the chance to usurp the prior ( think CSS declaration squashing, if you're familiar with that )
Related
I have a little mod_rewrite problem and really need some help.
I need to have a second .htaccess file in a subfolder for a project on my domain.
The URL to the project is like:
https://example.com/project-name/
Now I have a query parameter for which I want to create a nice URL with mod_rewrite.
The URL including the parameter looks like this:
https://example.com/project-name/index.php?preset=nameofapreset
And I want it to be:
https://example.com/project-name/nameofapreset
The important thing: The mod_rewrite has to work for the current folder only. Without having any info about the current path, cause I need to use the file in other folders, too.
That's what I thought should work (cause I am using a similar rewrite rule in another project):
RewriteEngine On
RewriteRule ^([a-z])/?$ index.php?preset=$1
But it doesn't. And all my trials fail.
Any ideas how I can make it work?
Thanks!
You can use this rule in /project-name/.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/?$ index.php?preset=$1 [L,QSA]
Working with a website that has a large quantity of hard coded pages. The problem is I've been requested to create duplicates of this site with different logos/contacts/addresses. So my thinking was to create URL with the location in it. This location in URL would then be "read" causing the PHP to make changes to specific details.
So URLs would look like:
www.domain.com/repairs-LOCATION/any file
Where as the actual path on the server would be:
www.domain.com/repairs/any file
Complete novice when it comes to htaccess and regular expressions. Initially I tried this, attaching the location name to a file:
# Rewrite repairs page URLs
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^repairs/([^\.]+)-repairs?$ repairs/index.php?in=$1 [L,NC,QSA]
RewriteRule ^repairs repairs/index.php [L]
But this was restrictive as ALL calls to the repairs folder were redirected to index.php, so thought renaming the folder would be a better way forward as a user would be able to navigate to other files within the directory.
Tried a redirect, but that defeated the object as the location was removed from the URL:
RewriteRule ^repairs-townname/(.*)$ /repairs/$1 [R=301,NC,L]
Lastly tried re-jigging the initial attempt, but with no joy.
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^repairs-([^\.]+)/?$ repairs/?in=$1 [L,NC,QSA]
At the moment though struggling to find a solution.
Any help or pointers greatly appreciated, thanks for your time.
The site I'm building at the moment is made of two main parts: The side which the general public can access, and the admin side which only authorised people can access.
It's built with basic templating such that the different sections are accessed as follow (Using RewriteRules).
Public:
http://localhost/about should be rewritten to http://localhost/index.php?page=about
Admin:
http://localhost/admin/manage-users should be rewritten to http://localhost/admin/index.php?page=manage-users
All URLs only ever have one argument. That is, public will always be localhost/PAGE and admin will always be localhost/admin/PAGE.
At the moment, I have the following .htaccess file:
RewriteEngine on
RewriteRule ^admin/([^/.]+)/?$ /admin/index.php?page=$1 [L,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?page=$1 [L,NC]
This seems to work properly when you construct the URL correctly. For example, if I navigate to localhost/about or localhost/admin/manage-users both pages load correctly. But if I go to localhost/about/blah or localhost/admin/manage-users/blah, the pages load, however the CSS is non-existant. Looking at the developer tools in Chrome, it appears that this is because it's trying to load the CSS file from the directories localhost/about/css/ and localhost/admin/css/ respectively, due to the style sheet being linked to the page with a relative path. (In reality, localhost/css/ is the directory it is actually located in.)
So even though the RedirectRule ignores any extra arguments in the URL, it is trying to load relative paths with respect to the last "directory" provided in the URL.
Is there any way to completely ignore any extra ../.. arguments? Or, even better, trigger a 404 when too many arguments are provided?
UPDATE: I have just discovered that the problem is actually a lot more complex than I previously thought. As my pages only had dummy data to test out the templating files, I didn't notice it until now.
It appears than when you navigate to localhost/admin or localhost/admin/manage-users it is loading from the http://localhost/admin/index.php file, but when you navigate to localhost/admin/manage-users/blah is reverts back to loading the http://localhost/index.php file. This makes me think that there is something I need to change in the RewriteRule, though I have no idea what.
It is better in long term to use absolute path in your css, js, images files rather than a relative one. Which means you have to make sure path of these files start either with http:// or a slash /.
But in order to avoid making changes to your website in-mass you can use these rules to fix your css/js/images links:
RewriteEngine on
# fix CSS/js/images links
RewriteRule (?:^|/)((?:css|js|images)/.+)$ /$1 [L,R=301]
RewriteRule ^admin/([^.]+)/?$ /admin/index.php?page=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /index.php?page=$1 [L,QSA]
Don't forget to replace first rule with your actual css/js/images directories.
You need to either make all of your links absolute URLs (e.g. href="/css/style.css") or add a relative URL base to the header of your page:
<base href="/" />
I have a site where I am trying to implement SEO friendly rewrite with an .htaccess file
My site have the following folder structure:
- root/
- corporativo/
- [more stuff...]
- social/
- [more stuff...]
- index.php
- corporativo.php
- social.php
index.php handles all my sites functionality and routing. I am using GET variable 'cuerpo' to determine the section i.e. for example for social section I am using index.php?cuerpo=social.
One of the problems I found is that having social dir and social.php are conflicting with names and with the rewrite conditions.
Please suggest the right way to handle this situation.
Thank you very much!
Best Regards!
In a .htaccess file, before rewrite rules one can use these two conditions -
RewriteCond %{REQUEST_FILENAME} !-f # Not an actual file
RewriteCond %{REQUEST_FILENAME} !-d # Not an actual directory
They dictate that the following rule will only apply if the requested filename or folder doesn't really exist. It is used so that a browser will still be able to access resources without them having to be routed.
I'm not 100% sure that this is your problem though. More likely it is an issue with your routing in index.php.
Make sure you are using the correct flags in your .htaccess file:
RewriteCond %{REQUEST_FILENAME} !-f [NC] #Not a file
RewriteCond %{REQUEST_FILENAME} !-d [NC] #Not a dir
EDIT:
Lix makes a good point - if you are on a Unix, Linux, etc. you may not want to use [NC], however, if you are in Windows, for example, you would want to use [NC]
So I'm using a simple rewrite rule like:
RewriteEngine On
RewriteRule ^foo/?$ foo.php [NC,L]
It redirects perfectly to foo.php, but it seems like all links and images in foo.php are being taken from folder foo on the server which doesn't exist. For instance, 1.png will now be foo/1.png or index.html will now be foo/index.html. So my question is: is there any way to make thing right without changing paths to the files in foo.php?
Your visitors' browsers see the current page as being at /foo/, thus all relative URLs will be resolved under /foo/. You will need to set the base URL, or update all your relative URLs to point to your site root (e.g. do not use relative/path/url.jpg but /relative/path/url.jpg).
In your code you should provide a rewrite rule for your resources (images, css, etc...) or add conditions for real files / folders like...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
The two RewriteCond lines test to see if the requested URL points to an actual real directory (the !-d part), and the second one tests if it's a real file (!-f)
In the future, you can easily debug your mod_rewrite stuff by adding this two lines to your .htaccess file:
RewriteLogLevel 3
RewriteLog "/path/to/a/file.log"
2 simple ways
absolutize the references as suggest by Ianzz
remove the foo path for referenced object still using htaccess
RewriteRule ^foo(/.*.(jpg|html|gif|css))$ $1 [L]
I prefer the 2nd solution because the htaccess do the mess and htaccess fix the situation, and no changes to your code are needed.