I need to know how to remove the ".php" from the directory index file
I don't want to see this:
http://www.domain.nl/wa.admin/index.php?login_msg=nopassword
I saw a lot of posts but they did not work for me for some reason.
these are my basic rules
RewriteRule ^admin[/]*$ /wa.admin [L]
RewriteRule ^([^./]{2}[^.]*)$ /index.php?page=$1 [QSA,L]
What do I have to do internally, because it comes from a redirect ?
Do I have to use absolute url's to make it work?
thanks, Rich
This should work for you.
RewriteBase /
# Stop rewrite process if the path points to a static file anyway
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule (.*) index.php
Explained in words: If the requested resource is a folder or a file don't rewrite, if not rewrite to the index.php.
In your case wa.admin/index.php?login_msg=nopassword will look like wa.admin/?login_msg=nopassword.
Don't forget to update you application. This rule only mapps requests to the appropriate files. This doesn't impact you HTML output. This means with this rewriting you can access both URLs but it's up to you which you want to link in your application.
If you want to distribute your app with others you may use the environment in combination with the if tag to determine whether mod_rewrite is available or not.
<IfModule mod_rewrite.c>
# Enable URL rewriting
RewriteEngine On
# Set flag so we know URL rewriting is available
SetEnv REWRITEURLS 1
# You will have to change the path in the following option if you
# experience problems while your installation is located in a subdirectory
# of the website root.
RewriteBase /
# Stop rewrite process if the path points to a static file anyway
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule (.*) index.php
</IfModule>
Use apache_getenv("REWRITEURLS"); to acess the value of the set variable.
You code might look like this (untested):
<?php
$rewriteurls = apache_getenv("REWRITEURLS");
if ($rewriteurls == '1') {
//adjust all your links
}
?>
Related
I am trying to rewrite page URL's with .htaccess.
I would like to transform links like this (mysite.com/page.php -> mysite.com/page)
This is the code which I've used in previous sites with the same requirements
RewriteEngine on
RewriteCond /%{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-Z0-9_-\s]+)/$ /$1.php
But when I try to access mysite.com/page it leeds to a 404 page where as mysite.com/page.php will show the page.
Can anyone explain if I have missed a setting somewhere? I have placed the .htaccess file in the site root dir and the permissions are set as 644.
Instead of using %{REQUEST_FILENAME} which by the way you have an unneeded / there, I suggest you to use %{DOCUMENT_ROOT}/$1\.php, here is an example:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
## To internally redirect /anything to /anything.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^([^/]+)$ $1.php [L]
Additionally on your rule you have /$ which would again cause you trouble as you want to catch /page.
You could have made it /? to make the / optional.
Your .htaccess fixed should look like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([a-z0-9_-\s]+)/?$ /$1.php [NC,L]
I have tried to create an .htaccess file to do following:
Direct www.domain.com/name or www.domain.com/name/ to www.domain.com/page.php?id=name
and www.domain.com/name/2 or www.domain.com/name/2/ to www.domain.com/page.php?id=name&pg=2
my .htaccess looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid link
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-z0-9-_\.]+)/?$ page.php?id=$1 [L]
RewriteRule ^([a-z0-9-_\.]+)/([a-z0-9]+)/?$ page.php?id=$1&pg=$2 [L]
</IfModule>
The problem is, that when I actually use a slash after name it thinks of it as a directory and looks for pages in www.domain.com/name/.. But I am still able to $_GET the variables based on id and pg.
Can anyone tell me what I have done wrong? I prefer that the URL in the address bar stays clean as www.domain.com/name/2/.
Also i have another question.. I have tried to rewrite the other URLS without luck.
If they write: www.domain.com/page.php?id=name&pg=2 and want to change the address bar URL to be be clean again, but that completely went wrong for me. Is there any specific way to do this by using what I have already made?
Thanks in advance for your help.
EDIT
The solution was based on PHP and not .htaccess. The answer was found based on this question: Stylesheet does not load after using RewriteRule and include . My problem was caused by PHP including relative to the public URL and directory. I have been forced to define a main URL variable to place before any foreign includes.
RewriteCond is only applicable to the very next RewriteRule.
Have your code this way:
RewriteEngine On
RewriteBase /
# If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
# If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+page\.php\?id=([^\s&]+) [NC]
RewriteRule ^ %1? [R=302,L]
RewriteRule ^([\w.-]+)/?$ page.php?id=$1 [L,QSA]
RewriteRule ^([\w.-]+)/([\w.-]+)/?$ page.php?id=$1&pg=$2 [L,QSA]
In my "public_html" directory I have the following structure:
- root
- index.html
- blog
- index.html
- lab
- index.html
- wp
- (WORDPRESS FILES)
The "lab" and "wp" directories are just subdomain directories ("http://lab.tomblanchard.co.uk" and "http://wp.tomblanchard.co.uk") which work fine.
Basically I want the main domain ("http://tomblanchard.co.uk") to point to the "root" directory without any actual redirecting, for example, I want "http://tomblanchard.co.uk" to point to the "index.html" file within the "root" directory, I want "http://tomblanchard.co.uk/blog" to point to the "index.html" file within the "root/blog" directory and so on.
I have kind of achieved this with the following code in my ".htaccess" file:
# Add directives
RewriteEngine on
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
Options +FollowSymLinks
RewriteCond %{REQUEST_URI} !(.*)root
RewriteRule ^(.*)$ root/$1 [L]
The only problem is that things like "http://tomblanchard.co.uk/root/" and "http://tomblanchard.co.uk/root/blog/" still work when really they shouldn't even be able to be accessed (404).
If anyone has any idea on how to sort this or has a stronger method of doing this it would be greatly appreciated.
Update
Finally got it working how I wanted it after hours of researching, I used the following:
# Add directives
RewriteEngine on
# Change root directory to "root" folder
RewriteCond %{THE_REQUEST} ^GET\ /root/
RewriteRule ^root/(.*) /$1 [L,R=301]
RewriteRule !^root/ root%{REQUEST_URI} [L]
The order of directives in mod_rewrite is important, as each rule sees the output of the previous rule as its input to test. You need to do 3 (or possibly 4) things, in order:
Deny access to any URL beginning /root/ (we have to do this first, else everything will be denied!)
It's generally good practice to ensure each URL has only one valid form, so URLs which do specify .html should cause a browser redirect to the non-.html form. This needs to happen before other rewrites, otherwise you can't tell the difference between a .html from the browser and one you've added virtually.
Look up any URL not denied above in the /root/ directory, rather than the configured DocumentRoot
Look up any URL not pointing at a directory under the URL + .html, if that file exists. This has to come after other rewrites, or the "file exists" check will always fail.
# General directives
Options +FollowSymLinks
RewriteEngine on
# Deny URLs beginning /root/, faking them as a 404 Not Found
RewriteRule ^root/ [R=404]
# Additional rule to strip .html off URLs in the browser
RewriteRule ^(.*)\.html$ $1 [R=permanent,L]
# Rewrite everything remaining to the /root sub-directory
# (Host condition was in your post originally, then edited out; this is where it would go)
RewriteCond %{HTTP_HOST} ^(www\.)?tomblanchard\.co\.uk$
RewriteRule ^(.*)$ root/$1
# Handle "missing" ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
PS: Note my careful language to describe (internal) rewrites, as opposed to (browser) redirects: the rule you have is not removing .html from anything, it is adding it, thus allowing the page to be accessed if someone else removes it. Since you are often modifying both within a set of rules, it's important to keep clear in your head the distinction between the URL the browser has requested, and the virtual URL Apache will ultimately serve.
You are not defining any rule to block /root address so how do you want to block it when there is nothing to do that?
Try this:
# Add directives
RewriteEngine on
RewriteCond %{REQUEST_URI} .root [NC]
RewriteRule (.*) / [L,R=404]
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
RewriteCond %{HTTP_HOST} ^tomblanchard.co.uk$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.tomblanchard.co.uk$
RewriteCond %{REQUEST_URI} !.root
RewriteRule (.*) /root/$1 [L,R=301,QSA]
This is not tested so if it wouldn't work, play around with it to get your need.
I have a website running at localhost/pm and the RewriteBase is correctly set to /pm/. There is a link tag in my document: <link ... href="themes/default/css/default.css">.
When the url is localhost/pm or localhost/pm/foo the CSS works all right. When there are more slashes in the URL, however, like localhost/pm/foo/bar the relative URL if the stylesheet changes to foo/themes/default/css/default.css.
How do I get this to work without having to put some sort of PHP path resolution in the link tag?
# invoke rewrite engine
RewriteEngine On
RewriteBase /pm/
# Protect application and system files from being viewed
RewriteRule ^(?:system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
EDIT:
Basically what I need now is this:
If request contains folder name /themes/ scrap everything that is before /themes/ and rewrite the rest to /pm/themes/...
I tried it like this: RewriteRule ^.*(/themes/.*)$ /pm/themes/$1 but I get an internal server error. Why?
If I do it like this: RewriteRule ^.*(/themes/.*)$ /pm/themes/ (ie. just remove $1 from the end) and use the URL http://localhost/pm/foo/themes/foo/ the resulting physical location is http://localhost/pm/themes which is what is expected too, which in turn means that at least my regex is correct. What am I missing?
The RewriteRule is almost correct
RewriteRule ^.*(/themes/.*)$ /pm/themes/$1
This rewrites http://localhost/pm/foo/themes/default/css/default.css to http://localhost/pm/themes/themes/default/css/default.css, which is one themes too much. Use this instead
RewriteRule /themes/(.*)$ /pm/themes/$1 [L]
But now you have an endless rewrite loop, because /pm/themes/.. is rewritten again and again. To prevent this, you need a RewriteCond excluding /pm/themes
RewriteCond %{REQUEST_URI} !^/pm/themes/
RewriteRule /themes/(.*)$ /pm/themes/$1 [L]
Now the request is rewritten only once and you're done.
You probably need to add the following lines before your RewriteRule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
It will only evaluate your rewrite rule if the requested file or directory doesn't exist.
You should post your .htaccess file so we can offer better advice
This is my htaccess:
RewriteEngine On
# Stop if it's a request to an existing file.
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule .* - [L]
# Redirect all requests to the index page
RewriteRule ^([^/]) /index.php [L]
Now this forwards everything to my index.php script! It dosen't stop if a script exists. Anyone have any idea why this isn't working? I've looked everywhere, but I don't really understand mod_rewrite (as much as I thought!).
The problem has come about because I've put in <script> tags which point to .js files in my web directory which are then forwarded to the index.php script. The web developer toolbar tells me this. :) And clicking links to the js files in firefox's view source window also shows the index.php output.
thank you.
This is because after processing a rewrite rule the whole process restarts with the new url. The processing of an url can go thru the rules over and over again each time with the changed URL, until there is no more change (no applying rules found).
You need this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.php [L]
Don't think of the rules as a program, they are rules which can overlap and must be as specific as possible with each one.
I guess you should add [OR] after the first condition like this:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*) $1 [QSA,L]