Hi David
Starting a new project and want to make the product page in root ie site.com/productname.html rather than site.com/product/productname.html, is this possible, htaccess seems easy but are there may changes to the script for this to work.
Thanks
Brent
Hi David,
I am using PT in a subfolder as WP is in root and would like to remove product from the url so the products would be at domain.com/pt/abc.html instead of domain.com/pt/product/abc.html.
Is this possible? I am using 12/10A and have tried the above but I can't find any instance of product/ in index.php or products.php.
Many thanks.
Hamish
Hi Hamish,
Even easier in 12/10A as the product URL is generated by a function in includes/tapestry.php. After making the .htaccess changes as described above look for the following code at line 53:
return $config_baseHREF."product/".urlencode(tapestry_hyphenate($product["normalised_name"])).".html";
...and REPLACE that with:
return $config_baseHREF.urlencode(tapestry_hyphenate($product["normalised_name"])).".html";
Cheers,
David.
--
PriceTapestry.com
Thank you.
Tell me, is it as easy to force all urls to be lowercase?
Thanks again.
Cheers,
Hamish
Hi Hamish,
Sure - use the following as the replacement:
return $config_baseHREF.urlencode(tapestry_hyphenate(strtolower($product["normalised_name"]))).".html";
Cheers,
David.
--
PriceTapestry.com
Working nicely, thanks.
Am I right in saying I need to add (strtolower($product.....)) to categories.php, brands.php and merchants.php to make them lowercase, too?
Thanks again for your help.
Cheers,
Hamish
Hi Hamish,
Correct, in each of those files you'll find this line (or similar):
$item["href"] = urlencode(tapestry_hyphenate($product["category"]))."/";
...REPLACE with:
$item["href"] = urlencode(tapestry_hyphenate(strtolower($product["category"])))."/";
Cheers,
David.
--
PriceTapestry.com
Do you not mean
urlencode(tapestry_hyphenate(strtolower($product["category"])))."/";
Just thinking of someone else.
Cheers,
H
Yes, sorry about that! Corrected above also...
Cheers,
David.
--
PriceTapestry.com
Hi David,
Re your answer at the top of this thread about rewriting product page urls to root in .htaccess, I would also like to have brands and categories mapped to root in .htaccess too, as well as products. (Merchants and Reviews not necessary to change).
So
...co.uk/category/Arts-Crafts/ becomes ...co.uk/Arts-Crafts.html
...co.uk/brand/Sony/ becomes ...co.uk/Sony.html
...co.uk/product/teabags.html becomes ...co.uk/teabags.html
My current .htaccess (I am using version 12/10B) is :
{code saved}
Could you please show how this .htaccess file should be rewritten, and any further search and replaces I should do?
Many thanks in advance
Mike
Hello Mike,
The first reply above refers to a few versions prior to 12/10B, and is is much easier modification now since the product URL is returned by a single function tapestry_productHREF(). The category and brand contractions need a little more consideration since there is nothing in the URL to indicate whether it is a category or a brand so this could have performance implications but it would be possible to add additional indexes if this is a problem.
Prepare a replacement .htaccess as follows (based on the distribution version, don't forget to replace any custom modifications such as your ErrorDocument directive etc.)
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^product/(.*).html$ $1.html [L,R=301]
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 ^brand/$ brands.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ search.php?q=catbrand:$1:&rewrite=1&%{QUERY_STRING} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*).html$ search.php?q=catbrand:$1:&page=$2&rewrite=1&%{QUERY_STRING} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ products.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
Before uploading, apply code changes as follows (12/10B)
In includes/tapestry.php look for the following code around line 53:
return $config_baseHREF."product/".urlencode(tapestry_hyphenate($product["normalised_name"])).".html";
...and REPLACE with:
return $config_baseHREF.urlencode(tapestry_hyphenate($product["normalised_name"])).".html";
In sitemap.php look for the following code at line 32:
$sitemapHREF = "product/".urlencode(str_replace(" ","-",$row["normalised_name"])).".html";
...and REPLACE with:
$sitemapHREF = urlencode(str_replace(" ","-",$row["normalised_name"])).".html";
In categories.php look for the following code at line 20:
$item["href"] = urlencode(tapestry_hyphenate($product["category"]))."/"
...and REPLACE with;
$item["href"] = $config_baseHREF.urlencode(tapestry_hyphenate($product["category"]))."/"
In brands.php look for the following code at line 20:
$item["href"] = urlencode(tapestry_hyphenate($product["brand"]))."/"
...and REPLACE with;
$item["href"] = $config_baseHREF.urlencode(tapestry_hyphenate($product["brand"]))."/"
And finally in search.php look for the following code at line 163:
case "bw":
...and REPLACE with:
case "catbrand":
$where = "category = '".database_safe($parts[1])."' OR brand = '".database_safe($parts[1])."'";
$sql = "SELECT SQL_CALC_FOUND_ROWS * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants FROM `".$config_databaseTablePrefix."products` WHERE ".$where.$priceWhere." GROUP BY name";
$orderBySelection = $orderByDefault;
break;
case "bw":
Cheers,
David.
--
PriceTapestry.com
Hi David,
Thanks for your reply. I've started doing the search and replaces, but notice that for categories.php and brands.php the search and replace appear to be the same code. Is this right?
Cheers
Mike
Sorry Mike, replacements for categories.php and brands.php corrected above.
Cheers,
David.
--
PriceTapestry.com
Hi David, thanks for your reply. Product pages rewriting is working fine but categories and brands are rewriting to search.php?.... instead of, eg., ...co.uk/Sony.html as given in the example in my first post above on this thread.
Is this because as most times there will be more than one brand page for say, Sony, it is not possible to rewrite as ...co.uk/Sony.html , ...co.uk/Sony-2.html etc, or that it would be too heavy on resources?
Cheers
Mike
Hello Mike,
Ah, I'd overlooked that in your original email sorry; but the above should be working with
...co.uk/Sony/
This is the way I normally apply this kind of modification as it leaves
...co.uk/Something.html
reserved for product pages.
This also makes pagination far more straight forward and works seamlessly with the existing
navigation code without modification, e.g.
...co.uk/Sony/
...co.uk/Sony/2.html
...co.uk/Sony/3.html
Let me know if that's all working with the above modifications in place (you can still browse brands and categories through /brand/ and /category/ as normal), and then if you would like to pursue an alternative structure I'll help you work towards that...
Cheers,
David.
--
PriceTapestry.com
Hi David, thanks for your response. Will do and I'll report back later. I'm also going to check my search.php as it has been modified from the original (brand filter added).
Cheers
Mike
Hi David,
Yes I rechecked, your modifications for categories and brands do as you suggest.
Thing is, I was hoping instead of .co.uk/Sony/ , .co.uk/Sony/2.html , .co.uk/Sony/3.html etc to get .co.uk/Sony.html , .co.uk/Sony-2.html , .co.uk/Sony-3.html etc as I hoped all category pages and brand pages could be kept to root.
I've reread your comments and it appears this might be considerably more complex to do. Would I be correct in that assumption? Your help is greatly appreciated and at this point would like to know your opinion before taking it further.
Hi Mike,
First of all, create a redirection script called redir.php as follows to be the target of the initial rewrite, and which will decide whether to send the request to products.php or search.php:
<?php
require("config.php");
function redir_normalise($text,$allow = "")
{
global $config_charset;
$text = str_replace("-"," ",$text);
if ($config_charset)
{
$allow = chr(0x80).'-'.chr(0xFF).$allow;
}
$text = preg_replace('/[^A-Za-z0-9'.$allow.' ]/e','',$text);
$text = preg_replace('/[ ]{2,}/',' ',$text);
return trim($text);
}
$link = mysql_connect($config_databaseServer,$config_databaseUsername,$config_databasePassword);
mysql_select_db($config_databaseName,$link);
$sql = "SELECT * FROM `".$config_databaseTablePrefix."products` WHERE normalised_name = '".mysql_escape_string(redir_normalise($_GET["q"]))."'";
$result = mysql_query($sql,$link);
if (mysql_num_rows($result))
{
require("products.php");
}
else
{
require("search.php");
}
?>
Note: the following changes are based on distribution files rather than the previously described changes...
In categories.php look for the following code at line 20:
$item["href"] = urlencode(tapestry_hyphenate($product["category"]))."/"
...and REPLACE with;
$item["href"] = $config_baseHREF.urlencode(tapestry_hyphenate($product["category"])).".html"
In brands.php look for the following code at line 20:
$item["href"] = urlencode(tapestry_hyphenate($product["brand"]))."/"
...and REPLACE with;
$item["href"] = $config_baseHREF.urlencode(tapestry_hyphenate($product["brand"])).".html"
Now in html/navigation.php look for the following code at line 14:
$prevHREF = "./";
...and REPLACE with:
$prevHREF = tapestry_hyphenate($parts[1]).".html";
And then look for the following code at line 18:
$prevHREF = $prevPage.".html";
...and REPLACE with:
$prevHREF = tapestry_hyphenate($parts[1])."-".$prevPage.".html";
And then the following code at line 65:
$pageOneHREF = "./";
...and REPLACE with:
$pageOneHREF = tapestry_hyphenate($parts[1]).".html";
And then the following code at line 85:
$pageHREF = $i.".html";
...and REPLACE with:
$pageHREF = tapestry_hyphenate($parts[1])."-".$i.".html";
And finally the following code at line 109:
$nextHREF = $nextPage.".html";
...and REPLACE with:
$nextHREF = tapestry_hyphenate($parts[1])."-".$nextPage.".html";
And here's the .htaccess to go with the above changes:
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^product/(.*).html$ $1.html [L,R=301]
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 ^brand/$ brands.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)-([0-9]*).html$ redir.php?q=catbrand:$1:&page=$2&rewrite=1&%{QUERY_STRING} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ redir.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
Hope this helps!
Cheers,
David.
--
PriceTapestry.com
Hi David,
Have uploaded changes and am getting :
Fatal error: Call to undefined function tapestry_normalise() in /redir.php on line 5
Any thoughts?
Cheers
Mike
Hi Mike,
Corrected above! It can't use the library version as it would result in a duplicate function name...
Cheers,
David.
--
PriceTapestry.com
Hi David,
Thanks v much for the update.
It's close. The .co.uk/Sony.html is working as is .co.uk/CategoryX.html, but the navigation , eg .co.uk/Sony-2.html , .co.uk/Sony-3.html is not.
Could you advise?
Cheers
Mike
Hi Mike,
I've ran it all through on my test server, correct redir.php above, but primarily it was that html/navigation.php needed to use $parts[1] instead of $q, that, plus an additional replacement for line 14 corrected above...
Cheers,
David.
--
PriceTapestry.com
Hi David, could it be that the mods you suggested for navigation.php are based on 13/03 and not 12/10B which is the one I'm using here? Just a thought as the line numbers suggest this?
Cheers
Mike
Hi Mike,
12/10B mods to html/navigation.php:
Look for the following code at line 12:
$prevHREF = $prevPage.".html";
...and REPLACE with:
$prevHREF = tapestry_hyphenate($parts[1])."-".$prevPage.".html";
And then the following code at line 58:
$pageOneHREF = "1.html";
...and REPLACE with:
$pageOneHREF = tapestry_hyphenate($parts[1]).".html";
And then the following code at line 71:
$pageHREF = $i.".html";
...and REPLACE with:
$pageHREF = tapestry_hyphenate($parts[1])."-".$i.".html";
And finally the following code at line 95:
$nextHREF = $nextPage.".html";
...and REPLACE with:
$nextHREF = tapestry_hyphenate($parts[1])."-".$nextPage.".html";
Cheers,
David.
--
PriceTapestry.com
Hi David,
Thanks very much for your updates, it's really appreciated. As you have tested that the mods are working ok on your server I'm going to do further testing here, (it's not quite working for me here), it may be something my end. Will report back.
Thanks again
Cheers
Mike
Hi Mike,
No problem - if you want to post any example URLs, or alternatively email me your modified files and example links I'll check it all out for you...
Cheers,
David.
--
PriceTapestry.com
Hi David.
Easy question regarding htacess.
I am doing test but I am not able to add the correct code.
What should I modify in order to have these urls working?
http://example.com/pricetapestry/brand
also
http://example.com/pricetapestry/brand/sony
Note that which work out of the box is
http://example.com/pricetapestry/brand/
http://example.com/pricetapestry/brand/sony/
I want to have both of them. with final slash or not. Also for merchant.
Thanks!
Hi,
Do you want both versions to return the same page (consider duplicate content guidelines) or would you like without final slash to 301 (Moved Permanently) to with final slash? e.g.
http://example.com/pricetapestry/brand
301 Moved Permanently to:
http://example.com/pricetapestry/brand/
and
http://example.com/pricetapestry/brand/Sony
301 Moved Permanently to:
http://example.com/pricetapestry/brand/Sony/
Cheers,
David.
--
PriceTapestry.com
Moved Permanently it seems to be easier as I don't want duplicate content. So it's okay.
Hi,
To do this, add the following rules to the very _end_ of .htaccess
RewriteRule ^merchant$ merchant/ [L,R=301]
RewriteRule ^merchant/(.*)$ merchant/$1/ [L,R=301]
RewriteRule ^category$ category/ [L,R=301]
RewriteRule ^category/(.*)$ category/$1/ [L,R=301]
RewriteRule ^brand$ brand/ [L,R=301]
RewriteRule ^brand/(.*)$ brand/$1/ [L,R=301]
Cheers,
David.
--
PriceTapestry.com
Hello Brent,
It's generally straight forward - they key thing is to make sure that .htaccess takes into account any other actual files that may exist in your top level folder that might be confused with product URLs. RewriteCond can be used to get around this.
In your .htaccess, move the product/ rule from the beginning to the end of your .htaccess adjusting as required, and preceding it with the RewriteCond rules to prevent it from redirecting actual files or directories as follows:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ products.php?q=$1&rewrite=1&%{QUERY_STRING} [L]
With that in place, it's basically just a case of search and replacing:
product/
with nothing (leave the replace box empty) in the following files:
index.php
products.php
reviews.php
search.php
sitemap.php
Cheers,
David.