In this tutorial we will see how to add Google Rich Snippets Breadcrumbs to a Prestashop website, by modifying a small portion of the template and using a lightweight override.
- Version used: Prestashop 1.5.6.2
Two types of markup
Google supports the following types of data for the breadcrumbs rich snippets:
- Microdata
- RDFa
Microdata is the one we used in the previous tutorial on how to add Google Rich Snippets to your Prestashop store, and the basic markup consists in adding itemprops and scopes to single html entities
On the other hand, RDFa adds a set of attributes and extensions to html using xml properties. You can read more about it here: RDFa Wiki.
I will use the latter in this demonstration, but either will do, so feel free to use the one you prefer in the end. You can visit the official Google Documentation on Breadcrumbs Rich Snippets if you want to get more info about the implementation.
Adding Google Rich Snippets Breadcrumbs to Prestashop – The tpl
First things first, we must hardcode a small portion of code inside breadcrumb.tpl. Open up the file located in your theme’s folder. It will look approximately like this (default theme):
[php htmlscript=”true”]
<!– Breadcrumb –>
{if isset($smarty.capture.path)}{assign var=’path’ value=$smarty.capture.path}{/if}
<div class="breadcrumb">
<a href="{$base_dir}" title="{l s=’Return to Home’}"><img src="{$img_dir}icon/home.gif" height="26" width="26" alt="{l s=’Home’}" /></a>
{if isset($path) AND $path}
<span class="navigation-pipe" {if isset($category) && isset($category->id_category) && $category->id_category == 1}style="display:none;"{/if}>{$navigationPipe|escape:html:’UTF-8′}</span>
{if !$path|strpos:’span’}
<span class="navigation_page">{$path}</span>
{else}
{$path}
{/if}
{/if}
</div>
<!– /Breadcrumb –>
[/php]
Edit as follows:
[php htmlscript=”true”]
<!– Breadcrumb –>
{if isset($smarty.capture.path)}{assign var=’path’ value=$smarty.capture.path}{/if}
<div class="breadcrumb" xmlns:v="http://rdf.data-vocabulary.org/#">
<span typeof="v:Breadcrumb"><a href="{$base_dir}" rel="v:url" property="v:title" title="{l s=’Return to Home’}"><img src="{$img_dir}icon/home.gif" height="26" width="26" alt="{l s=’Home’}" /></a></span>
{if isset($path) AND $path}
<span class="navigation-pipe" {if isset($category) && isset($category->id_category) && $category->id_category == 1}style="display:none;"{/if}>{$navigationPipe|escape:html:’UTF-8′}</span>
{if !$path|strpos:’span’}
<span typeof="v:Breadcrumb">
<span property="v:title" class="navigation_page">{$path}</span>
</span>
{else}
{$path}
{/if}
{/if}
</div>
<!– /Breadcrumb –>
[/php]
Explanation: First, we told Google that the .breadcrumb div is our breadcrumb container. Then, we added a span around the homepage link, with typeof=”v:Breadcrumb” so that it know it’s dealing with part of the breadcrumb. Lastly, we added a rel and property attribute to the link pointing to the homepage. Then, we added the breadcrumb object and title property to the last item
At this point, we must use an override as Prestashop builds breadcrumbs in the Tools::getPath() method!
Adding Google Rich Snippets Breadcrumbs to Prestashop – The override
Create a new override in override/classes and call it Tools.php. Add some regular override markup inside:
[php]
class Tools extends ToolsCore
{
}
[/php]
We need to override the getPath method, so open the original Tools.php class file that you find in your classes/ directory, copy the whole getPath() method, and paste it inside the new override as follows:
[php]
class Tools extends ToolsCore
{
public static function getPath($id_category, $path = ”, $link_on_the_item = false, $category_type = ‘products’, Context $context = null)
{
if (!$context)
$context = Context::getContext();
$id_category = (int)$id_category;
if ($id_category == 1)
return ‘<span class="navigation_end">’.$path.'</span>’;
$pipe = Configuration::get(‘PS_NAVIGATION_PIPE’);
if (empty($pipe))
$pipe = ‘>’;
$full_path = ”;
if ($category_type === ‘products’)
{
$interval = Category::getInterval($id_category);
$id_root_category = $context->shop->getCategory();
$interval_root = Category::getInterval($id_root_category);
if ($interval)
{
$sql = ‘SELECT c.id_category, cl.name, cl.link_rewrite
FROM ‘._DB_PREFIX_.’category c
LEFT JOIN ‘._DB_PREFIX_.’category_lang cl ON (cl.id_category = c.id_category’.Shop::addSqlRestrictionOnLang(‘cl’).’)
WHERE c.nleft <= ‘.$interval[‘nleft’].’
AND c.nright >= ‘.$interval[‘nright’].’
AND c.nleft >= ‘.$interval_root[‘nleft’].’
AND c.nright <= ‘.$interval_root[‘nright’].’
AND cl.id_lang = ‘.(int)$context->language->id.’
AND c.active = 1
AND c.level_depth > ‘.(int)$interval_root[‘level_depth’].’
ORDER BY c.level_depth ASC’;
$categories = Db::getInstance()->executeS($sql);
$n = 1;
$n_categories = count($categories);
foreach ($categories as $category)
{
$full_path .=
(($n < $n_categories || $link_on_the_item) ? ‘<a href="’.Tools::safeOutput($context->link->getCategoryLink((int)$category[‘id_category’], $category[‘link_rewrite’])).’" title="’.htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8′).’">’ : ”).
htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8’).
(($n < $n_categories || $link_on_the_item) ? ‘</a>’ : ”).
(($n++ != $n_categories || !empty($path)) ? ‘<span class="navigation-pipe">’.$pipe.'</span>’ : ”);
}
return $full_path.$path;
}
}
else if ($category_type === ‘CMS’)
{
$category = new CMSCategory($id_category, $context->language->id);
if (!Validate::isLoadedObject($category))
die(Tools::displayError());
$category_link = $context->link->getCMSCategoryLink($category);
if ($path != $category->name)
$full_path .= ‘<a href="’.Tools::safeOutput($category_link).’">’.htmlentities($category->name, ENT_NOQUOTES, ‘UTF-8′).'</a><span class="navigation-pipe">’.$pipe.'</span>’.$path;
else
$full_path = ($link_on_the_item ? ‘<a href="’.Tools::safeOutput($category_link).’">’ : ”).htmlentities($path, ENT_NOQUOTES, ‘UTF-8’).($link_on_the_item ? ‘</a>’ : ”);
return Tools::getPath($category->id_parent, $full_path, $link_on_the_item, $category_type);
}
}
}
[/php]
We can now modify the code snippets that generate links. First off, locate:
[php]
if (!$context)
$context = Context::getContext();
[/php]
Right after it, add
[php]
$path = ‘<span typeof="v:Breadcrumb"><span property="v:title">’.$path.'</span></span>’;
[/php]
This way we label the current page name as title in the breadcrumbs. Then:
[php]
$full_path .=
(($n < $n_categories || $link_on_the_item) ? ‘<a href="’.Tools::safeOutput($context->link->getCategoryLink((int)$category[‘id_category’], $category[‘link_rewrite’])).’" title="’.htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8′).’">’ : ”).
htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8’).
(($n < $n_categories || $link_on_the_item) ? ‘</a>’ : ”).
[/php]
Edit as follows
[php]
$full_path .=
(($n < $n_categories || $link_on_the_item) ? ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" href="’.Tools::safeOutput($context->link->getCategoryLink((int)$category[‘id_category’], $category[‘link_rewrite’])).’" title="’.htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8′).’">’ : ”).
htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8’).
(($n < $n_categories || $link_on_the_item) ? ‘</a> </span>’ : ”).
[/php]
Explanation: as we did previously, we added a span around the link, and assigned a rel and property attributes to the inner link. Remember to close the span at the end!.
Lastly, let’s account for cms pages as well, find:
[php]
if ($path != $category->name)
$full_path .= ‘<a href="’.Tools::safeOutput($category_link).’">’.htmlentities($category->name, ENT_NOQUOTES, ‘UTF-8′).'</a><span class="navigation-pipe">’.$pipe.'</span>’.$path;
else
$full_path = ($link_on_the_item ? ‘<a href="’.Tools::safeOutput($category_link).’">’ : ”).htmlentities($path, ENT_NOQUOTES, ‘UTF-8’).($link_on_the_item ? ‘</a>’ : ”);
[/php]
And change it to:
[php]
if ($path != $category->name)
$full_path .= ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" href="’.Tools::safeOutput($category_link).’">’.htmlentities($category->name, ENT_NOQUOTES, ‘UTF-8’).'</a> </span> <span class="navigation-pipe"> ‘.$pipe.’ </span> ‘.$path;
else
$full_path = ($link_on_the_item ? ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" <a href="’.Tools::safeOutput($category_link).’">’ : ”).htmlentities($path, ENT_NOQUOTES, ‘UTF-8’).($link_on_the_item ? ‘</a> <span>’ : ”);
[/php]
We are done! Save, clear smarty cache/force compile so that changes take effect, then go to cache/ and erase class_index.php so that the override can take place!
The final override:
[php]
class Tools extends ToolsCore
{
public static function getPath($id_category, $path = ”, $link_on_the_item = false, $category_type = ‘products’, Context $context = null)
{
if (!$context)
$context = Context::getContext();
$path = ‘<span typeof="v:Breadcrumb"><span property="v:title">’.$path.'</span></span>’;
$id_category = (int)$id_category;
if ($id_category == 1)
return ‘<span class="navigation_end">’.$path.'</span>’;
$pipe = Configuration::get(‘PS_NAVIGATION_PIPE’);
if (empty($pipe))
$pipe = ‘>’;
$full_path = ”;
if ($category_type === ‘products’)
{
$interval = Category::getInterval($id_category);
$id_root_category = $context->shop->getCategory();
$interval_root = Category::getInterval($id_root_category);
if ($interval)
{
$sql = ‘SELECT c.id_category, cl.name, cl.link_rewrite
FROM ‘._DB_PREFIX_.’category c
LEFT JOIN ‘._DB_PREFIX_.’category_lang cl ON (cl.id_category = c.id_category’.Shop::addSqlRestrictionOnLang(‘cl’).’)
WHERE c.nleft <= ‘.$interval[‘nleft’].’
AND c.nright >= ‘.$interval[‘nright’].’
AND c.nleft >= ‘.$interval_root[‘nleft’].’
AND c.nright <= ‘.$interval_root[‘nright’].’
AND cl.id_lang = ‘.(int)$context->language->id.’
AND c.active = 1
AND c.level_depth > ‘.(int)$interval_root[‘level_depth’].’
ORDER BY c.level_depth ASC’;
$categories = Db::getInstance()->executeS($sql);
$n = 1;
$n_categories = count($categories);
foreach ($categories as $category)
{
$full_path .=
(($n < $n_categories || $link_on_the_item) ? ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" href="’.Tools::safeOutput($context->link->getCategoryLink((int)$category[‘id_category’], $category[‘link_rewrite’])).’" title="’.htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8′).’">’ : ”).
htmlentities($category[‘name’], ENT_NOQUOTES, ‘UTF-8’).
(($n < $n_categories || $link_on_the_item) ? ‘</a> </span>’ : ”).
(($n++ != $n_categories || !empty($path)) ? ‘ <span class="navigation-pipe"> ‘.$pipe.’ </span> ‘ : ”);
}
return $full_path.$path;
}
}
else if ($category_type === ‘CMS’)
{
$category = new CMSCategory($id_category, $context->language->id);
if (!Validate::isLoadedObject($category))
die(Tools::displayError());
$category_link = $context->link->getCMSCategoryLink($category);
if ($path != $category->name)
$full_path .= ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" href="’.Tools::safeOutput($category_link).’">’.htmlentities($category->name, ENT_NOQUOTES, ‘UTF-8’).'</a> </span> <span class="navigation-pipe"> ‘.$pipe.’ </span> ‘.$path;
else
$full_path = ($link_on_the_item ? ‘<span typeof="v:Breadcrumb"> <a rel="v:url" property="v:title" <a href="’.Tools::safeOutput($category_link).’">’ : ”).htmlentities($path, ENT_NOQUOTES, ‘UTF-8’).($link_on_the_item ? ‘</a> <span>’ : ”);
return Tools::getPath($category->id_parent, $full_path, $link_on_the_item, $category_type);
}
}
}
[/php]
Time to test your page now! Here is one from my Prestashop modules store: Prestashop SEO Booster example
Need Prestashop Modules? Have a look at my Prestashop Addons Store!
Looking for quality PrestaShop Web Hosting? Look no further than Arvixe Web Hosting!