Forum Moderators: phranque
I'm working on a client's new website. The old website's product pages are all still indexed in google with good pagerank and rankings.
The old site's product pages were dynamic php pages which use a query string to determine which product is which.
They are formatted like this:
http://www.example.com/products/products_detail.php?news_id=0028
news_id being the product identifier.
I want to 301 redirect these pages to their new static product pages. I want widgetA's product page to redirect to widgetA's new product page, and widgetB's product page to redirect to widgetB's new product page.
My problem is this: 301 redirects don't take the string into account, only the filename. Therefore it will only redirect from the page products_detail.php, and not products_detail.php?news_id=0028
Every new product page is static.
I am trying to do this in .htaccess
If anyone can help me it would be greatly appreciated!
Many Thanks,
Henry
[edited by: Saurus_Henry at 12:10 pm (utc) on Sep. 26, 2008]
php_flag session.use_trans_sid off
php_flag register_globals on
php_flag safe_mode off
php_flag open_basedir off
Options +FollowSymLinks
RewriteEngine On
rewritecond %{http_host} ^example.co.uk
rewriteRule ^(.*) http://www.example.co.uk/$1 [R=301,L]
rewriteCond %{QUERY_STRING} ^news_id=(.*)$
rewriteRule ^products/products_detail\.php$ /products/%1.html? [R=301,L]
redirect 301 /products/0028.html http://www.example.co.uk/index2.php/cPath/0_76_84
***
Does anyone know how to condense it so that only one redirect takes place?
thanks!
H
[edited by: Saurus_Henry at 1:30 pm (utc) on Sep. 26, 2008]
To prevent sequential redirects and rewrites and to minimize unexpected problems, put you rules in order: External redirects first, ordered from most-specific to least-specific, followed by internal rewrites, again from most-specific to least-specific.
By 'specific' I mean 'selective'. That is, rules with more-specific patterns affecting the fewest number of URLs should generally go first, and the non-www-to-www domain redirect should almost always be the last external redirect.
Be sure to escape all literal periods within regex patterns by preceding them with a "\". Otherwise, the period is taken as a regex token meaning "match any single character."
RewriteEngine On
#
RewriteCond %{QUERY_STRING} ^news_id=(.+)$
RewriteRule ^products/products_detail\.php$ http://www.example.co.uk/products/%1.html? [R=301,L]
#
RewriteRule ^products/0028\.html$ http://www.example.co.uk/index2.php/cPath/0_76_84 [R=301,L]
#
RewriteCond %{HTTP_HOST} ^example\.co\.uk
RewriteRule (.*) http://www.example.co.uk/$1 [R=301,L]
Jim
Note, also, the change on the very first RewriteCond, which now allows the redirect to happen even if extra/dummy parameters are present, and that those extra parameters are dumped during the redirect.
RewriteEngine On
#
RewriteCond %{QUERY_STRING} &?news_id=(.+)&?
RewriteRule ^products/products_detail\.php$ http://www.example.co.uk/products/%1.html? [R=301,L]
#
RewriteCond %{HTTP_HOST} ^example\.co\.uk
RewriteRule (.*) http://www.example.co.uk/$1 [R=301,L]
#
RewriteRule ^products/0028\.html$ /index2.php/cPath/0_76_84 [L]
You only have one parameter in the URL, so you can simplify this quite a bit:
External URL Format: www.example.com/345/1234567
Internal Server Path: /index.php?cat=345&art=1234567
# Specify acceptable index/root file. You could have a static
# index.html or allow index.php without parameters for root:
DirectoryIndex index.html index.php # Redirect to remove trailing period or comma from URL request
# with parameters, such as from forum with autolink, and force
# www to always be in the URL:
RewriteCond %{QUERY_STRING} ^(([^&]+&)*)[.,]$
RewriteRule (.*) http://www.example.com/$1?%1 [R=301,L] # Redirect to remove trailing period or comma from URL request
# with path, such as from forum with autolink, and force www:
RewriteRule ^(([^/]+/)*)[.,]$ http://www.example.com/$1 [R=301,L] # Redirect two-parameter-based index.php¦html? or / URL request
# (with parameters in any order) to folder-based URL format, and
# force www to always be in URL:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.(php¦html?))?(\?[^\ ]*)\ HTTP/ [NC]
RewriteCond %{QUERY_STRING} &?cat=([0-9]{3})&?
RewriteCond %1>%{QUERY_STRING} ^([^>]+)>([^&]*&)*art=([0-9]{7})&?
RewriteRule ^(index\.(php¦html?))?$ http://www.example.com/%1/%3? [R=301,L] # Force all remaining requests for named index files to drop
# the index file filename, and force www:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]*/)*index\.(html?¦php)(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]*/)*)index\.(html?¦php)$ http://www.example.com/$1 [R=301,L] # General rule to force all non-www URLs to be www URLs.
# This rule must be the last one of the redirects:
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L] # Rewrite such that stray parameters or value names on any index.html?
# or any index.php URL or on / URL request always fail to the
# 404 page:
RewriteCond %{QUERY_STRING} .
RewriteRule ^(index\.(php¦html?))?$ /this.page.does.not.exist [L] # Rewrite URL request: www.example.com/345/1234567 to internal
# path: /index.php?cat=345&art=1234567 to serve content:
RewriteRule ^([0-9]{3})/([0-9]{7})$ /index.php?cat=$1&art=$2 [L] Website now only directly responds with content as "200 OK" for paths like / and /345/1234567 and all other formats either redirect or fail to the 404 Error Page if a real file does not exist. It does this without having to do server-intensive !-d and !-f checks on the filesystem.
The site root can be implemented either as a static index.html page or by using index.php without any parameters. The script will also need to check that parameters are present, and that the values are acceptable, and fail to the internally script-generated 404 Error Page if not.
The rules in the .htaccess file restrict certain URL requests from ever reaching the filesystem on the server. They are redirected or failed to a 404 immediately.
[edited by: jdMorgan at 3:14 pm (utc) on Sep. 26, 2008]
[edit reason] Disabled graphic smile faces in code [/edit]