David,
Is it possible to Mod Rewrite the search results into search engine firendly URLs? If possible I would like to change, for instance, http://www.the-big-business-directory.com/uk_directory/online_shopping/search.php?q=dvd&page=2&sort=relevance to http://www.the-big-business-directory.com/uk_directory/online_shopping/search/dvd/2/relevance.
Thanks
Stephen
The Big Business Directory
http://www.the-big-business-directory.com
http://www.the-big-business-directory.co.uk
http://www.the-big-business-directory.org
http://www.the-big-business-directory.org.uk
Hello Stephen,
My apologies for the delay getting back to you on this.
It can actually be achieved with far less code modification by following the existing search engine friendly URL structure that is supported by search.php for the merchant / category / brand searches. These are of the format:
http://www.example.com/merchant/Merchant-Name/
...with follow on pages being:
http://www.example.com/merchant/Merchant-Name/2.html
etc. etc.
This means that by making the normal query search engine friendly URLs take the following example structure (using "dvd" as the query), we can re-use the code that already exists to do the above:
http://www.example.com/search/relevance/dvd/
...with follow on pages being:
http://www.example.com/search/relevance/dvd/2.html
etc. etc.
To do this, first the new rewrite rules need to be added to .htaccess as follows:
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/$ search.php?sort=$1&q=$2&rewrite=1&%{QUERY_STRING} [L]
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/(.*).html$ search.php?sort=$1&q=$2&page=$3&rewrite=1&%{QUERY_STRING} [L]
Secondly, a check needs to be added at the top of search.php to see if we are in a re-written URL, and redirect to it if not. To do this, look for the following code on line 10:
$rewrite = isset($_GET["rewrite"]);
...and ADD the following new code immediately afterwards:
if (!$rewrite)
{
$location = $config_baseHREF."search/".$sort."/".tapestry_hyphenate($q)."/";
if ($page > 1)
{
$location .= $page.".html";
}
header("Location: ".$location);
exit();
}
At this stage, check a basic search, and then the follow-on pages (2,3,4 etc.) are working OK. Finally, the links to change sort order need to be modified to use the new, search engine friendly URLs. To do this, look for the following block of code, beginning at line 107 of search.php:
$sortHREF = $config_baseHREF."search.php?q=".urlencode($q)."&page=1&sort=";
$sortRelevance = ($sort=="relevance"?"<strong>".translate("Relevance")."</strong>":"<a href='".$sortHREF."relevance'>".translate("Relevance")."</a>");
if ($config_useInteraction)
{
$sortRating = ", ".($sort=="rating"?"<strong>".translate("Product Rating")."</strong>":"<a href='".$sortHREF."rating'>".translate("Product Rating")."</a>");
}
else
{
$sortRating = "";
}
$sortPriceAsc = ($sort=="priceAsc"?"<strong>".translate("Low to High")."</strong>":"<a href='".$sortHREF."priceAsc'>".translate("Low to High")."</a>");
$sortPriceDesc = ($sort=="priceDesc"?"<strong>".translate("High to Low")."</strong>":"<a href='".$sortHREF."priceDesc'>".translate("High to Low")."</a>");
...and REPLACE this with the following new version:
$sortHREF = $config_baseHREF."search/%SORT%/".tapestry_hyphenate($q)."/";
if ($page > 1)
{
$sortHREF .= $page.".html";
}
$sortRelevance = ($sort=="relevance"?"<strong>".translate("Relevance")."</strong>":"<a href='".str_replace("%SORT%","relevance",$sortHREF)."'>".translate("Relevance")."</a>");
if ($config_useInteraction)
{
$sortRating = ", ".($sort=="rating"?"<strong>".translate("Product Rating")."</strong>":"<a href='".str_replace("%SORT%","rating",$sortHREF)."'>".translate("Product Rating")."</a>");
}
else
{
$sortRating = "";
}
$sortPriceAsc = ($sort=="priceAsc"?"<strong>".translate("Low to High")."</strong>":"<a href='".str_replace("%SORT%","priceAsc",$sortHREF)."'>".translate("Low to High")."</a>");
$sortPriceDesc = ($sort=="priceDesc"?"<strong>".translate("High to Low")."</strong>":"<a href='".str_replace("%SORT%","priceDesc",$sortHREF)."'>".translate("High to Low")."</a>");
That should do the trick!
Cheers,
David.
Thanks for all that David, it works perfectly.
I also insert merchant products into merchant pages, i.e. http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/index.php has
<?php
include('http://www.the-big-business-directory.com/uk_directory/online_shopping/search2.php?q=merchant%3AOfficeGiant&'.$_SERVER['QUERY_STRING']);
?>
Thanks
Stephen
Hello Stephen,
The search results returned by your search2.php (if it uses the same code as search.php) should return re-written results if your site as $config_useRewrite enabled; although I may not have completely understood your question. What URLs are not being re-written in the above case?
Cheers,
David.
David,
Sorry for not making myself clear.
The URL http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/index.php, and all the other individual merchant pages in the directory part of the site, currently use the PHP include URL to add the merchants products into the merchants page with links to the further pages, taken from the Online shopping section (http://www.the-big-business-directory.com/uk_directory/online_shopping/index.php - where PT is installed). I have tried to use the rewrite code you gave, but I get a missing page error if I use that when I try to navigate to http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/2.html.
The search2.php file is the search.php file with the header and footer stripped out as it is only being inserted into pages that already have a header and footer.
Yours
Stephen
Hi Stephen,
I understand. I think this will work without any coding changes, if instead of making your merchant directory:
http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/index.php
...you link to:
http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/
(i.e. without the index.php) - which I've just tried on your server and seems to work correctly.
And then, instead of:
<?php
include('http://www.the-big-business-directory.com/uk_directory/online_shopping/search2.php?q=merchant%3AOfficeGiant&'.$_SERVER['QUERY_STRING']);
?>
... add rewrite=1 to the query string, for example:
<?php
include('http://www.the-big-business-directory.com/uk_directory/online_shopping/search2.php?q=merchant%3AOfficeGiant&rewrite=1&'.$_SERVER['QUERY_STRING']);
?>
This should force the navigation links to go to /2.html, /3.html etc., but as you say these won't work until there is a rewrite in place to support these. Can you post the rewrite rules you have got so far and i'll see what needs to be added...
Cheers,
David.
Thanks for that update.
I have tried it and it still doesn't work. I wondered whether it my be because of the navigation.php file? It may be that that will need modification so that the URLs are amended to something different that does work. The rewrite code I have used for the search is exactly as you gave above.
Thanks
Stephen
David,
I have just had an idea, which has worked partially. Inserting the page with search.php?xxxxxx etc. doesn't work, but if I insert the rewritten url i.e. http://www.the-big-business-directory.com/uk_directory/online_shopping/search/relevance/dvd/ the results come up correctly. The issue here seems to be that the next page links are http://www.the-big-business-directory.com/uk_directory/online_shopping/2.html etc. which means that somewhere in the code the URL is being taken back 3 directories which it seems is most likely why it won't work.
Yours
Stephen
Hi Stephen,
That makes sense - which is why I think you need another re-write rule to handle the follow on pages (2.html, 3.html etc.). If you could post the re-write that currently generates the merchant indexes i'll try and work out what that should be for you...
Cheers,
David.
David,
All of the merchant rewrite code and rules I have all the standard ones I downloaded after payment was made.
Yours
Stephen
Hi Stephen,
What needs to be supported, is that in addition to your new re-written (i'm assuming) URLs for example:
http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/
http://www.the-big-business-directory.com/uk_directory/office_supplies_and_equipment/officegiant/2.html
Once this is supported, the previous change of adding rewrite=1 to the Price Tapestry URL that you are include()'ing will need to be put back, as this makes the navigation links use /2.html etc. rather than the full, non-rewritten URL.
Could you perhaps post your current .htaccess so that I can see how it is all working together and work out how to add support for this for you... (you can post it into the forum using the <code> ... </code> tags)
Cheers,
David.
David,
Thanks for all of that. I currently have 2 .htaccess files.
The first has
ErrorDocument 300 http://www.the-big-business-directory.com/error.php
ErrorDocument 400 http://www.the-big-business-directory.com/error.php
ErrorDocument 403 http://www.the-big-business-directory.com/error.php
ErrorDocument 404 http://www.the-big-business-directory.com/error.php
ErrorDocument 500 http://www.the-big-business-directory.com/error.php
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.the-big-business-directory.com$ [NC]
RewriteRule ^(.*)$ http://www.the-big-business-directory.com/$1 [L,R=301]
The second, which originally came with PT, has
Options -MultiViews
RewriteEngine On
RewriteBase /uk_directory/online_shopping/
RewriteRule ^product/(.*).html$ products.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
RewriteRule ^review/(.*).html$ reviews.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
RewriteRule ^merchant/$ merchants.php
RewriteRule ^merchant/(.*)/$ search.php?q=merchant:$1:&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^merchant/(.*)/(.*).html$ search.php?q=merchant:$1:&page=$2&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^category/$ categories.php
RewriteRule ^category/(.*)/$ search.php?q=category:$1:&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^category/(.*)/(.*).html$ search.php?q=category:$1:&page=$2&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^brand/$ brands.php
RewriteRule ^brand/(.*)/$ search.php?q=brand:$1:&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^brand/(.*)/(.*).html$ search.php?q=brand:$1:&page=$2&rewrite=1%{QUERY_STRING} [L]
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/$ search.php?sort=$1&q=$2&rewrite=1&%{QUERY_STRING} [L]
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/(.*).html$ search.php?sort=$1&q=$2&page=$3&rewrite=1&%{QUERY_STRING} [L]
Yours
Stephen
Hi Stephen,
Just looking back over the way you have implemented this; getting the follow on URLs to be rewritten is going to be very tricky when including the pages via HTTP. This is because the script creates the onwards rewritten URLs based on the current URL of the page, and this is of course the URL being included, not the URL that is in the browser window.
As these sites are on the same server, could you investigate creating your merchant specific pages using a rewrite rule and then including the Price Tapestry directly instead of HTTP? This would involve setting the appropriate $_GET[""] variables, and then using (hopefully i've got this right):
require("../../online_shopping/search2.php");
So, taking the Office Giant example from this thread, instead of:
<?php
include('http://www.the-big-business-directory.com/uk_directory/online_shopping/search2.php?q=merchant%3AOfficeGiant&'.$_SERVER['QUERY_STRING']);
?>
Try this:
<?php
$_GET["q"] = "merchant:OfficeGiant";
require("../../online_shopping/search2.php");
?>
If this works, then it should be much easier to create re-written follow on links the way you want....
Cheers,
David.
Hello!
I was able to get the mod rewrite to work as described above but the product links were redirecting to the wrong product page.
I was getting links like:
mysite.com/directory/search/product/product-name.html
while it should be
mysite.com/directory/product/product-name.html (This works for the brands, merchant and category pages)
ideally I would rather have the mod rewrite be more like
mysite.com/directory/search/search-terms/ then what was showing, something like mysite.com/directory/search/sort/relevance/search-terms/
Can this be done with mod rewrite? I suppose it can :) I tried making some modifications to the htaccess file with no luck.
This is the original search is on my site:
http://www.mysite.com/directory/search.php?q=easton+skate
to be:
http://www.mysite.com/directory/search/easton-skate/ ?
Thanks!
Hi,
This is happening because search.php is generating the link as relative rather than absolute. It's easy to change it over. In that file, look for the following code (starting at line 143):
$searchresults["products"][$k]["productHREF"] = "product/".tapestry_hyphenate($product["name"]).".html";
if ($rewrite) $searchresults["products"][$k]["productHREF"] = "../../".$searchresults["products"][$k]["productHREF"];
...and REPLACE this with just:
$searchresults["products"][$k]["productHREF"] = $config_baseHREF . "product/".tapestry_hyphenate($product["name"]).".html";
That should sort it!
Cheers,
David.
Very useful thread thanks! Stumbled across this when wanting to do the very same thing. Have managed to implement the changes suggested and the all important last issue whereby it was also generating the link as relative rather than absolute, resulting in a 404. Sorted now and the resulting URLs are so much more SEO & user friendly.
Hi Dave,
I have just modified code from this post all work great but i have just test some old url listed in google results is it possible to rewright old product urls with new ones
Example:
http://www.bargainshack.co.uk/product/3Com-16-Port-10100-OC-Plus-Switch.html
to this
http://www.bargainshack.co.uk/search/product/3Com-16-Port-10100-OC-Plus-Switch.html
cheers darren
Hello Darren,
With the old URLs still ranking in Google, the best thing to do would be to set it up so that it issues a 301 "Moved Permanently" redirect from the old product URL to the new product URL. This will tell search engines to update their index for the old pages.
To do this, look for the current product rule in .htaccess:
RewriteRule ^product/(.*).html$ products.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
...and change this to:
RewriteRule ^product/(.*).html$ search/product/$1.html [R=301,L]
Hope this helps,
Cheers,
David.
Hi Dave,
Found another little problem since intergrating seo urls the articles code you done for me now point to the wrong file path this is what i have
http://www.bargainshack.co.uk/search/relevance/mig-welders-195amp/articles/Stabil-250mm-Welders-Clamp-From-Bessey-Germany-World-Of-DIY.html
need to be
http://www.bargainshack.co.uk/articles/Stabil-250mm-Welders-Clamp-From-Bessey-Germany-World-Of-DIY.html
Your article code
<?php
$articleFilename = "articles/".str_replace(" ","-",$product["name"])."-".str_replace(" ","-",$product["merchant"]).".html";
if (file_exists($articleFilename))
{
print "<a href='" . $articleFilename .
"'><font color=\"#006600\">Read Product Article</font></a>"; }
?>
many thanks
Darren
Hello Darren,
The $articleFilename will be correct because the rewriting doesn't affect that. What you can do for the href is to add $config_baseHREF to the URL, like this:
<?php
$articleFilename = "articles/".str_replace(" ","-",$product["name"])."-".str_replace(" ","-",$product["merchant"]).".html";
if (file_exists($articleFilename))
{
print "<a href='" . $config_baseHREF.$articleFilename ."'><font color=\"#006600\">Read Product Article</font></a>";
}
?>
That should do the trick!
Cheers,
David.
Hi Dave,
Again you shine my friend from a novice you loves PHP but my brain is just not mapped to understand the way the code works i have tried for over 6 years but still get baffled, I should have stayed at school all those years ago I hold my hat off to you Dave you amaze me on your code skills.
Many thanks Again
All the best
Darren
Hello Mr David,i try this snippet and work fine with normal search,the only exception is that the pricemod (i download from you) don t work with modifications above. What can i do to get it working with pricemod ?
I already try for get it work and on forum i can t find anything.
Thank you.
Hi,
I don't think anyone has tried to combine the search rewrite with the min/max price mods yet! I really need to know where you are at the moment so that I can check it out for you.
Can you email to me (reply to your reg code or forum registration email)
- a link to your site
- your modified .htaccess
- your modified search.php
I will then take a look at the changes for you!
Cheers,
David.
Hi,
I am trying to implement this search mod rewriting but have got in to a bit of a muddle I think! I'm now getting 'redirect loop' errors. I think the header is being set correctly as when I run the search, get the error (using Firefox), remove the 'header set' piece of code, refresh the page, the header looks correct.
Any ideas on what would cause this?
Cheers.
Keeop
Hello Keeop,
A re-write loop would indicate that the $rewrite variable; which should prevent this; is not being set within the internally re-written URL. Perhaps the easiest thing to do is if you want to email me your .htaccess and search.php i'll check them over for you...
Cheers,
David.
Using this has caused all my modifications for http://www.pricetapestry.com/node/892 to stop working. What can I change to make this work? It appears to be maybe related to search.php changes?
Hi,
Yes - what will have happened is that the redirection to the rewritten search URL is taking place before your code to log the query has happened.
To fix this, look for your query log modification, which should look something like this:
if ($_GET["log"])
{
$sql = "INSERT INTO querylog SET query='".database_safe($q)."'";
database_queryModify($sql,$result);
$sql = "UPDATE querylog SET count=count+1 WHERE query='".database_safe($q)."'";
database_queryModify($sql,$result);
}
CUT that block, out and reposition it higher up the script, inside the redirect block, in other words immediately after the following code:
if (!$rewrite)
{
However, I would modify it slightly as $q may be empty at this point; so after pasting the query log code back in, REPLACE
if ($_GET["log"])
with:
if ($_GET["log"] && $q)
So you should end up with something like...
if (!$rewrite)
{
if ($_GET["log"])
{
$sql = "INSERT INTO querylog SET query='".database_safe($q)."'";
database_queryModify($sql,$result);
$sql = "UPDATE querylog SET count=count+1 WHERE query='".database_safe($q)."'";
database_queryModify($sql,$result);
}
...
If you're not sure, email me your search.php as it is and I'll re-arrange the code for you...
Cheers,
David.
David,
As always thank you very much. I have one other slight issue. Once I do all that everything works fine but I have my site setup to list URLS as www.site.com/product/xbox-360/ instead of www.site.com/product/xbox-360.html. If I edit the files to change .html to / I get errors when using the bottom next page navigation. It also keeps adding the page numbers to the search string if I modify the files to exclude .html and use /.
Example:
www.site.com/search/relevance/ifrogz/3/4/5/6/7/
Thoughts?
Hi Tommy,
The /2/3/4 effect would indicate that this line of the .htaccess mod:
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/(.*).html$ search.php?sort=$1&q=$2&page=$3&rewrite=1&%{QUERY_STRING} [L]
...has been modified something like:
RewriteRule ^search/(relevance|priceAsc|priceDesc|rating)/(.*)/(.*)/$ search.php?sort=$1&q=$2&page=$3&rewrite=1&%{QUERY_STRING} [L]
If you only intended to have product pages appear as /Product-Name/ instead of /Product-Name.html then the above change wouldn't be required and navigation as 2.html, 3.html etc. would work as normal.
However, if you do wish to have search result navigation pages appear as /2/ /3/ etc. then together with .htaccess modified as described above changes will be required in html/navigation.php:
Look for the following code on line 12:
$prevHREF = $prevPage.".html";
...and REPLACE with:
$prevHREF = "../".$prevPage."/";
Look for the following code at line 58:
$pageOneHREF = "1.html";
...and REPLACE with:
$pageOneHREF = "../1/";
Look for the following code at line 95:
$nextHREF = $nextPage.".html";
...and REPLACE with:
$nextHREF = "../".$nextPage."/";
Hope this helps!
Cheers,
David.
That almost worked. I have a problem where it strips out the search term when changing page using the above codes.
Example:
/search/relevance/college/ goes to /search/relevance/2/ when I click next.
Hi,
I think the safest thing to do in this case is actually to reconstruct the entire URL within html/navigation.php rather than try to determine what level of ../ or ./ is required in each case. To do this, reverting back to the distribution version of html/navigation.php;
Look for the following code on line 12:
$prevHREF = $prevPage.".html";
...and REPLACE with:
$prevHREF = $config_baseHREF."search/".$sort."/".urlencode($q)."/".$prevPage."/";
Look for the following code at line 58:
$pageOneHREF = "1.html";
...and REPLACE with:
$pageOneHREF = $config_baseHREF."search/".$sort."/".urlencode($q)."/";
Look for the following code at line 95:
$nextHREF = $nextPage.".html";
...and REPLACE with:
$nextHREF = $config_baseHREF."search/".$sort."/".urlencode($q)."/".$nextPage."/";
Hope this helps!
Cheers,
David.
That is working better for I have an issue somewhere still because it adds the page number to the search string once I click next.
/search/relevance/college/2/ cause my search for college to become college2.
Hi Stephen,
This is certainly possible - the rewrite part is relatively straight forward; but a lot of code changes will be required to make sure that follow on links are to the re-written pages (which I assume is what you want). I'll have time to work through it with you on Monday if you check back then - starting with .htaccess and then working through the code changes...
Cheers,
David.