trace Posted July 25, 2017 Share Posted July 25, 2017 (edited) Breadcrumbs for Google snippet. [updated] Note: Before changing breadcrumbs, make sure that you have assigned the most relevant default category for each product. It is desirable that this category is the highest level of nesting, since the breadcrumbs path will be compiled on the basis of this category. /theme/your_theme/breadcrumb.tpl code: <!-- Breadcrumb --> {if isset($smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if} <div class="breadcrumb" {if $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'}itemscope itemtype="http://schema.org/BreadcrumbList"{/if}> <!-- <div class="container" > --> <!--<meta itemprop="name" content="{$meta_title|escape:'html':'UTF-8'}"/>--> <span {if $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'}itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ListItem"{/if}><meta itemprop="position" content="1"><a class="home" itemprop="item" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}"><meta itemprop="name" content="{l s='Home'}" /><i class="icon-home"></i></a></span> {if isset($path) AND $path} <span class="navigation-pipe" {if isset($category) && isset($category->id_category) && $category->id_category == (int)Configuration::get('PS_ROOT_CATEGORY')} style="display:none;"{/if}>{$navigationPipe|escape:'html':'UTF-8'}</span> {if $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'} {if $path|strpos:'span' !== false} <span class="navigation_page" > {$path|@replace:'<a ': '<span > <span > <a itemprop="item" '|@replace:'data-gg="">': '> <span >'|@replace:'</a>': '</a></span></span>'}</span> {else} <span itemprop="itemListElement" class="item-breadcrumb" itemscope="" itemtype="http://schema.org/ListItem"><meta itemprop="position" content="1"><meta itemprop="item" content="{if isset($force_ssl) && $force_ssl}https://{$smarty.server.HTTP_HOST}{$smarty.server.REQUEST_URI}{else}http://{$smarty.server.HTTP_HOST}{$smarty.server.REQUEST_URI}{/if}" /><meta itemprop="name" content="{$path}" /><span class="item-breadalone">{$path}</span></span> {/if} {else} {if $path|strpos:'span' !== false} <span class="navigation_page" > {$path|@replace:'<a ': '<span > <span > <a '|@replace:'data-gg="">': '> <span >'|@replace:'</a>': '</a></span></span>'}</span> {else} <span class="item-breadalone">{$path}</span> {/if} {/if} {/if} </div> /override/classes/Tools.php <?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, cl.meta_title FROM '._DB_PREFIX_.'category c LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = c.id_category'.Shop::addSqlRestrictionOnLang('cl').') '.Shop::addSqlAssociation('category', 'c').' 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 $key => $category) { $key = $key+2; $full_path .='<span itemprop="itemListElement" class="item-breadcrumb" itemscope="" itemtype="http://schema.org/ListItem" ><meta itemprop="position" content="'.$key.'">'. (($n < $n_categories || $link_on_the_item) ? '<a itemprop="url" href="'.Tools::safeOutput($context->link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'])).'" title="'.htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8').'">' : '<meta itemprop="url" content="'.Tools::safeOutput($context->link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'])).'" title="'.htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8').'" />').'<meta itemprop="name" content="'.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>' : '').'</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); } } } /override/controllers/ProductController.php <?php class ProductController extends ProductControllerCore { protected function assignCategory() { // Assign category to the template if ($this->category !== false && Validate::isLoadedObject($this->category) && $this->category->inShop() && $this->category->isAssociatedToShop()) { $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id); $path = Tools::getPath($this->product->id_category_default, $this->product->name, true); } elseif (Category::inShopStatic($this->product->id_category_default, $this->context->shop)) { $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id); if (Validate::isLoadedObject($this->category) && $this->category->active && $this->category->isAssociatedToShop()) { $path = Tools::getPath((int)$this->product->id_category_default, $this->product->name); } } if (!isset($path) || !$path) { $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id); $path = Tools::getPath($this->product->id_category_default, $this->product->name, true); } $sub_categories = array(); if (Validate::isLoadedObject($this->category)) { $sub_categories = $this->category->getSubCategories($this->context->language->id, true); // various assignements before Hook::exec $this->context->smarty->assign(array( 'path' => $path, 'category' => $this->category, 'subCategories' => $sub_categories, 'id_category_current' => (int)$this->category->id, 'id_category_parent' => (int)$this->category->id_parent, 'return_category_name' => Tools::safeOutput($this->category->getFieldByLang('name')), 'categories' => Category::getHomeCategories($this->context->language->id, true, (int)$this->context->shop->id) )); } $this->context->smarty->assign(array('HOOK_PRODUCT_FOOTER' => Hook::exec('displayFooterProduct', array('product' => $this->product, 'category' => $this->category)))); } } Edited November 12, 2017 by trace 1. "position" starts at 1; 2. breadcramps path on product page is now based on the default category of product; 3. All "display:none;" changed to <meta> (see edit history) 2 Link to comment Share on other sites More sharing options...
trace Posted July 27, 2017 Author Share Posted July 27, 2017 Use Structured Data Testing Tool for check result. 2 Link to comment Share on other sites More sharing options...
mpatzekov Posted October 20, 2017 Share Posted October 20, 2017 Hi, trace. Is there any option to start the counter of the position property from 1 instead of 0? Link to comment Share on other sites More sharing options...
trace Posted October 21, 2017 Author Share Posted October 21, 2017 Change this string in Tools.php: $key = $key+1; to: $key = $key+2; and in breadcrumb.tpl: <meta itemprop="position" content="0"> to: <meta itemprop="position" content="1"> But for what you need it? I watched Google's instructions and there the countdown started at 0. Link to comment Share on other sites More sharing options...
mpatzekov Posted October 21, 2017 Share Posted October 21, 2017 Hey, trace... Many thanks on the assistance, I really appreciate it. Well, this is interesting... I am sure that there may be some recommendations that give the 0 as a starting position. Actually, I haven't checked if there are examples in schema.org. What I've found is this: https://developers.google.com/search/docs/data-types/breadcrumbs and in all the examples (see markup buttons), the starting position is 1, so that's why I assumed that I should use 1 instead of 0. What do you think, is it possible that I may be wrong? 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now