mod_rewrite does not work - .htaccess

I have the following page name
http://example.co.uk/vehicle.php?size=large
and I have written the following rewrite rule so the domain should look as follows
http://example.co.uk/size/large
Here is the rule
RewriteEngine On
RewriteRule ^size/([a-zA-Z0-9]+)/$ vehicle.php?size=$1
I have two problems:
The first is its not working. In fact its not working at all.
The second is if it does work then it will remove the page name which I don't want. I'm struggling to see my mistake in the first place to fix it but I want the domain to look as follows:
http://example.co.uk/vehicle/size/large

If you want to redirect from /vehicle.php URLs to /vehicle/ URLs, then try this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*?)=(.*?)$
RewriteRule ^vehicle\.php /vehicle/%1/%2? [R=301,L]
As for displaying contents of nonclean URLs (like /example.php?foo=bar) at clean URLs (like /example/foo/bar), there is a cyclic-redirection issue when trying to use both internal (from a to b) and external (from b to a) redirections at the same time.
If you've decided to switch to clean URLs, then I would recommend you to use /index.php as the only handler for all requests, and use mod_rewrite solely to redirect from old URLs to clean ones. Moreover, I usually perform most of operations with PHP (by parsing $_SERVER['REQUEST_URI'] via PHP), and use mod_rewrite solely to map all requests to index.php file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]
That's most flexible, straightforward, and portable solution.

Related

htacces - need to fix broken links coming from other sites to mine

I am having an issue where Google Webmaster Tools is reporting a ton of 404 links to my site which are coming from ask.com.
I have tried to get ask.com to fix their side but of course they are not, so now I am stuck with over 11k of bad links to my site which I am suspecting is effecting my ranks right now.
Anyways I have a possible way to 301 them, but not sure how to do it with .htaccess.
Here is the bad link pointing to my site
http://www.freescrabbledictionary.com/sentence-examples/fere-film/feverous/about.php
It should be
http://www.freescrabbledictionary.com/sentence-examples/fere-film/feverous/
Besides the about.php there are other variations of endings as well, I basically need to be able to remove the ending.
Problem is that the URL after /sentence-examples/ can change. The beginning is always:
http://www.freescrabbledictionary.com/sentence-examples/
So basically:
http://www.freescrabbledictionary.com/sentence-examples/<-keep but can change->/<-keep but can change->/<-remove this->
This .htaccess should be placed on the folder before sentence-examples:
RewriteEngine on
# Redirect /sentence-examples/anything/anything/remove to /sentence-examples/anything/anything/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(sentence-examples/[^/]+/[^/]+)/.* [NC]
RewriteRule ^ /%1/? [R=302,PT,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/(.*)$ /sentence-examples/examplesentence.php?havethis=$1&word=$2 [L]
Change 302 to 301 once you confirm it's working as expected.
If you have a CMS installed you might need a different rule to work along with it without conflicting.
Keep in mind that if you had previously tried different redirects using 301 aka permanent redirect its recommended that you use a different browser to test this rule to avoid the caching.
This is possibly quick and dirty but I've done a simple test on localhost and here just to make sure it works.
RewriteEngine On
RewriteRule ^sentence-examples/(.*)/(.*)/(.*)\.php http://www.freescrabbledictionary.com/sentence-examples/$1/$2/ [R=301,L]
You can see that I've added wildcard groups (.*) to the RewriteRule so that we can pick up the elements of the URL that we need to aid in proper redirection i.e. $1 and $2. You can also use the third one ($3) to get which destinations are being targeted alot for your SEO needs.
NB: The rule above assumes that that the redirected URL will always be from a .php target and to ensure that you can redirect regardless of whatever comes after the 3rd URL segment replace the RewriteRule with this
RewriteRule ^sentence-examples/(.*)/(.*)/(.*)$ http://www.freescrabbledictionary.com/sentence-examples/$1/$2/ [R=301,L]

Tricky: Remap url but stay on the same url internally

Need your help. Just spend many ours on this htaccess problem and still don't have a clue how to manage this.
I have many http://www.example.com/menu-alias/foo links on my company's website which should get redirected to http://www.example.com/foo.
This alone shouldn't be the hard part but listen up... the tricky part follows.
I don't manage to get the site (Joomla 1.5) working without the 'menu-alias' this means that all http://www.example.com/foo should get internally mapped to http://www.example.com/menu-alias/foo. So that the user still has http://www.example.com/foo in his browser's address bar.
To make it even more complicated i have to 301 redirect the old menu-alias/foo links to /foo.
Can some htaccess guru help me out? Is this even possible?
You can try adding these rules in the htaccess file in your document root (or vhost config):
RewriteEngine On
# externally redirect requests that have "menu-alias"
RewriteCond %{THE_REQUEST} /menu-alias/([^\ \?]+)
RewriteRule ^ /%1 [L,R=301]
# internally rewrite requests back to menu-alias
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/menu-alias/
RewriteRule ^/?(.*)$ /menu-alias/$1 [L]
Couple of potential problems:
Joomla may be looking for the original un-rewritten request in $_SERVER, if so, the rewrite won't work.
The rule to add the /menu-alias/ back into the URI does so blindly rewrites all requests that don't point to an existing resource. This means "virtual" paths that Joomla may handle will get a "menu-alias" appended to the front.

how joomla htaccess identifies what is the get method for particular alias?

Im developing a website which supports SEF urls. I use PHP as serverside language. I know htaccess basic codes how works with it. But the problem is if I want to rewrite a php get link I have to put each both links on htaccess like this.
RewriteRule ^sign-in$ index.php?view=signin
RewriteRule ^register$ index.php?view=register
RewriteRule ^jobs$ index.php?id=2
Is there any possible way to automate urls with htaccess and url particular alias instead of adding Rewrite rules manually? something like joomla? I was trying to understand how joomla htaccess connects with particual alias. But I still couldn't understand how it works. I cant uderstand how joomla htaccess makes relationship with article aliases. Please help. Thanks in advance.
If there isn't any difference for how an id looks like compared to how a view looks like (in your example, register is a view and jobs is an id=2), then you have to do one or the other individually:
To "automate" the views you could try just doing this:
RewriteEngine On
# all id's here:
RewriteRule ^jobs$ index.php?id=2 [L]
RewriteRule ^something-else$ index.php?id=3 [L]
RewriteRule ^another$ index.php?id=4 [L]
# this will do all views
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?view=$1 [L]
EDIT: If you need to do these mappings via an external set of aliases, you need to take a look at the RewriteMap directive. You will need to have access to the server or vhost configs in order to setup the map, but your rules can stay in an htaccess file.
Say you have a text file called "joomla_maps.txt" that looks like:
jobs id=2
another id=3
sign-in view=sign-in
register view=register
etc...
You can use that mapping by setting it up in a RewriteMap (in vhost/server config)
RewriteMap joomla txt:/path/to/joomla_maps.txt
And later in your htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?${joomla:$1} [L]
Take a look through the RewriteMap docs to get some examples of other kinds of maps, including executing a script or using a dbm hash map.

how to rename a module in the url with mod_rewrite

I'm using MVC with /<module>/<controller>/<action>/ have a module at example.com/module/whatever, and I need to 'rename' it to example.com/module-a/whatever. The whole application is already written, so I can't go through and change it everywhere in my code, so I'm hoping to do it with mod_rewrite. I've tried the following
RewriteCond %{THE_REQUEST} ^GET\ /module/
RewriteRule ^module/(.*) /module-a/$1 [L,R=301]
which did what I wanted as far as redirecting all urls like example.com/module/whatever to example.com/module-a/whatever, but now I need all requests at 'module-a' to be internally rewritten as 'module'. It also needs to work for the module root (i.e. example.com/module with no trailing slash). Is this possible? I added
RewriteRule ^module-a/(.*)$ module/$1
directly beneath the above condition and rule, but when the page is accessed, it still says the module 'module-a' is not found.
Edit:
I have a few more rules below those, I wouldn't think they would affect this, but here they are anyway:
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Solution
I ended up using
RewriteCond %{THE_REQUEST} ^GET\ /module/
RewriteRule ^module$ /module-a [L,R=301]
RewriteRule ^module/(.*) /module-a/$1 [L,R=301]
to redirect all links from module to module-a. I had to do it with 2 rules because I don't know regex well enough to combine them, handling the special case of the url example.com/module.
To rewrite internally, the original rule I had would normally work, but Zend seems to do some stuff that overrides that, so I had to handle it with routes. See rename a zend module with routes
If I understand correctly then you've gone about this from the wrong direction. I am also not clear on the purpose of your RewriteCond
You want all module-a/* requests to be processed internally as module/*, so all you need is a simple rewrite::
RewriteRule ^module-a/?(.*) /module/$1 [L]
I suspect the problem you are having is the internal links on the site all reference /module/ rather than /module-a/, but putting a 301 there will cause no end of problems (not least with search engines), and with the subsequent rewrite you may fall into circular references. You are much better off changing the link code in your app (if you have a link abstraction class), or at worst using output buffering to swap all links out before rendering the page.
Note: The second rule below the above is not being processed if the first matched, as [L] causes mod_rewrite to cease processing if that rule is matched.

How do I redirect all but one url to a script

I'm trying to get www.example.com and www.example.com/index.html to go to index.html, but I want all other urls e.g. www.example.com/this/is/another/link to still show www.example.com/this/is/another/link but be processed by a generic script. I've tried
RewriteEngine on
RewriteCond %{REQUEST_URI} !^index\.html$
RewriteCond %{REQUEST_URI} !^$
RewriteRule ^(.*)$ mygenericscript.php [L]
but it wont work, can someone please help?
Instead of testing what %{REQUEST_URI} is, you can instead just test if the resource exists:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* mygenericscript.php
This prevents your static resources (images, stylesheets, etc.) from being redirected if they're handled through the same directory your .htaccess is in as well.
What's probably happening now is that you're seeing an internal server error, caused by an infinite internal redirection loop when you try to access anything that isn't / or /index.html. This is because .* matches every request, and after you rewrite to mygenericscript.php the first time, the rule set is reprocessed (because of how mod_rewrite works in the context that you're using it in).
The easiest to do this is to install a 404-handler which gets executed when the server does not find a file to display.
ErrorDocument 404 /mygenericscript.php
or
ErrorDocument 404 /cgi-bin/handler.cgi
or similar should do the trick.
It is not that RewriteRule's can not be used for this, it is just that they are tricky to set up and requires in depth knowledge on how apache handles requests. It is a bit of a black art.
It appears as if you're using PHP, and you can use auto_x_file (x is either append or prepend:
http://php.net/manual/en/ini.core.php

Resources