At the top of the root .htaccess file, I have added
#RewriteCond %{REQUEST_URI} !^/maintenance_503.php [NC]
#RewriteRule .* maintenance_503.php [L]
If uncommented, it redirects the users to a maintenance screen.
However, this doesn't work for subdirectories with their own .htaccess files, and it looks like I cannot use inherit, since it appends parent rules after child rules. I'd rather not add this rule to every single .htaccess file since I want to have a single point of entry for switching it off and on. Are there any best practices for such a case?
Related
I have a file structure like this.
Folder
- .htaccess
- Subfolder
- Otherfolder
- file1.html
- file2.html
- filea.html
- fileb.html
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
i want to remove all other subfolders names except folder.
I just want to get URL like - mywebsite.com/folder/file.html
Edit
currently I am using this code snippet in .htaccess
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^subfolder/([^.]+)\.html$ /folder/$1 [L,R]
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
This isn't possible in .htaccess alone. The problem is not in removing the subfolder from the URL (although this should already have been done in the internal link), the problem is internally rewriting the request back to the appropriate subfolder. There is no built-in mechanism to "search" for arbitrary files in .htaccess.
If you have a limited number of known subfolders then you can do this, but you need to add a rule (in the root .htaccess file) for every subfolder. However, this is not particularly efficient since you need to manually test for the existence of that file in each subfolder. You also have a potential problem of name collision. Obviously, if you effectively "flatten" the filesystem the file file1.html can only exist once on the filesystem, amongst all subfolders. If there is more than one file1.html then the first match wins.
In principle, you would need to do something like the following to rewrite a request for /folder/<file>.html back to /folder/subfolder/otherfolderN/<file>.html.
# Test "subfolder/otherfolder1"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder1/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder1/$0 [L]
# Test "subfolder/otherfolder2"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder2/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder2/$0 [L]
# Test "subfolder/otherfolder3"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder3/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder3/$0 [L]
The parent /folder/ could be abstracted out of the RewriteCond TestString if you wish, but the subfolder and otherfolderN would need to be hardcoded. (Although subfolder could be manually assigned to an environment variable to save repetition.)
Aside:
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
A "problem" with this code is that it rewrites the request regardless of whether the target file exists or not. This is OK if you are rewriting all requests to a single subfolder, but if you have multiple subfolders then you must check for the target file's existence before rewriting.
This also rewrites the request even if it already maps to an existing file. So any legitimate files in the /folder/ directory (eg. filea.html and fileb.html in your file structure) would not be accessible.
This also rewrites every file type (except for the few file extensions listed in the preceding condition). It would, for instance rewrite a request for foo/bar/file.webp to /folder/subfolder/foo/bar/file.webp.html. If you are only wanting to rewrite .html files then include this in the RewriteRule pattern and the preceding condition is not required.
I have a PHP script to generate placeholder images, much like the Placehold.it service. I wanted a custom one to prevent the latency that often occurs with free online services.
I have included this script inside of the folder ./assets/placeholder/ in my personal front-end boilerplate. That is why I need a .htaccess that adapts to the current location of the placeholder folder, as it will not always be the root.
The script takes the following parameters: d (dimension, eg. 400, 250x100), bg (background color), color (text color) and text.
Ideally, the url would work as following ./assets/placeholder/300x200/EAEAEA/333333?text=Test, with text being a regular GET var.
Here is the .htaccess that I put together a while ago. It works provided the file is in the root directory:
RewriteEngine on
RewriteRule ^#([^/]*)/([^/]*)/([^/]*)$ index.php?d=$1&bg=$2&color=$3 [QSA]
In one sentence, if I move this file (index.php) from the root to /some/other/dir/index.php, I want the .htaccess file to still function without have to change the RewriteBase or anything.
I have already found this article on the matter, but I don't have enough knowledge on this subject to make it fit this case.
Thanks in advance!
UPDATE: I decided to move the .htaccess file to the root of my project. The only thing not working is the adding of the / at the end, but before the ?
## Turn mod_rewrite engine on ##
RewriteEngine On
# No trailing / ?
RewriteCond %{REQUEST_URI} !(.*)/$
# Add the slash.
RewriteRule assets/placeholder/(.*)$ assets/placeholder/$1/ [L,R=301]
# Map parameters to get vars
RewriteRule assets/placeholder/?([^/]*)/?([^/]*)/?([^/]*)/$ assets/placeholder/index.php?d=$1&bg=$2&color=$3 [QSA]
Change this url .assets/placeholder/300x200/EAEAEA/333333&text=Test to .assets/placeholder/300x200/EAEAEA/333333?text=Test if you want the QSA flag runs.
And try this code :
RewriteEngine on
RewriteRule ^assets/placeholder/([^/]*)/([^/]*)/([^/]*)$ index.php?d=$1&bg=$2&color=$3 [QSA]
Try also this code for the redirection the url with end slash :
RewriteCond %{REQUEST_URI} !^([^/]*)/$
RewriteRule assets/placeholder/(.*)$ assets/placeholder/$1/ [L,R=301]
I have this rewrite cond:
RewriteCond %{REQUEST_URI} !.*\.(css|js|php|html|png|jpg|gif)|notes|messages|/delete/|/achors_data/|/composer/|/pagination/|/mom_mp3/|/swf/|/js/|/stories/|/wall/|/news_feed/|/notifications/|opencv|hdflvplayer|hdflvplayer2|videojs|ffmpeg|mediaplayer|uploadify|/v/|/video/|/options/|show_msg_dialogs|facedetector|classes|right_column_modules|functions|maurice|pokes|opticrop|geoip_city|/autocomplete/|chrono|ajax|editprofile|tag|Svetlozar.NET
It has to be maintained with each new directory that is created on root as I have a rewrite rule that redirects everything from non existing directories (root/mydirectory/ and root/mydirectory_b/) to root/specialdirectory/ except what's on the condition which is just any existing directory in root which does not need to have the rule of going to specialdirectory applied.
My question is if it would be possible to write the rewritecond or take another approach to accomplish the same, not having to write manually each new directory in the .htaccess that is being created in root.
So this is the rewrite rule with the cond that makes everything (root/anydir/) go to
root/master
RewriteCond %{REQUEST_URI} !.*\.(css|js|php|html|png|jpg|gif)|notes|messages|/delete/|/search/|/buttons/|/achors_data/|/composer/|/pagination/|/mom_mp3/|/swf/|/js/|/stories/|/wall/|/news_feed/|/notifications/|opencv|hdflvplayer|hdflvplayer2|videojs|ffmpeg|mediaplayer|uploadify|/v/|/video/|/options/|show_msg_dialogs|facedetector|classes|right_column_modules|functions|maurice|pokes|opticrop|lists|geoip_city|/autocomplete/|chrono|ajax|editprofile|tag|Svetlozar.NET
RewriteRule ^([A-Za-z-0-9-_.]+)?$ master/$2
Then there is the problem in which the directory friends only outside all of the directories in root should perform a certain action anything/friends goes to anything/view_friends.php
What I would like is to be able to write a RewriteCond that takes in consideration every existing directory in root - a wildcard for that.
So I would end up writing something like the following with no maintenance
RewriteCond %{REQUEST_URI} ! * existing directories - except just one
instead of:
RewriteCond %{REQUEST_URI} !.*\.(css|js|php|html|png|jpg|gif)|pokes|opticrop|notes|/delete/|/search/|/buttons/|/achors_data/|/composer/|/pagination/|/mom_mp3/|/swf/|/js/|/stories/|/wall/|/news_feed/|/notifications/|opencv|hdflvplayer|hdflvplayer2|videojs|ffmpeg|mediaplayer|uploadify|/v/|/video/|/options/|show_msg_dialogs|facedetector|classes|right_column_modules|functions|maurice|lists|geoip_city|/autocomplete/|chrono|ajax|editprofile|tag|Svetlozar.NET
RewriteRule ^([A-Za-z-0-9-_.]+)/friends $1/view_friends.php
directories must exist as real directories for the rewritecond to apply as I use phantom directories for the first rewriterule.
I'm not following what you want exactly. Would easier if you could post the entire htaccess instead of just fragments. Also giving some sample urls would help.
But I'll just go tell you what I use.
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^([^/]+)(/(.*))?$ - [L]
This rule get the first past of the url, before the first /, and check if there is an existing directory (in the root) with that name. If so, it will stop processing any rewrite-rules below it (that's what the - [L] part does).
I just moved a site to a subdirectory. Instead of changing every link I'd like to do a 301 redirect via htaccess. Heres an example of what I want to do:
When someone tries to go to www.example.com/test.html, I want them really to go to www.example.com/website/test.html. When someone goes to www.example.com/documents/test.pdf, I want them to go to www.example.com/website/documents/test.pdf.
I want to append the /website/ directory to every request basically. Because I moved the site from the root folder into this subdirectory.
I do have one restriction, I want to make it so that www.example.com/website1/ still goes to www.example.com/website1/. If this changes the solution please give me both solutions, because I am flexible with this.
2 basic approaches (there are some more, but they depend on your rewrite logic (other rules) so may not be suitable for every scenario):
First:
# Redirect all incoming requests into /website/ subfolder
# but excluding /website1/ folder
# First condition is to prevent infinite redirect
RewriteCond %{REQUEST_URI} !^/website/
RewriteCond %{REQUEST_URI} !^/website1/
RewriteRule ^.*$ http://www.example.com/website%{REQUEST_URI} [R=301,L]
Second:
# Redirect all incoming requests into /website/ subfolder
# but excluding /website1/ folder
# Condition is to prevent infinite redirect
RewriteCond %{REQUEST_URI} !^/website/
RewriteRule ^(?!website1/).*$ http://www.example.com/website%{REQUEST_URI} [R=301,L]
As of now my website has a few static pages, one of which is /portfolio. Among other things, my htaccess hides the .html extension. I'd like to add a portfolio directory, but I do not want to move my existing portfolio page into the portfolio directory as the default index file. My /portfolio page is one of my Google sitelinks and I am afraid if it is moved or if the url changes in someway, Google will consider it to be a brand new page.
My problem is once I add the /portfolio/ directory, whenever I try to visit the original /portfolio page, a trailing slash is automatically added and it links to the directory itself.
I've tried countless options, one being a rewrite of /portfolio/ to /portfolio, however this creates an infinite loop. I also tried "DirectorySlash Off" but that only removed the trailing slash while being inside the directory, it didn't revert access to the original /portfolio page.
Ultimately, I would like to keep my /portfolio page as-is, linking to pages inside the directory like so /portfolio/example and if either /portfolio or /portfolio/ is accessed it will result in showing the same page which is outside of the directory without Google thinking it is duplicate content.
A similar question exists here:
.htaccess rewriting url to page or directory though this still resulted in an infinite loop for me for some reason, I'm guess it has something to do with the hidden extensions.
Here's my htaccess-
RewriteEngine On
# HTML to PHP
RemoveHandler .html .htm
AddType application/x-httpd-php .htm .html
# Hide extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Force WWW
RewriteCond %{HTTP_HOST} ^mydomain\.net
RewriteRule ^(.*)$ http://www.mydomain.net/$1 [R=301,L]
# Blog Subdomain
RewriteCond %{HTTP_HOST} ^blog.mydomain.net$
RewriteRule ^(.*)$ http://www.mydomain.net/blog/$1 [R=301,L]
I know it's not a great idea having a directory with the same name as a static page, but I really would rather not alter the existing page and lose the Google sitelink, so a clean and proper way to handle this would be a help.
There are two things going "wrong" here, and two ways to fix it.
The first is that apache "figures out" that there is a directory by the name of "portfolio" before the rewrite conditions are applied. That means that the rewrite conditions are receiving "portfolio/" instead of "portfolio".
Second, the "!-d" rule is specifically avoiding the rewrite that you want to make if there is in fact a directory by that name
Solution 1: Manually re-route requests for the portfolio directory to remove the slash.
# Manually re-route portfolio/ requests to portfolio
RewriteCond %{REQUEST_FILENAME} portfolio/$
RewriteRule ^(.*)/$ $1
# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Note the removal of the "!-d" condition.
The downside to this is that you are having to hard-code the "portfolio" edge case directly into the rewrite rules, and will still result in the browser being first redirected to portfolio/
Solution 2: Set DirectorySlash Off and remove directory exists test
# Disable Automatic Directory detection
DirectorySlash Off
# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Setting DirectorySlash Off would fix this issue the best, but may break other parts of your site where you actually want the auto DirectorySlash. Best of Luck, and I hope this helps.
Note when testing solution 2, your browser may remember the redirect of "portfolio" to "portfolio/" and perform the redirect before it even sends the request to the server. Be sure to test in a cache-clear, clean environment for best results.