I have a site I'm trying to develop and I am having some (probably noob) problems getting my reWrite rules to work correctly.
Basically, I'm using the codeIgniter framework to develop the site and as part of this I have created a RewriteRule to remove the index.php part of the URL with the exception of some folders for images etc.
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|shop)
RewriteRule ^(.*)$ /TESTSite/index.php/$1 [L]
The site originally has a current page of page/facilities/our-shop which was a very basic page with a few links to paypal to make a very rough shop page as we needed one quickly. However now I have implemented a different (read OpenCart) shop section to make this a bit more professional and allow more features etc. I have placed the openCart in a subdirectory called shop. The shop continues to work correctly as I've excluded the /shop from my original reWrite rule.
However - My problem...
I want the old page page/facilities/our-shop to redirect to the /shop and therefore work as if I navigated directly there..
I have tried the following:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|shop)
RewriteRule ^page/facilities\/our-shop$ /TESTSite/shop/$1 [R,NC,L]
RewriteRule ^(.*)$ /TESTSite/index.php/$1 [L]
And
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|shop)
RewriteRule ^page/facilities\/our-shop$ /TESTSite/shop/$1 [N]
RewriteRule ^(.*)$ /TESTSite/index.php/$1 [L]
And with a few other variations, but every time I can't get it to work. Can anyone advise please?
Thanks
I think you can try the following rules:
RewriteEngine on
RewriteRule TESTSite/page/facilities/our-shop$ /TESTSite/shop/$1 [R=301]
RewriteCond %{REQUEST_URI} !^(index\.php|images|css|js|robots\.txt|shop)
RewriteRule ^TESTSite/page/(.*)$ /TESTSite/index.php/$1 [L]
Two things:
When you use RewriteCond, it only applies to the following rule. So I re-ordered the two lines.
You do not need \ before a / in a rule.
Check this tool to debug your rules.
Related
I'm working on a project with a custom CMS (which is written by someone else). There's an existing .htaccess file with some conditions and rewrite rules, one of which directs requests to the index.php file. This file loads the CMS object, and calls a method to check if the URL leads to an existing CMS page. If it doesn't, the user is redirected to a 404 page.
The CMS also allows you to build custom modules on top of the base CMS functionality. Usually this is used for user management and stuff like that, but for this project the client wants to be able to build a knowledge base with hundreds of knowledge base items, which in the CMS would become a giant mess. I've now built a custom module for these items, and they also store a slug. I want the URLs to be /knowledgebase/items/item-slug, but with the existing configuration this would lead to a redirect to the 404 page because, as far as the CMS is aware, the item-slug doesn't lead to an existing CMS page. This is the current rewrite section in the .htaccess file.
# Enable the rewrite engine
RewriteEngine On
RewriteBase /domain.tld
# SSL Redirect 301 transfer the current request.
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# never rewrite for existing files, and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
#RewriteCond %{REQUEST_FILENAME} !-d
# For Friendly URLs
RewriteRule ^knowledgebase/items/(.*)$ index.php?knowledge_item_slug=$1 # my own RewriteRule
RewriteRule ^(.*)$ index.php [L]
In index.php I've added the following lines to check if a custom knowledgebase item needs to be shown
if (isset($_GET['knowledge_item_slug']) && $_GET['knowledge_item_slug'] !== '') {
include_once(__DIR__ . '/components/knowledgebase_item.php');
exit(0);
}
This works fine, going to knowledgebase/items/test loads the test item as it should. With this rule added however, CSS and JS files can no longer be found after a hard reload (clearing the cache) and cause net::ERR_TOO_MANY_REDIRECTS errors in the console.
I've modified the rule to RewriteRule ^kennisbank/items/(.*)$ index.php?knowledge_item_slug=$1 [C] (basically just added the [C] flag) and now the item detail page works, but any other page causes the error The requested URL /domain.tld/page was not found on this server.
I've also tried placing RewriteRule ^(.*)$ index.php above my own RewriteRule (without the [L] flag, obviously), but then my own one doesn't work at all.
I'm not too familiar with Apache rewrites, any idea what's causing this issue?
Problem is that you have 2 RewriteRule rules after checking for non-file and non-directory in RewriteCond. Only immediate next RewriteRule is affected by one or more RewriteCond hence last rule executes without any conditions that routes every request including css/js/images to index.php.
You can have your .htaccess as this:
# Enable the rewrite engine
RewriteEngine On
RewriteBase /domain.tld
# SSL Redirect 301 transfer the current request.
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# never rewrite for existing files, and links
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
# For Friendly URLs
RewriteRule ^knowledgebase/items/(.*)$ index.php?knowledge_item_slug=$1 [L,NC,QSA]
RewriteRule ^ index.php [L]
Do-nothing rule RewriteRule ^ - [L] will skip any rules below that line for the conditions above i.e. non-file and non-directory.
I'm asking a question regarding my .htaccess. I'll quickly explain what i'm trying to accomplish and how it's not working.
I'm using the $_GET directory as a rule for the page.
i.e https://example.com/test?p=page1 = https://example.com/test/page1
I also have a directory called "account" inside this /test/ directory but when I try to access the page.
https://example.com/test/account it redirects me to https://example.com/test/account/?p=account
note (https://example.com/test/account/ works fine)
I've tried disabling it by following methods on other StackOverflow posts but none of this is working.
My rule is:
RewriteRule ^([0-9a-zA-Z-_\ ]+)/?$ index.php?p=$1 [NC,L]
Is there any way I can configure this rule to exclude the word "account" and "admin" etc I've tried placing a .htaccess with the rewrite engine off but that doesn't work because the .htaccess thinks /account is a page rather than a directory.
I've tried other methods which stop directories with the same issue. It doesn't think /account is a directory. It thinks it's a page.
Any help would be great!
add this line above to exclude requests with account or admin in them
RewriteCond %{REQUEST_URI} !(account|admin)$ [NC]
put that above your current rule and it should exclude using the rule on requests including those terms.
here is what I use (have for ages), to do what you are wanting to do:
**I am pretty sure I could reduce this to a single set of expressions but I'm not that good. Without the second I miss domain.tld and without the first I miss fancy.domain.tld
ErrorDocument 404 http://domain.tld
RewriteEngine On
RewriteCond %{REQUEST_URI} !(actionspage|\/excludeddir\/|\/otherdir\/).*$ [NC]
RewriteCond %{HTTP_HOST} ^(.+)\.domain\.tld$ [NC]
RewriteRule ^(.*)$ index.php?pre=%1&pos=$1 [L,QSA]
RewriteCond %{REQUEST_URI} !(actionspage|\/excludeddir\/|\/otherdir\/).*$ [NC]
RewriteRule ^(.*)$ index.php?pre=0&pos=$1 [L,QSA]
I've done some research on this and cannot find an good solution. I come from an ASP.net background and am moving our site to WordPress.
My old portfolio link format is as follows
/custom-website-design/airline-aviation/5
The same link on the new website will be
/custom-website-design/airline-aviation
Note the last "/5" is not there. On my old site I used this to look up the category on the back end.
Now my question is, in wordpress, using either a plugin or a custom .htaccess file, can I have the site look for
/custom-website-design/(ANYTHING)/(NUMERIC)
and then have it redirect to
/custom-website-design/(ANYTHING)
Thanks again!
It can be done using WordPress rewrite module but i'm not an expert.
Anyway, you can also do it using .htaccess and mod_rewrite.
You can put this code in your htaccess (which has to be in root folder)
RewriteEngine On
RewriteRule ^custom-website-design/([^/]+)/[0-9]+$ /custom-website-design/$1 [R=301,L]
Note: since you're using WordPress, you have to put this rule before WordPress' main rule.
Should look like this finally
RewriteEngine On
RewriteRule ^(custom-website-design/[^/]+)/[0-9]*$ /$1 [R=301,L]
# WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L]
I am trying to build an online store using dynamic php pages. Currently, .htaccess works with the following:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^online_store/category/(.*)$ category?uri=$1 [QSA,L]
RewriteRule ^(.*)$ index.php?action=$1 [QSA,L]
My index.php is just built with a bunch of includes, so a flat link to browse a category would be:
domain.com/online_store/category/apparel
Index.php is including online_store.htm, which processes the URI properly.
What I'm trying to accomplish next is to add a rule for product URIs, which would tell index.php to include product.htm to process the given URI:
domain.com/online_store/category/apparel/t-shirt1
I thought it would be as easy as adding:
RewriteRule ^online_store/category/(.*)/(.*)$ product?uri=$2 [QSA,L]
But it doesn't work. Even my uneducated mind tells me that the previous rewrite rule for categories preempts this one since L is included - but when I remove it neither work. Can someone educate me on the proper way to process this? Logically, I need this to happen:
domain.com/online_store/category/(URI1)/(URI2)
rewrite domain.com/category?uri=(URI1)
rewrite domain.com/product?uri=(URI2)
Final Edit - I decided to scrap the idea of nesting the product within the respective category, turns out I had issues with the way I was getting the URI using my php script. Here's the .htaccess that is working for me:
RewriteRule ^online_store/category/([^/]+)$ /category?uri=$1 [QSA,L]
RewriteRule ^online_store/product/([^/]+)$ /product?uri=$1 [QSA,L]
You should do:
RewriteRule ^online_store/category/[^/]+/(.*)$ category?uri=$1 [QSA,L]
it has to do with greedy repetition. Basically, the dot matches any character, including the slash(/)
I am working on the htaccess file for my mvc site. The software that the company purchased for the site works only without the www, so I was able to fix up the htaccess to allow www in the URL since most of our affiliates are going to try to use it anyway. However, this renders the siteurl.org/index.php/admin and the siteurl.org/index.php/members unreachable. I'm trying to exclude these URL's from the www forward to non-www but everything I know and can find seems to relate to non-MVC sites, and it seems that mvc sites are set up differently across the board so the examples I'm finding aren't working for me.
Here's my current htaccess (I had to comment out the forwarding lines to allow admins to access the admin section and affiliates to access the member section)
<Files ~ "serial.txt$">
Order allow,deny
Deny from all
</Files>
RewriteEngine On
#RewriteCond %{HTTP_HOST} !^www\. [NC]
#RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^aff/(.*)$ /index.php/aff/?aff=$1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [R=301,NC]
If it could be addressed at the same time, I'd also love a pointer on how to clean up that URL so that we could type in siteurl.org/admin as opposed to siteurl.org/index.php/admin (same for members), and also to show the affiliate name in the URL (it's currently cleaning up the URL to remove the /aff/affiliateusername but affiliates would like to see their name in the URL). If anybody has a great link to specific resources on writing htaccess for MVC I would be eternally grateful. Thank you in advance for any assistance.
Let's be clear on three things before going into explanations:
Apache doesn't have a care in the world whether your site is built on the MVC approach/design pattern or not. It. Doesn't. Even. See. It. To it, it sees htaccess mod_rewrite rules.
Whoever puts a serial code in serial.txt on the root is just begging for it to get nicked using a file include vulnerability in PHP.
This is suspiciously similar to CodeIgniter in rewrite rules.
Now. Your rules:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
This rule will match only if the http host does not start with www. . If this is true, then it'll redirect to the http ://www. version.
Based on your description, you want the opposite: Your CMS does not work with www.. So, you will want this:
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^(.*)$ http://mydomain/$1 [R=302, L]
Note that you'll need to hardcode your domain in there. Sucks.
Next set of rules:
RewriteRule ^aff/(.*)$ /index.php/aff/?aff=$1 [R,L]
This is bog-standard - redirects aff/whatever to /index.php/aff/?aff=$1
For the future, change it to this:
RewriteRule ^aff/(.*)$ /index.php?/aff/?aff=$1 [L]
This will clean up the URL and prevent an Apache rewrite cycle.
Next one:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [R=301,NC]
These will wildcard-match anything that does not exist. Same thing as before, change the last line to this:
RewriteRule ^(.*)$ /index.php?$1 [L]
This will, again, make the rewrite transparent.
P.S: get a real CMS developer. 301s are hardly useful.