I am using mod_rewrite to redirect long URL's to specific pages. Its for a shop so basically if the URL is one folder deep it takes the user to a specific page, if the URL is two folders it takes them to another etc. I achieved this using the following...
RewriteRule ^([^/\.]+)/?$ shop.php?category=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ brand.php?category=$1&brand=$2 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ handler.php?category=$1&brand=$2&product=$3 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ handler.php?category=$1&brand=$2&product=$3&car=$4 [L]
Notice each rule is one folder deeper than the previous.
Rather than use another rule for the next stage which is the final product page I would rather take the user to http://www.domain.com/PRODUCT/DB/ID so I wrote a rule to check if the first folder was PRODUCT and if so take the user to PRODUCT.PHP?DB=$1&ID=$2...
RewriteRule ^product/([^/\.]+)/([^/\.]+)/?$ /product.php?db=$1&id=$2 [L]
It keeps returning a 404 error though. I placed this new rule just before the others in the hope it would execute this rule before any others (this appears to be 3 folders deep for which there is another rule when the first folder isn't PRODUCT)
The .htaccess and subsequent .php files are at the root level of the site.
Have I wrote the rule correctly? I have tried all sorts and looked everywhere but questions like this are generally related to ignoring a specific folder which I don't actually want to do.
Thanks
Try turning off Multiviews:
Options -Multiviews
Multiviews is part of mod_negotiation which tries to match a request to existing files, including ones that are missing the extension. So it's possible that mod_negotiation sees the request for /product/something and sees the file /product.php and serves up that file using PATH INFO, which will completely bypass mod_rewrite.
Previously I have vbulletin forum installed on main domain. Now I have replaced it with WP blog and shifted forum to subfolder. Both WP and vB has seperate htaccess files. Please help me to redirect old forum urls to new ones.
Old url pattern:
www.domain.com/f1/post-title/
www.domain.com/f2/post-title/
www.domain.com/f3/post-title/
New url pattern:
www.domain.com/forums/f1/post-title/
www.domain.com/forums/f2/post-title/
www.domain.com/forums/f3/post-title/
Please somebody help me with rewriting rules for correct redirection. Also mention which htaccess (WP or vB) to put the code. Thanks in advance.
It needs to be placed on the .htaccess on the root folder of your domain.
So if your root folder is /home/youraccount/public_html/ then in the .htaccess in that folder.
This will redirect as you asked above, any forum/topic to forums/forum/topic
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteRule ^(f\d+)/([^/]+)/?$ /forums/$1/$2/ [R=301,L]
I could use ([^/]+) twice but since you mentioned you have a WordPress in the root now then you should need a more specific rule for the first folder like the above.
This will match the forum id aka f1, f2 ... up to any amount of numbers:
(f\d+)
This will get anything not a / so it will get the post id and title altogether.
([^/]+)
If you have more rules inside your .htaccess file make sure you place this rule after RewriteEngine on and before any other rule, so it doesn't conflict with other rules and redirect as you asked:
RewriteRule ^(f\d+)/([^/]+)/?$ /forums/$1/$2/ [R=301,L]
I want to redirect
http://subdom.domain.com/guidelines/article1
http://subdom.domain.com/guidelines/article2
http://subdom.domain.com/guidelines/article3
to
http://subdom.domain.com/notsoguideline/noarticlepage/blahblah
so I wrote the following rule in .htaccess of my wordpress site but it doesn't seem to work
RewriteRule ^guidelines/([^/]+)/ /notsoguideline/noarticlepage/blahblah/
Check that your hosting supports and allows the use of .htaccess files.
Ensure that you have RewriteEngine On in your .htaccess (before your custom rules)
If you create a nonsense .htaccess file what happens? If nothing then your .htaccess file is not in use.
I'm having difficulties to get this to work. Maybe someone can help me.
If a user opens
domain.com/folder/images/1.png
the server should rewrite to
domain.com/folder/images/image.php?file=1.png
since some rewrites are required elswhere on the site, I thought I should put the .htaccess file for this one into
domain.com/folder/images/
containing
RewriteEngine on
RewriteRule ^([\.\-_0-9A-Za-z]+)$ image.php?file=$1 [L]
but this somehow sets
$1=image.php
instead of using the actual filename. If I use
RewriteEngine on
RewriteRule ^([\-_0-9A-Za-z]+)$ image.php?file=$1 [L]
the redirect only works for strings without a period in it
If i can get the behavior for multiple folders with one single .htacces file in the root of domain.com it would be even better. Oh and btw, the file extension can only be jpg or png. Can i include that into the regular expression?
Help would be greatly appreciated!
You can put this in your root htaccess (or better in you vhost conf file and disable AllowOverride, to disable the use of htaccess)
RewriteRule ^folder/images/([\.\-_0-9a-z]+)$ folder/images/image.php?file=$1 [L,N]
N for case insensitive url.
I have seen this in a few .htaccess examples
RewriteBase /
It appears to be somewhat similar in functionality to the <base href=""> of HTML.
I believe it may automatically prepend its value to the beginning of RewriteRule statements (possibly ones without a leading slash)?
I could not get it to work properly. I think it's use could come in very handy for site portability, as I often have a development server which is different to a production one. My current method leaves me deleting portions out of my RewriteRule statements.
Can anyone explain to me briefly how to implement it?
Thanks
RewriteBase is only applied to the target of a relative rewrite rule.
Using RewriteBase like this...
RewriteBase /folder/
RewriteRule a\.html b.html
is essentially the same as...
RewriteRule a\.html /folder/b.html
But when the .htaccess file is inside /folder/ then this also points to the same target:
RewriteRule a\.html b.html
Although the docs imply always using a RewriteBase, Apache usually detects it correctly for paths under the DocumentRoot unless:
You are using Alias directives
You are using .htaccess rewrite rules to perform HTTP redirects (rather than just silent rewriting) to relative URLs
In these cases, you may find that you need to specify the RewriteBase.
However, since it's a confusing directive, it's generally better to simply specify absolute (aka 'root relative') URIs in your rewrite targets. Other developers reading your rules will grasp these more easily.
Quoting from Jon Lin's excellent in-depth answer here:
In an htaccess file, mod_rewrite works similar to a <Directory> or <Location> container. and the RewriteBase is used to provide a relative path base.
For example, say you have this folder structure:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
So you can access:
http://example.com/ (root)
http://example.com/subdir1 (subdir1)
http://example.com/subdir2 (subdir2)
http://example.com/subdir2/subsubdir (subsubdir)
The URI that gets sent through a RewriteRule is relative to the directory containing the htaccess file. So if you have:
RewriteRule ^(.*)$ -
In the root htaccess, and the request is /a/b/c/d, then the captured URI ($1) is a/b/c/d.
If the rule is in subdir2 and the request is /subdir2/e/f/g then the captured URI is e/f/g.
If the rule is in the subsubdir, and the request is /subdir2/subsubdir/x/y/z, then the captured URI is x/y/z.
The directory that the rule is in has that part stripped off of the URI. The rewrite base has no affect on this, this is simply how per-directory works.
What the rewrite base does do, is provide a URL-path base (not a file-path base) for any relative paths in the rule's target. So say you have this rule:
RewriteRule ^foo$ bar.php [L]
The bar.php is a relative path, as opposed to:
RewriteRule ^foo$ /bar.php [L]
where the /bar.php is an absolute path. The absolute path will always be the "root" (in the directory structure above). That means that regardless of whether the rule is in the "root", "subdir1", "subsubdir", etc. the /bar.php path always maps to http://example.com/bar.php.
But the other rule, with the relative path, it's based on the directory that the rule is in. So if
RewriteRule ^foo$ bar.php [L]
is in the "root" and you go to http://example.com/foo, you get served http://example.com/bar.php. But if that rule is in the "subdir1" directory, and you go to http://example.com/subdir1/foo, you get served http://example.com/subdir1/bar.php. etc. This sometimes works and sometimes doesn't, as the documentation says, it's supposed to be required for relative paths, but most of the time it seems to work. Except when you are redirecting (using the R flag, or implicitly because you have http://host in your rule's target). That means this rule:
RewriteRule ^foo$ bar.php [L,R]
if it's in the "subdir2" directory, and you go to http://example.com/subdir2/foo, mod_rewrite will mistake the relative path as a file-path instead of a URL-path and because of the R flag, you'll end up getting redirected to something like: http://example.com/var/www/localhost/htdocs/subdir1. Which is obviously not what you want.
This is where RewriteBase comes in. The directive tells mod_rewrite what to append to the beginning of every relative path. So if I have:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
in "subsubdir", going to http://example.com/subdir2/subsubdir/foo will actually serve me http://example.com/blah/bar.php. The "bar.php" is added to the end of the base. In practice, this example is usually not what you want, because you can't have multiple bases in the same directory container or htaccess file.
In most cases, it's used like this:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
where those rules would be in the "subdir1" directory and
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
would be in the "subsubdir" directory.
This partly allows you to make your rules portable, so you can drop them in any directory and only need to change the base instead of a bunch of rules. For example if you had:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
such that going to http://example.com/subdir1/foo will serve http://example.com/subdir1/bar.php etc. And say you decided to move all of those files and rules to the "subsubdir" directory. Instead of changing every instance of /subdir1/ to /subdir2/subsubdir/, you could have just had a base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
And then when you needed to move those files and the rules to another directory, just change the base:
RewriteBase /subdir2/subsubdir/
and that's it.
In my own words, after reading the docs and experimenting:
You can use RewriteBase to provide a base for your rewrites. Consider this
# invoke rewrite engine
RewriteEngine On
RewriteBase /~new/
# add trailing slash if missing
rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]
This is a real rule I used to ensure that URLs have a trailing slash. This will convert
http://www.example.com/~new/page
to
http://www.example.com/~new/page/
By having the RewriteBase there, you make the relative path come off the RewriteBase parameter.
AFAIK, RewriteBase is only used to fix cases where mod_rewrite is running in a .htaccess file not at the root of a site and it guesses the wrong web path (as opposed to filesystem path) for the folder it is running in. So if you have a RewriteRule in a .htaccess in a folder that maps to http://example.com/myfolder you can use:
RewriteBase myfolder
If mod_rewrite isn't working correctly.
Trying to use it to achieve something unusual, rather than to fix this problem sounds like a recipe to getting very confused.
RewriteBase is only useful in situations where you can only put a .htaccess at the root of your site. Otherwise, you may be better off placing your different .htaccess files in different directories of your site and completely omitting the RewriteBase directive.
Lately, for complex sites, I've been taking them out, because it makes deploying files from testing to live just one more step complicated.
When I develop, it's on a different domain within a folder. When I take a site live, that folder doesn't exist anymore. Using RewriteBase allows me to use the same .htaccess file in both environments.
When live:
RewriteBase /
# RewriteBase /dev_folder/
When developing:
# RewriteBase /
RewriteBase /dev_folder/
The clearest explanation I found was not in the current 2.4 apache docs, but in version 2.0.
# /abc/def/.htaccess -- per-dir config file for directory /abc/def
# Remember: /abc/def is the physical path of /xyz, i.e., the server
# has a 'Alias /xyz /abc/def' directive e.g.
RewriteEngine On
# let the server know that we were reached via /xyz and not
# via the physical path prefix /abc/def
RewriteBase /xyz
How does it work? For you apache hackers, this 2.0 doc goes on to give "detailed information about the internal processing steps."
Lesson learned: While we need to be familiar with "current," gems can be found in the annals.
This command can explicitly set the base URL for your rewrites. If you wish to start in the root of your domain, you would include the following line before your RewriteRule:
RewriteBase /
I believe this excerpt from the Apache documentation, complements well the previous answers :
This directive is required when you use a relative path in a
substitution in per-directory (htaccess) context unless either of the
following conditions are true:
The original request, and the substitution, are underneath the DocumentRoot (as opposed to reachable by other means, such as Alias).
The filesystem path to the directory containing the RewriteRule, suffixed by the relative substitution is also valid as a URL path on
the server (this is rare).
As previously mentioned, in other contexts, it is only useful to make
your rule shorter. Moreover, also as previously mentioned, you can
achieve the same thing by placing the htaccess file in the
subdirectory.
I simply delete .htaccess file and it runs perfectly