How to remove extension and force trailing slash with .htaccess - .htaccess

I managed to solve this problem by the following code:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]
In other words, not to do anything if its a directory.
Yet, my current problem is that css and the images are not loaded until I change the path to the css file and to the images to the absolute path.
Is there any other way to solve it rather then changing all the paths in all the files in the website to absolute.
Thanks a lot.

Add RewriteCond %{REQUEST_FILENAME} !-f to the first two RewriteCond, then images and css won't hit the rewrite, but PHP files will, and things that are not folders will also hit the rewrite

Related

.htaccess URL rewrite directory

so I want to rewrite a URL. The default URL is http://example.com/m.php?i=random_string
Here's the rule
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
RewriteRule ^m/([^/]+)/?$ m?i=$1 [L]
However, when I access http://example.com/m/random_string, the page comes up but my external css and js files don't load. Why does this happen? I thought that the directory does not change from the original rewritten URL.
The directory indeed does not change, but browser doesn't know that - what it gets looks like a directory, such as m/something, so it tries to load the CSS file relative to this directory.
To fix that, use absolute paths to your CSS and JS in the page, ie.:
/css/style.css
(the initial forward slash makes it absolute)
RewriteEngine On
RewriteRule ^m/([^/]+)/?$ m.php?i=$1 [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)(\?.*|)?$ %{REQUEST_FILENAME}.php$2 [QSA,L]
Have your rules like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^m/([^/]+)/?$ m.php?i=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-d and RewriteCond %{REQUEST_FILENAME} !-f will prevent first rewrite rule to be applied for real files and directories.

Remove .php extensions with .htaccess without breaking DirectoryIndex

I have the following rewrite in my .htaccess file which removes the .php extension from files, converting for example so.com/question.php to so.com/question.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
However this also breaks the default DirectoryIndex behaviour, in which just typing the directory will redirect to the index file in the folder, e.g. so.com/answer displays so.com/answer/index.php
Simply combining the above code with DirectoryIndex index.php does not achieve both results.
Can someone help me combine these two functions, or rewrite the code to exclude index.php files, which would achieve the same result?
I'm thinking you just need to verify that the file exists prior to doing the rewrite, that way you'll leave 404 and directoryindex behaviours intact:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
(not tested)
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
I tested and it is working fine.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [L, QSA]
verify files and folder and also, add RewriteBase /

folder doesn't load while making the URLs work with and without the .php

I included the code for making the URLs work with and without .php. I included the below written code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Now the url works with and without .php. For e.g. if we put http://www.test.com/test.php or http://www.test.com/test both works. But the problem is folders doesn't load. For e.g. http://www.test.com/admin doesn't load. not found error is shown. Admin is a folder. Any idea?
Try this code for .php extension removal instead:
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^GET\s.+\.php [NC]
RewriteRule ^(.+)\.php$ /$1 [R=301,L,NC]
# To internally redirect /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule . %{REQUEST_URI}.php [L]
Make sure to comment out your existing code
Try below :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [NC,L]
this will also work with a directory path.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
just try this...I think its working

.htaccess clean URL and relative paths

I have the following in my .htaccess which is :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /index.php?type=cat&id=$1 [QSA,L]
RewriteRule ^page/([^/]+)$ /index.php?type=page&name=$1
This seems to work just fine but relative paths to pictures and css files inside of index.php become broken in the second case (Page). did not work. In second case, all images are pointing to page/images/ instead of image/
Other than hardcoding the actual path to images, is there any other way to fix this?
images, css, js folders are located in the root. This is how the root looks like
.htaccess
index.php
images/
css/
js/
RewriteCond directives only apply to the rule directly following them.Try the follwing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /index.php?type=cat&id=$1 [QSA,L]
RewriteCond %{REQUEST_URI} !\.(css|js|jpe?g|gif|png)$ [NC]
RewriteRule ^page/([^/]+)$ /index.php?type=page&name=$1 [L]
#rewrite requests for page/images to images
RewriteCond %{REQUEST_URI} ^/page(/images/.+)$ [NC]
RewriteRule . %1 [L]
EDIT.
Modified to rewrite page/images to images

htaccess code to remove extension AND add+force trailing slash?

I'm trying to put together some htaccess code that will turn example.com/filename.php into example.com/filename/ (and force the slash) - I've tried varous approaches, but each hasn't worked quite right, from 500 errors on subfolders to issues with the trailing slash, etc...
Please help!
Try this:
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteRule (.*)/$ $1.php [L]
The first rule redirects requests of /foo/bar.php externally to /foo/bar/. And the second rule rewrites requests of /foo/bar/ internally to /foo/bar.php.
And to force the trailing slash, try this rule:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]
This solution of Gumbo works great for files, yet it does not work with directories.
In other words:
For mysite.com/file1.php, it shows mysite.com/file1/ which is great.
Yet, it does not work well for directories. If I try to access the following directory (that contains index.php file inside) mysite.com/dir1, instead of showing the content of the http:/mysite.com/dir1/index.php and the url: mysite.com/dir1/, it returns 404.
My solution around it was:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]
In other words, not to do anything if its a directory.
Hope it helps.
Another problem with the original solution is that css and the images are not loaded until I change the path to the css file and to images to absolute path.
Is there any other way to solve it, rather then changing all the paths in all the files in the website to absolute.
Thanks a lot.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
Works like a charm - thanks for the help folks.
You could try working off the question here. Whilst the solution to the question isn't relevant (yet...) the question itself provides a set of rewrite rules which you may be able to use in your own site.
If you require symbols in URLs you could just use ".*" instead of the specific A-Za-z0-9, but if you're looking for a possible trailing slash you may want to use ".*?" instead. This is a standard regular expression feature to avoid the greediness of ".*".
For the path you can add <base href="yourpath" /> to your php pages.
Try this, this one works on my Apache, even when you remove manual the last slash:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

Resources