Need to remove .html file extension and duplicate names - html

I have a .htaccess file with the contents below, that removes the .html file extension for all of my website's pages.
Options +MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteCond %{HTTP_HOST} ^(www\.)?james-lee\.io$ [NC]
RewriteRule ^$ https://www.james-lee.io%{REQUEST_URI} [R,L]
My links now look like www.james-lee.io/resume/resume when before they looked like www.james-lee.io/resume/resume.html. I would like to remove the folder name so the name of the folder is not duplicated by the name of the file minus the .html and the final result looks like www.james-lee.io/resume.
I have seen similar questions but not exactly what I am looking for.

So I have done this task!
Try this code:
RewriteCond %{REQUEST_URI} ^/(.*)/(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteCond %{DOCUMENT_ROOT}/%1/%2 -f
RewriteCond %1::%2 ^(.*)::\1$
RewriteRule ^(.*)$ /%1 [R,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)/(.*)$ /$1/$1 [END]
Now I try to explain this rules.
first line: you do request like /folder/file
second line: check if /folder/ real existing folder
third line: check if /folder/file is real existing file
fourth line: I use notation %1::%2 because backreferences can only
be used in the left part of RewriteCond. But it possible to reuse
left part in pattern of the right part. So, in the "^(.*)::\1$" I
check all before ::. Then I have result at the \1 backreference. So,
if folder is equal to file, text after :: will be equal to %2.
Next I just redirect to the result (/folder or /file, doesn't
matter, because both are equal)
But if folder == file, redirect will be always to the directory.
So, next I check, if redirect result is existing dir and change the link.
Request example:
http://yourdomain/test/test
(this will be redirected to http://yourdomain/test, but will reference to original link)
I hope, I explain clearly, but if you have any questions, I would glad to answer.
Thank you for insteresting task!
P.S. see also %N backreference inside RewriteCond
UPDATED. Your htaccess have to be like below:
RewriteEngine on
RewriteCond %{SERVER_PORT} !=443
RewriteCond %{HTTP_HOST} ^(www\.)?james-lee\.io$ [NC]
RewriteRule ^$ https://www.james-lee.io%{REQUEST_URI} [R,L]
RewriteCond %{REQUEST_URI} ^/(.*)/(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteCond %{DOCUMENT_ROOT}/%1/%2\.html -f
RewriteCond %1::%2 ^(.*)::\1$
RewriteRule ^(.*)$ /%1 [R,L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)/(.*)$ /$1/$1.html [END]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]

Related

Apache Mod Rewrite for CodeIgniter AND HTML5 mode

I have Codeigniter running on Apache and have Apache Mod Rewrite that works well.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
I've now changed the front-end to be HTML5 and my app uses emulated URLs that suppose to be handled by the same 1-page application.
So I need something like the following URL rewrite:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
So, I'd like to combine those together.
First I'd like to see if the first part of URL path is a CI controller (a file in ./application/controllers) and if yes then rewrite it to index.php.
If not, I'd like to rewrite it to index.html.
I'm trying to build something like
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# -- RewriteCond ^/([^/]+)/ (application/controllers/$1.php) is a file
RewriteRule ^(.*)$ index.php/$1 [L]
RewriteRule ^ index.html [L]
I understand that my other option it to manually specify all possible routes and controllers but would be nice to do it automatically...
UPDATE:
The proposed solution below helped me to solve the problem.
This is what worked for me eventually:
RewriteCond C:/projects/someproject/WS/application/controllers/$1.php -f [OR]
RewriteCond C:/projects/someproject/WS/application/controllers/$1 -d
RewriteRule ^(.+)$ index.php/$1 [L]
RewriteCond $1 ^(.*)/$
RewriteCond C:/projects/someproject/WS/application/controllers/%1 -d
RewriteRule ^(.+)$ index.php/$1 [L]
RewriteCond $1 ^(.*)/[^/]*/?$
RewriteCond C:/projects/someproject/WS/application/controllers/%1.php -f
RewriteRule ^(.+)$ index.php/$1 [L]
# else, rewrite the request to /index.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.html [L]
I've realised I had to check for more types of URLs and also I found I couldn't use %{DOCUMENT_ROOT} because I'm using VirtualDocumentRoot settings and DOCUMENT_ROOT isn't working
Try :
# If /document_root/application/controllers/request.php is a file
RewriteCond %{DOCUMENT_ROOT}/application/controllers/$1.php -f
# Rewrite the request to /index.php
RewriteRule ^(.+)$ /index.php/$1 [NC,L]
# else, rewrite the request to /index.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /index.html

How to remove .html in htaccess

I have a problem removing the .html on the end of a page.
The code I use works perfectly accept on one page /contact.html.
If I rename the html file to anything else then /contact.html it works.
For an example /nothing.html.
If I add an empty html file on my server called contact.html it doesn't work either.
This is the code I use:
RewriteEngine on
RewriteBase /
RewriteCond %{http://www.bijleshelmond.nl} !(\.[^./]+)$
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !-f
RewriteRule (.*) /$1.html [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+)\.html\ HTTP
RewriteRule ^([^.]+)\.html$ http://www.bijleshelmond.nl/$1 [R=301,L]
You probably have a folder (or even a file) named contact, you will need to remove that folder (or file first).
The condition is not met in this situation is one of the too:
# Condition broken if the directory 'contact' exists
RewriteCond %{REQUEST_fileNAME} !-d
# Condition broken if the file 'contact' exists
RewriteCond %{REQUEST_fileNAME} !-f

Exclude all Files from Rewrite (NGINX to APACHE Migration)

My URL structure is like
http://www.example.com/folder/index.php?dir=dir1
To be able to access it from
http://www.example.com/folder/dir1
and at the same time redirect the 1st URL to 2nd one, my htaccess (in 'folder') is
Options +FollowSymLinks
RewriteEngine On
RewriteBase /folder
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{QUERY_STRING} ^dir=(.*)$ [NC]
RewriteRule ^ %1? [L,R=301,NE]
RewriteRule ^(.+)/? index.php?dir=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ index.php?dir=$1 [L,QSA]
The Redirect and Rewrite were working perfect until recently I switched from NGINX back to APACHE.The trouble is that it is now also rewriting file extensions which I don't want!How can I only apply it only to directories and exclude ALL files from it?
Figured it out! :)
Actually had to add
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
before the first rewrite!
So the htaccess looks like:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /folder
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{QUERY_STRING} ^dir=(.*)$ [NC]
RewriteRule ^ %1? [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)/? index.php?dir=$1 [L,QSA]

Regex to avoid "dirty" web links

If this is my actual URL to a file:
http://www.example.org/posts.php?post=example-post-name
In my .htaccess file, how can I use a regular expression to get to this path when a user submits:
http://www.example.org/posts/example-post-name
So far I've come up with this bringing together a few examples (this also included a www redirect):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*) http://%1/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !(\.[^./]+)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /$1.php [L]
RewriteRule ^posts/([A-Za-z])/$ /posts.php?post=$1
But I'm not having much luck with it, can anyone tell me where I'm going wrong?
You need a + after your A-Za-z group to indicate one or more characters, and also you need to add a - to the end of that group. At the end, the /? indicates that the final slash may or may not be present.
Finally, add [L] to be sure no further rewrite rules get processed.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*) http://%1/$1 [R=301,L]
# First rewrite the posts:
RewriteRule ^posts/([A-Za-z-]+)/?$ /posts.php?post=$1 [L]
# ing0 edit: add in dirs that need changing back.
# (I dont know if there is an easier way to do this).
RewriteRule ^posts/css/(.*)$ /css/$1 [L]
RewriteRule ^posts/img/(.*)$ /img/$1 [L]
# etc
# Then, if it's not a real file and doesn't already end in .php
# Note change here ...
RewriteCond %{REQUEST_URI} !\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# redirect it to PHP.
RewriteRule (.*) /$1.php [L]
I think you need to match the whole url and the regex wasn't quite right. Try this:
RewriteRule ^(.*)/posts/([\w-]+)$ $1/posts.php?post=$2
If it works only matching the non-base part of the url, this this:
RewriteRule ^posts/([\w-]+)$ posts.php?post=$1
Why not use:
RewriteRule ^posts/(.*)/$ posts.php?post=$1

Exclude certain subfolders and domains in redirects

This is a continuation from Redirect only HTML files?
How can I change my .htaccess to make it exclude certain subfolders or subdomains from the HTML-only redirect? I tried doing using this code to exclude the 'downloads' subfolder and the 'dev' and 'support' subdomains, but it didn't work:
RewriteCond %{HTTP_HOST} ^pandamonia.us$ [OR]
RewriteCond %{HTTP_HOST} ^www.pandamonia.us$ [OR]
RewriteCond %{HTTP_HOST} !download [OR]
RewriteCond %{HTTP_HOST} !faq
RewriteCond %{HTTP_HOST} !support [OR]
RewriteRule /.+\.html$ "http\:\/\/pandamonia\.us\/" [L]
You need to check REQUEST_URI or the whole match of the RewriteRule $0 for this; HTTP_HOST does only contain the host name of the current request. You also need to change the logical expression of your condition:
RewriteCond %{HTTP_HOST} ^pandamonia\.us$ [OR]
RewriteCond %{HTTP_HOST} ^www.pandamonia\.us$
RewriteCond %{REQUEST_URI} !^/download/
RewriteCond %{REQUEST_URI} !^/faq/
RewriteCond %{REQUEST_URI} !^/support/
RewriteRule /.+\.html$ http://pandamonia.us/ [L]
For those looking for a quick bit of insight into Gumbo's previous reply (where he mentions the situations for when to (and not to) use [OR], I found this WMW thread very helpful: http://www.webmasterworld.com/apache/3522649.htm