I have quite a few mappings to do before the holidays, but I'm worried about all the not founds that will occur when people click on existing links using the old names (from google, etc.). I know I can update .htaccess with proper 301 redirects, but there will be a large number and I would rather not have to do that (risk, maintenance, performance, etc.). I see that the original product name is saved on the database as original_name. I am thinking about adding some code to the Not Found/404 else in products.php to do the following:
If not found
- Query products table against the original_name using $q
- If a match is found - redo all the original code under "if($q)" using the mapped name from the found row (replace $q)
- Show the mapped page to the user, but send the 404 code to remove it from the index
- If no match is found, then do normal 404 logic
Do you see issues with this? Is the original_name column normalised the same way the normalised_name column is and would the new select work correctly? I don't even see where these columns are populated in the first place. Do you have any other ideas for this? Do you think it's worth it to do this or should I just let the normal 404 logic handle it?
If I instead add the 301s to .htaccess, could I remove them after a while or would they need to stay in place forever?
Confused! Thank you for any suggestions.
Gregor
Installed this code tonight and it works great. Even easier than I thought it would be. Thanks so much!
I don't know if it's important or not, but I left this line in place rather than replacing it. Is that ok?
$importRecord["original_name"] = $importRecord["name"];
Gregor
Hi Gregor,
You were right to leave it in place I have corrected the modification instructions above also;
Cheers,
David.
--
PriceTapestry.com
Hi David,
Could I implement this pretty easy? Basically i'm changing some of my products because the SEO value is pretty poor, however they're already indexed, would i need to reimport all products for this to work successfully?
I have an issue where i have swapped over the old site from using a bunch of rewrites to using the original url. Now i'm getting a ton of 404's. I'm unsure how i can update google to let them know of the change, any ideas?
Cheers,
Steve
Hi Steve,
Shouldn't be a problem - can you post an example of each style of old (now 404) and equivalent new URL and I'll work out the .htaccess rules for you...
(i'll remove the links before publishing your reply)
Cheers,
David.
--
PriceTapestry.com
Hi david,
That's the problem heh. I have switched my VPS to nginx in the hope of getting more for my money. It runs like a dream btw on nginx. I had shared hosting before and i always had a nightmare. I guess that makes a difference. I don't think you support nginx? I've looked at the rewrites and they're a little confusing and most of the pages out there say the same thing.
I think it would be tedious to have to try and redirect all of them, i let the search engines loose a little early on, and they got into a look in the search filters which now means that the url's are all over the place.
Just wondering if i could put a permanent redirect on the error page? like get nginx to redirect to that page, and then perhaps depending on the url redirect to different places?
Thanks,
Steve
Hi Steve,
There should be uniformity in the rewrite required and wildcards can be used to match these - in other words your previous installation will have been creating URLs in one particular way (the URLs that are now 404), and your new installation in another way, so it can only take 1 RewriteRule to rewrite 1000s of old URLs to their new versions...
(this would have to be done on your error page anyway...)
Do you have a couple of examples of old > new?
Thanks,
David.
--
PriceTapestry.com
These are just some of them.
Old: /c/Category-name/search.php?q=category:toys&subCategoryFilter=blue
New: search.php?q=category:toys&subCategoryFilter=blue
Old: /the-shop/merchant1/merchant2/search.php
New: search.php?q=merchantFilter:The merchant
Old: /name1/name2/name3/categories.php
New: /categories.php
Old: /the-shop/merchant1/merchant2/merchant3/contactus.php
New: /contactus.php
Old: /merchant/search.php
New: /search.php
is it possible to like take for example search.php and its uri and ignore all other information?
Like I said, a real mess :(
I think the best option may be a 404 page that basically 301 permanently?
Hi Steve,
Most should actually be easily catchable, the first, can be caught by pattern, and the remainder (it looks like links may have been created that were not absolute previous) by a generic rule looking for a .php request that is not in the top level.
Have a go with the following, as the first rules immediately following the RewriteBase line (that must always come first)...
RewriteRule ^c/(.*)/search.php(.*)$ search.php?%{QUERY_STRING} [L,R=301]
RewriteRule ^(.*)/(.*).php$ $1.php [L,R=301]
...give it a thorough test of course, and make sure that there are no unintentional redirects of new pages...!
Hope this helps!
Cheers,
David.
--
PriceTapestry.com
Thanks alot,
I'll see about getting that converted over to nginx and see how I get on. Your a star!
Steve
hmm i've tried adding this and it's not working :(
For starters I can't find the header redirect in my version of the products.php.
i've tried adding it into the section where:
$banner["h2"] .= "(".translate("product not found").")";
require("html/featured.php");
The product isn't in the database yet it's still not redirecting. any ideas?
Steve
Hi Steve,
I've just checked the latest products.php that I have from you in email, and assuming that normalised_orignal_name has been added to the database (and feeds re-imported) the code should work at the location you have identified provided that it is inserted _before_ that code. Once html/featured.php has been included the redirect will no longer be able to function because output has already begun...
Cheers,
David.
--
PriceTapestry.com
Hi David. In PT last version there is no line
header("HTTP/1.0 404 Not Found");
how can I implement this feature?
Is possible?
Thanks
Giuseppe
Hello Giuseppe;
For 16/10A, edit products.php and look for the following code at line 78:
$banner["h2"] .= "(".translate("product no longer available").")";
...and REPLACE with:
$sql = "SELECT * FROM `".$config_databaseTablePrefix."products` WHERE normalised_original_name = '".database_safe($q)."' LIMIT 1";
if (database_querySelect($sql,$rows))
{
header("HTTP/1.0 301 Moved Permanently");
header("Location: ".tapestry_productHREF($rows[0]));
exit();
}
else
{
$banner["h2"] .= "(".translate("product no longer available").")";
}
In this case, if the product page is not redirected by a new product mapping thee related products will still show - if you wanted to include the 404 response then you can include that within the else condition, for example;
$sql = "SELECT * FROM `".$config_databaseTablePrefix."products` WHERE normalised_original_name = '".database_safe($q)."' LIMIT 1";
if (database_querySelect($sql,$rows))
{
header("HTTP/1.0 301 Moved Permanently");
header("Location: ".tapestry_productHREF($rows[0]));
exit();
}
else
{
$banner["h2"] .= "(".translate("product no longer available").")";
header("HTTP/1.0 404 Not Found");
}
Cheers,
David.
--
PriceTapestry.com
Hi Gregor,
That makes sense; and you can actually send a 301 Moved Permanently from the code as well as .htaccess which will both redirect the user and inform search engines that the page no longer exists.
For this to work properly, I would actually recommend adding a normalised_original_name field to the products table otherwise only products with a name that doesn't change through normalisation would be found using this method.
The following dbmod.php script will add the field;
<?php
require("includes/common.php");
$sql = "ALTER TABLE `".$config_databaseTablePrefix."products`
ADD `normalised_original_name` VARCHAR(255) NOT NULL";
database_queryModify($sql,$result);
print "Done.";
?>
Next, in includes/admin.php look for the following code at line 267:
$importRecord["original_name"] = $importRecord["name"];
...and REPLACE with:
$importRecord["original_name"] = $importRecord["name"];
$importRecord["normalised_original_name"] = tapestry_normalise($importRecord["name"]);
Finally, in products.php look for the following code around line 72:
header("HTTP/1.0 404 Not Found");
...and REPLACE with:
$sql = "SELECT * FROM `".$config_databaseTablePrefix."products` WHERE normalised_original_name = '".database_safe($q)."' LIMIT 1";
if (database_querySelect($sql,$rows))
{
header("HTTP/1.0 301 Moved Permanently");
header("Location: ".tapestry_productHREF($rows[0]));
exit();
}
else
{
header("HTTP/1.0 404 Not Found");
}
Cheers,
David.
--
PriceTapestry.com