htaccess and URL rewriting - .htaccess

I have a list of URLs such as,
http://www.mywebsite.com/page.php?genus=A_GENUS&species=A_SPECIES&id=12345.
I would like to write a .htaccess which permanently redirects visits to this form of URL to the following URL,
http://www.mywebsite.com/species/A_GENUS/A_SPECIES.
Is it possible to do this without having to manually list each species in the database?
I've tried to look it up but my head is in WordPress-Custom-Post-Type land and as such my brain isn't functioning properly. Any help would be greatly appreciated.
EDIT: Clarification
Currently my .htaccess is completely empty. I am re-writing my website to use an entirely new CMS and this new URL format. The old URL format will cease to exist but all of the information will still be used.
We are quite highly ranked for a lot of species on Google and I would like visitors from there to be able to view the information they require despite the URL format changing.
These changes haven't occurred yet (still using a Sandbox environment for the new version of the site) and I'd like to make the URL changes just before I "go live" with the new version.
EDIT 2: New site .htaccess
The contents of the new site's .htaccess looks like this in its entirety:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /sandboxfolder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /sandboxfolder/index.php [L]
</IfModule>
# END WordPress
EDIT for Garmen's answer
RewriteEngine On
RewriteBase /sandboxfolder/
RewriteCond %{QUERY_STRING} genus=([a-zA-Z0-9-]+)&species=([a-zA-Z0-9-]+)
RewriteRule ^profile.php$ /species/%1/%2 [R=302]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /sandboxfolder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /sandboxfolder/index.php [L]
</IfModule>
# END WordPress
Not sure if I've used RewriteBase correctly there, but it doesn't appear to function with or without it.
Regards,

RewriteEngine On
RewriteCond %{QUERY_STRING} genus=([a-zA-Z0-9-]+)&species=([a-zA-Z0-9-]+)
RewriteRule ^page.php$ /species/%1/%2? [L,R=302]
This one assumes a very specific order of query string parameters. So be warned. Also it assumes the names only contains plain letters, numbers, or dashes.
Change 302 to 301 when you are done testing. I used 302 because 301's are aggressively cached by browsers, making debugging very difficult.
EDIT: You should add this above the other rewrite rules you have, or it will not work.
EDIT 2: added a ? at the end to remove the querystring. And L flag to prevent further execution.

Related

Using .htaccess to change directory in url

I am trying to change the url that is displayed in the address bar from mysite.com/blog/wedding-hair/ to mysite.com/services/wedding-hair/ using .htaccess.
Using answers from:
https://stackoverflow.com/questions/8713319/assigning-different-name-to-existing-folder-in-url-in-htaccess
rewrite a folder name using .htaccess
Replace directory name in url with another name
I added to the .htaccess file. Here is the .htaccess file, I added the last rewrite rule:
Options -Indexes
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mysite.com$
RewriteRule ^/?$ "http\:\/\/www\.mysite\.com" [R=301]
RewriteRule ^blog/(.*)$ /services/$1 [L]
the non-www redirect works but not the blog-services rewrite. I thought maybe I had the directory names reversed but changing them around doesn't work either. I have tried adding and removing /'s around the directory names in all of the different combinations. I tried adding
RewriteCond %{THE_REQUEST} ^GET\ /blog/
before my RewriteRule. Nothing I Have tried has worked, the displayed url remains mysite.com/blog/wedding-hair/
I am sure this is pretty straight forward for someone but I am unable to get this correct. Any help would be appreciated.
When I was working on this yesterday I didn't think about the fact that the blog directory is a WordPress install. Here is the .htaccess file that is in the blog directory:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
I have tried adding my RewriteRule in this file but still no joy.
The problem here is that RewriteRule ^blog/(.*)$ /services/$1 [L] internally rewrites the URI, so that the browser doesn't know it's happening, this happens entirely on the server's end. If you want the browser to actually load a different URL, you need to use the R flag like you are in your www redirect, though it's only redirecting requests to root. If you want it to redirect everything to include the "www", you want something like this:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
Then to redirect "blog" to "services", just add the R flag (or R=301 if you want the redirect to be permanent).
RewriteRule ^blog/(.*)$ /services/$1 [L,R]
And, if for whatever reason your content isn't actually at /blog/, you need to internally rewrite it back
RewriteCond %{THE_REQUEST} ^GET\ /services/
RewriteRule ^services/(.*)$ /blog/$1 [L]
But this is only if your content is really at /blog/ but you only want to make it appear that it's at /services/.
Actually, in such case, as you have a specific field in Wordpress options to handle the display of a different url, it CAN'T work with .htaccess is the WordPress rules are executed at the end.
And it would be much simpler to use the field "Site Address (URL)" in the General Settings, and enter "mysite.com/services/"
If you don't do that, in spite of your .htaccess, the WP internal rewriting will use you installation repertory

mod rewrite doing something weird

http://localhost/clean_urls/user/whtffgh redirect fine to this http://localhost/clean_urls/user/whtffgh/ (pretty much anything I put there works).
http://localhost/clean_urls/user/cohen however, redirects to this
http://localhost/clean/ and I have no idea why. It should just add a /
Heres my .htaccess code
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /clean_urls/user/$1/ [L,R=301]
RewriteBase /clean_urls/user/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9]+)/$ index.php?user=$1
</ifModule>
UPDATE:
The code works besides when I put cohen as the username. The second part of the .htaccess file is making user/index.php?user=username look like user/username so its just a $_GET variable that looks nice in the url and is SEO friendly (apparently).
I am just learning this stuff and making a webapp to try it out so not really sure where its going but I do think I will need another variable on the end. http:://localhost/clean_urls/user/fred/someverb
You misunderstand what the RewriteBase directive is used for. It helps the rewrite engine in a "per directory" context to convert the relative URIs to the correct filename equivalent.
You should only have one RewriteBase directive per .htaccess file. The rewrite engine by default will use the lowest .htaccess file on the path with the RewriteEngine On directive set.
So in DOCroot (that is the directory where a "GET /xxx" is mapped to, this should be
RewriteBase /
If your .htaccess file is in DOCroot/clean_urls/user then it should have
RewriteBase /clean_urls/user/
How do you want to decode URIs of the form http:://localhost/fred or are you only wanting do process URIs of the form http:://localhost/clean_urls/user/fred/. What about http:://localhost/clean_urls/user/fred/someverb?
Let me know and where you are putting you .htaccess then I can give you the right content.

SocialEngine - 301 redirection of old site pages .htaccess

I installed SocialEngine to replace an old CMS. The problem is that a lot of old URLs are present in the search engines. I would like to redirect them to the corresponding URLs on the current website (because at this time they only redirect to the homepage).
All the content of my old CMS was imported into SE, so each old page has its equivalent now.
For example :
old address : /index.php?mod=news&ac=commentaires&id=367
new address : /articles/367
I tried to add in my .htaccess something like :
redirectmatch 301 index.php?mod=news&ac=commentaires&id=([0-9]+) http://www.nailissima.fr/articles/$1
But it doesn't work. When I type the old address, it still redirects to the homepage, not to the corresponding article.
Would you please help me to solve that ?
Here is my .htaccess :
# $Id: .htaccess 7539 2010-10-04 04:41:38Z john $
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
# Get rid of index.php
RewriteCond %{REQUEST_URI} /index\.php
RewriteRule (.*) index.php?rewrite=2 [L,QSA]
# Rewrite all directory-looking urls
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*) index.php?rewrite=1 [L,QSA]
# Try to route missing files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} public\/ [OR]
RewriteCond %{REQUEST_FILENAME} \.(jpg|gif|png|ico|flv|htm|html|php|css|js)$
RewriteRule . - [L]
# If the file doesn't exist, rewrite to index
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rewrite=1 [L,QSA]
</IfModule>
# sends requests /index.php/path/to/module/ to "index.php"
# AcceptPathInfo On
# #todo This may not be effective in some cases
FileETag Size
Thank you in advance !
Best regards
Possibly you have the problem with order of your redirects instructions.
First disable with comments all your current general rules and try your new redirects alone.
If they work, then attentivly think where you should place them.
[L] at the end of instruction makes it last, so it this instruction matches, not further will process.
Using this, write more detailed instructions first, and more general later, otherwise, you can meet situation when further instructions overright your current!

Htaccess friendly SEO rewrite made images stop loading?

I used a generator to make my SEO friendly htaccess rewrite, here it is.
RewriteRule ^([^/]*)/([^/]*) /detail.php?type=$1&?id=$2 [L]
The output should be www.site.com/type/id
Now, the rewrite works and pages redirect fine, BUT the images on the site no longer show up, they're all broken... :( The URL for the images is right but seems it just doesn't want to load anymore, any help? Should there be another Rewrite rule to cancel out this one from doing other stuff? If so, what?
Your existing rule could affect images. To prevent that, use a RewriteCond directive that will exlcude extensions for images etc. being affected by the rule You can add other extensions as necessary.
#if its not an image, css, js etc
RewriteCond %{REQUEST_URI} !\.(gif|jpg|png|css|js|etc)$ [NC]
RewriteRule ^([^/]*)/([^/]*) /detail.php?type=$1&?id=$2 [L]
I'm not sure how your .htaccess looks like, but here is handy rules that I'm using for my projects, it's pretty simple and covers most of the problems:
<IfModule mod_rewrite.c>
############################################
# Enable mod_rewrite
RewriteEngine On
RewriteBase /
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|assets)/
############################################
# never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .*$ index.php [L]
</IfModule>

How to use rewriterules in .htaccess to change url?

I'm using this rewriterule:
RewriteRule ^page/([^/]*)$ http://example.com/page?q=$1 [QSA,L]
If I go to example.com/page/somePage I get redirected to example.com/page?q=somePage
But I don't want a redirection, what I want is the URL to always be example.com/page/somePage
How to do this?
Thank you
I removed http://example.com but it doesn't work, I get Page not Found.
I am using Wordpress for my site, this is my complete .htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^page/([^/]+)/?$ page?q=$1 [L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Whenever you specify the http:// at the beginning of the path to be rewritten to, Apache will always force a 301 redirect to the new URL, whether the URL is on the same website or not. Simply removing the http://example.com part should fix your problem.
As for the page not found, is there another RewriteRule somewhere that tells just 'page' to be processed as 'page.php' or something of the sort? Do you have your PHP files saved without extensions?
Well then your problem is you definitely need to remove the [L] flag because you're telling Apache not to process any more RewriteRules for that request, so it never looks at the WordPress rewrites because that rule was already executed and Apache was told that should be the final rule. I would recommend leaving the [QSA] in the line though, that would not affect the overall outcome of your script.

Resources