You are here:  » Redirect Old Pages to Mapped Product


Redirect Old Pages to Mapped Product

Submitted by gregor on Fri, 2011-11-04 03:52 in

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

Submitted by support on Fri, 2011-11-04 09:31

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

Submitted by gregor on Tue, 2011-11-08 03:54

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

Submitted by support on Tue, 2011-11-08 09:58

Hi Gregor,

You were right to leave it in place I have corrected the modification instructions above also;

Cheers,
David.
--
PriceTapestry.com

Submitted by stevewales20 on Wed, 2013-08-14 12:54

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

Submitted by support on Wed, 2013-08-14 12:59

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

Submitted by stevewales20 on Wed, 2013-08-14 13:36

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

Submitted by support on Wed, 2013-08-14 14:12

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

Submitted by stevewales20 on Wed, 2013-08-14 16:52

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?

Submitted by support on Wed, 2013-08-14 17:16

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

Submitted by stevewales20 on Wed, 2013-08-14 21:17

Thanks alot,

I'll see about getting that converted over to nginx and see how I get on. Your a star!

Steve

Submitted by stevewales20 on Sat, 2013-08-17 19:14

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

Submitted by support on Sun, 2013-08-18 11:25

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

Submitted by smartprice24 on Thu, 2017-12-14 10:24

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

Submitted by support on Thu, 2017-12-14 11:35

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

Submitted by smartprice24 on Thu, 2017-12-14 13:14

Thanks David! Work fine!

Good weekend!

Giuseppe