Jump to content

[Free module] Prestashop 1.6 modern breadcrumb (data-vocabulary.org schema fix)


Daresh

Recommended Posts

Thanks.

2 problems :

  • in .php : ltrim to avoid the space in content=" aaaa"
    'title' => ltrim($lastItem), ltrim($link->nodeValue),
  • showing 5 items in source code (position 5) but I need only 4 items to display ... the 5th sets just the link (no content no name) and it is the same link as the 4th element.
Link to comment
Share on other sites

Hi Daresh, thank you for the module. I'm not a coder and I see all kinds of different 'breadcrumps'.

I installed your module, but in my breadcrumb file I do not know where exactly I need to override the code and insert your hook.

This is my breadcrumb code at the moment:

<!-- Breadcrumb -->
{if isset($smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
<div class="breadcrumb clearfix">
	<a class="home" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}"><i class="icon-home"></i></a>
	{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 $path|strpos:'span' !== false}
			<span class="navigation_page">{$path|@replace:'<a ': '
				<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
					<a itemprop="url" '|@replace:'data-gg="">': '>
						<span itemprop="title">'|@replace:'</a>': '</span>
					</a>
				</span>'}
			</span>
		{else}
			{$path}
		{/if}
	{/if}
</div>
{if isset($smarty.get.search_query) && isset($smarty.get.results) && $smarty.get.results > 1 && isset($smarty.server.HTTP_REFERER)}
<div class="pull-right">
	<strong>
		{capture}{if isset($smarty.get.HTTP_REFERER) && $smarty.get.HTTP_REFERER}{$smarty.get.HTTP_REFERER}{elseif isset($smarty.server.HTTP_REFERER) && $smarty.server.HTTP_REFERER}{$smarty.server.HTTP_REFERER}{/if}{/capture}
		<a href="{$smarty.capture.default|escape:'html':'UTF-8'|secureReferrer|regex_replace:'/[\?|&]content_only=1/':''}" name="back">
			<i class="icon-chevron-left left"></i> {l s='Back to Search results for "%s" (%d other results)' sprintf=[$smarty.get.search_query,$smarty.get.results]}
		</a>
	</strong>
</div>
{/if}
<!-- /Breadcrumb -->

Can you please tell me what code I need to replace with your hook? Thank you so much.

Ellen

Link to comment
Share on other sites

Ok, a very stupid "solution" to the issue that never pops up into my mind I'm posting just for other newbies like me: refresh the cache FROM BACKOFFICE after applying the changes to the code...any other newbie mean won't work :)

Now Google is validating the changes, assessing whether they're effective or not. It says it will take some days for it.

I'll keep you updated.

@Daresh thank you for your prompt support! Very appreciated!

 

Edited by JRCFirewalker (see edit history)
  • Like 1
Link to comment
Share on other sites

Hi Daresh,

I probed you module and it looks to work fine now.(I did it before but replacing complete code on the template...

Just two questions, when reviewing goggle results after module and refreshing cache, I see that there are some field (optional) but missing like :

Brand, review SBN, url and availability. How can I do to show these info?

example: https://www.delica-te-zen.com/comprar-te-rojo/146-te-pu-erh-mango-maracuya.html

Second question, is more about cosmetic issue, but since place the hook the icon for root (Home) disappears from breadcrumb in the top, do you expect implement to show the home location?

Thanks

Link to comment
Share on other sites

I'm with your module, but I still have errors .

Tnx.

 <!-- Breadcrumb -->
{if isset($smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
  {hook h='displayModernBreadCrumb' path=$path}
{if isset($smarty.get.search_query) && isset($smarty.get.results) && $smarty.get.results > 1 && isset($smarty.server.HTTP_REFERER)}
<div class="pull-right">
    <strong>
        {capture}{if isset($smarty.get.HTTP_REFERER) && $smarty.get.HTTP_REFERER}{$smarty.get.HTTP_REFERER}{elseif isset($smarty.server.HTTP_REFERER) && $smarty.server.HTTP_REFERER}{$smarty.server.HTTP_REFERER}{/if}{/capture}
        <a href="{$smarty.capture.default|escape:'html':'UTF-8'|secureReferrer|regex_replace:'/[\?|&]content_only=1/':''}" name="back">
            <i class="icon-chevron-left left"></i> {l s='Back to Search results for "%s" (%d other results)' sprintf=[$smarty.get.search_query,$smarty.get.results]}
        </a>
    </strong>
</div>
{/if}
<!-- /Breadcrumb -->

Screenshot_2020-01-22 Инструмент за тестване на структурирани данни.png

Link to comment
Share on other sites

Great module, thank for sharing. Works btw as well for 1.5.6, so there is thus no need to limit the usage to minimum 1.6.

But there is a difference: Neither in 1.6 nor in 1.5 the last path item shows up like before with your module installed. Where is the adjusting screw to fix this little mistake? ;)

 

Edited by Wuschel (see edit history)
Link to comment
Share on other sites

Who cares for 1.5? ;)

But it's simple, if you don't want the last item to be linked, you can change the foreach loop in the module's tpl file to this:

{foreach from=$breadcrumbLinks item=breadcrumbLink}
        <span itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
            {if !$breadcrumbLink.last}
                <a itemprop="item" href="{$breadcrumbLink.href}" title="{$breadcrumbLink.title}">
                    {$breadcrumbLink.title}
                </a>
                <span class="navigation-pipe">{$navigationPipe}</span>
            {else}
                {$breadcrumbLink.title}
            {/if}
            <meta itemprop="position" content="{$breadcrumbLink.position}">
            <meta itemprop="name" content="{$breadcrumbLink.title}">
        </span>
    {/foreach}

Seems it's still correctly validated by the snippets testing tool.

Link to comment
Share on other sites

13 hours ago, Daresh said:

If you don't want the last item to be linked, you execute the hook like this: {hook h='displayModernBreadCrumb' path=$path} (according to Google's specs the last item is not required to be a link)

Thank you again, I really appreciate this. I'll check it out tomorrow. It's just that in my opinion the navigation of a shop system should first and foremost serve the customer - and not Google.

Edited by Wuschel (see edit history)
Link to comment
Share on other sites

I don't understand, where to insert that hook...

If you want the last item to be linked, you execute the hook like this: {hook h='displayModernBreadCrumb' path=$path linkLast=true}

If you don't want the last item to be linked, you execute the hook like this: {hook h='displayModernBreadCrumb' path=$path} (according to Google's specs the last item is not required to be a link)

Edited by Claudiocool (see edit history)
Link to comment
Share on other sites

1 hour ago, Claudiocool said:

I don't understand, where to insert that hook...

If you want the last item to be linked, you execute the hook like this: {hook h='displayModernBreadCrumb' path=$path linkLast=true}

If you don't want the last item to be linked, you execute the hook like this: {hook h='displayModernBreadCrumb' path=$path} (according to Google's specs the last item is not required to be a link)

Add the hook in the breadcrumb.tpl file of your theme (/themes/your_theme/breadcrumb.tpl)

Like this: 

breadcrumbs_hook.png

  • Like 1
Link to comment
Share on other sites

5 hours ago, NSN said:

@Daresh Thanks a lot for your work and the module. It's maybe a stupid question, but if an older version of your module is already installed and I want to update, can the new version simply be uploaded or should the old one be removed first?

Just upload the new module.

  • Thanks 1
Link to comment
Share on other sites

Thank you very much for this nice module !

However I see always errors on my host server :

Quote

[Fri Jan 24 15:51:43.336228 2020] [:error] [pid 166526:tid 140510819755776] [client 66.249.64.228:55532] FastCGI:
server "/home/clients/xxxxxxxxxxxxxxxxxx/.config/apache/xxxxxxxxxxxxxx.xx.ch/.fpm/php5.external"
stderr: PHP message: PHP Warning:  DOMDocument::loadHTML():
Empty string supplied as input in /home/clients/8xxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxx.xx.ch/httpdocs/modules/gmbreadcrumb/gmbreadcrumb.php on line 48

[Fri Jan 24 15:47:44.904573 2020] [:error] [pid 158947:tid 140510735828736] [client 66.249.64.228:36586] FastCGI:
server "/home/clients/xxxxxxxxxxxxxxxxxx/.config/apache/xxxxxxxxxxxxxx.xx.ch/.fpm/php5.external"
stderr: PHP message: PHP Warning:  DOMDocument::loadHTML():
Empty string supplied as input in /home/clients/xxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxx.xx.ch/httpdocs/modules/gmbreadcrumb/gmbreadcrumb.php on line 48

Seems this line gives errors  (line : 48):

 $dom->loadHTML(mb_convert_encoding($path, 'HTML-ENTITIES', 'UTF-8'));

Thank you

 

Edited by myselfidem (see edit history)
Link to comment
Share on other sites

It's just a warning, so it will not break your site. It would be good to know if it happens for a page that should have a breadcrumb, or maybe for some reason the path is indeed empty?

Do you know for what page request you have this warning?

Link to comment
Share on other sites

The module works wonderfully but I am having an issue with either CMS that are in categories: the last item does not show and Google says the name is missing (which it is since the title of the last page is not there) and with the BLOG module, you get another arrow with nothing and Google again calls for an empty name.

Example CMS: https://librairiezbookstore.com/en/info/informations/accepted-payment-methods

Example BLOG 1: https://librairiezbookstore.com/NEWS

Example BLOG 2: https://librairiezbookstore.com/en/NEWS/post/straight-to-hell.html

Other than that, everything works great. Thank you for the module!

Link to comment
Share on other sites

Breadcrumb is reduntant on cms pages. I've added "cms" pages to header.tpl not to be displayed - the same as index and pagenotfound pages:

                    {if $page_name !='index' && $page_name !='pagenotfound' && $page_name !='cms'}
                        {include file="$tpl_dir./breadcrumb.tpl"}
                    {/if}

Link to comment
Share on other sites

19 hours ago, Daresh said:

Thanks for your feedback guys, I just updated the module to v. 1.1.1 and uploaded it into the first post, check it out!

Hi Daresh,

 

how to update to the new version? Just un install the old one and load the new? or there is any other better way how to?

Thanks!

Link to comment
Share on other sites

Thanks for this! Just a question, our theme have some user defined variables inside breadcrumb.tpl (we use Warehouse):

 

<div class="breadcrumb clearfix {if isset($warehouse_vars.breadcrumb_width) && $warehouse_vars.breadcrumb_width == 0}fullwidth-breadcrumb{/if}">
	{if isset($warehouse_vars.breadcrumb_width) && $warehouse_vars.breadcrumb_width == 0}<div class="container">{/if}
		<a class="home" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}"><i class="icon-home"></i></a>
	{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 $path|strpos:'span' !== false}
			<span class="navigation_page">{$path|@replace:'<a ': '<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a itemprop="url" '|@replace:'data-gg="">': '><span itemprop="title">'|@replace:'</a>': '</span></a></span>'}</span>
		{else}
			{$path}
		{/if}
	{/if}

		{if $page_name == 'product'}
		{hook h='productnavs'}
		{/if}

{if isset($warehouse_vars.breadcrumb_width) && $warehouse_vars.breadcrumb_width == 0}</div>{/if}
</div>

 

If I replace this with your module hook, would it affect how things related to breadcrumb looks? Or should I also edit your gmbreadcrumb.tpl so it's compatible with the theme?

Link to comment
Share on other sites

19 minutes ago, Daresh said:

It may affect how the breadcrumb looks, but your code seems to be using a lot of custom variables, so I don't think my module will work for you if you wan to keep all this markup.

Ah that's too bad, what exactly would I have to change in it to be able to use the new Schema?

Link to comment
Share on other sites

On 1/24/2020 at 9:17 AM, Daresh said:

Use the snippets testing tool to verify your breadcrumb: https://search.google.com/structured-data/testing-tool/u/0/?hl=en

Hi Daresh, I ran the test: https://search.google.com/structured-data/testing-tool/u/0/?hl=en#url=https%3A%2F%2Fwww.bike4travel.nl
I see some errors, but I don't know if they are related to your module (I'm not a programmer, we try to do this ourselves and sometimes things get complicated :) )

Thanks again.

Link to comment
Share on other sites

Another important update - I made this module with an assumption that the current page should be a link, but it's actually not required by Google.

So the best solution would be to only modify the breadcrumb.tpl, replacing it's contents with this code:

<!-- Breadcrumb -->
{if isset($smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
{if !empty($path)}
{$matchCount = preg_match_all('/<a.+?href="(.+?)"[^>]*>([^<]*)<\/a>/', $path, $matches)}
{$breadcrumbs = []}
{for $i=0; $i < $matchCount; $i++}
{$breadcrumbs[] = ['url' => $matches[1][$i], 'title' => $matches[2][$i]]}
{/for}
{$match = preg_match('/>([^<]+)(?:<\/\\w+>s*)?$/', $path, $matches)}
{if !empty($matches[1])}
{$breadcrumbs[] = ['url' => '', 'title' => $matches[1]]}
{elseif !$match && !$matchCount}
{$breadcrumbs[] = ['url' => '', 'title' => $path]}
{/if}
{/if}
<div class="clearfix">
	<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
		<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> 
			<a class="home" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}" itemprop="item">
				<i class="icon-home"></i>
			</a>
			<meta itemprop="name" content="{l s='Home'}" />
			<meta itemprop="position" content="1" />
		</li>
{if !empty($breadcrumbs)}
{foreach from=$breadcrumbs item=breadcrumb name=crumbs}
		<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
{if !empty($breadcrumb.url)}
			<a href="{$breadcrumb.url}" itemprop="item" title="{$breadcrumb.title}">
				<span itemprop="name">{$breadcrumb.title}</span>
			</a>
{else}
			<span itemprop="name">{$breadcrumb.title}</span>
{/if}
			<meta itemprop="position" content="{($smarty.foreach.crumbs.iteration|intval + 1)}" />
		</li>
{/foreach}
{/if}
	</ol>
</div>
{if isset($smarty.get.search_query) && isset($smarty.get.results) && $smarty.get.results > 1 && isset($smarty.server.HTTP_REFERER)}
<div class="pull-right">
	<strong>
		{capture}{if isset($smarty.get.HTTP_REFERER) && $smarty.get.HTTP_REFERER}{$smarty.get.HTTP_REFERER}{elseif isset($smarty.server.HTTP_REFERER) && $smarty.server.HTTP_REFERER}{$smarty.server.HTTP_REFERER}{/if}{/capture}
		<a href="{$smarty.capture.default|escape:'html':'UTF-8'|secureReferrer|regex_replace:'/[\?|&]content_only=1/':''}" name="back">
			<i class="icon-chevron-left left"></i> {l s='Back to Search results for "%s" (%d other results)' sprintf=[$smarty.get.search_query,$smarty.get.results]}
		</a>
	</strong>
</div>
{/if}
<!-- /Breadcrumb -->

That's the most simple solution, and finally we have a correct code of the breadcrumb.tpl file.

  • Like 1
Link to comment
Share on other sites

10 hours ago, Daresh said:

Another important update - I made this module with an assumption that the current page should be a link, but it's actually not required by Google.

So the best solution would be to only modify the breadcrumb.tpl, replacing it's contents with this code:


<!-- Breadcrumb -->
{if isset($smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
{if !empty($path)}
{$matchCount = preg_match_all('/<a.+?href="(.+?)"[^>]*>([^<]*)<\/a>/', $path, $matches)}
{$breadcrumbs = []}
{for $i=0; $i < $matchCount; $i++}
{$breadcrumbs[] = ['url' => $matches[1][$i], 'title' => $matches[2][$i]]}
{/for}
{$match = preg_match('/>([^<]+)(?:<\/\\w+>s*)?$/', $path, $matches)}
{if !empty($matches[1])}
{$breadcrumbs[] = ['url' => '', 'title' => $matches[1]]}
{elseif !$match && !$matchCount}
{$breadcrumbs[] = ['url' => '', 'title' => $path]}
{/if}
{/if}
<div class="clearfix">
	<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
		<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> 
			<a class="home" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}" itemprop="item">
				<i class="icon-home"></i>
			</a>
			<meta itemprop="name" content="{l s='Home'}" />
			<meta itemprop="position" content="1" />
		</li>
{if !empty($breadcrumbs)}
{foreach from=$breadcrumbs item=breadcrumb name=crumbs}
		<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
{if !empty($breadcrumb.url)}
			<a href="{$breadcrumb.url}" itemprop="item" title="{$breadcrumb.title}">
				<span itemprop="name">{$breadcrumb.title}</span>
			</a>
{else}
			<span itemprop="name">{$breadcrumb.title}</span>
{/if}
			<meta itemprop="position" content="{($smarty.foreach.crumbs.iteration|intval + 1)}" />
		</li>
{/foreach}
{/if}
	</ol>
</div>
{if isset($smarty.get.search_query) && isset($smarty.get.results) && $smarty.get.results > 1 && isset($smarty.server.HTTP_REFERER)}
<div class="pull-right">
	<strong>
		{capture}{if isset($smarty.get.HTTP_REFERER) && $smarty.get.HTTP_REFERER}{$smarty.get.HTTP_REFERER}{elseif isset($smarty.server.HTTP_REFERER) && $smarty.server.HTTP_REFERER}{$smarty.server.HTTP_REFERER}{/if}{/capture}
		<a href="{$smarty.capture.default|escape:'html':'UTF-8'|secureReferrer|regex_replace:'/[\?|&]content_only=1/':''}" name="back">
			<i class="icon-chevron-left left"></i> {l s='Back to Search results for "%s" (%d other results)' sprintf=[$smarty.get.search_query,$smarty.get.results]}
		</a>
	</strong>
</div>
{/if}
<!-- /Breadcrumb -->

That's the most simple solution, and finally we have a correct code of the breadcrumb.tpl file.

Hi Daresh,

 

now I´m really cofused. So, we can un install the module and simply replace the original breadcrumb.tpl in our theme with this new code?

Thanks for clarification and your time.

Link to comment
Share on other sites

I have created/updated origional breadcump.tpl and added pages who i wanted to include.

Page to include?/exclude  you do update in the lines highligted

working perfect in prestashop 1.6 versions.

ps dont forget to backup your origional before copy past 

<!-- 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' or $page_name == 'new-products' or $page_name == 'best-sales' or $page_name == 'prices-drop' or $page_name == 'manufacturer' or $page_name == 'sitemap' or $page_name == 'content' or $page_name == 'stores' or $page_name == 'search'}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' or $page_name == 'new-products' or $page_name == 'best-sales' or $page_name == 'prices-drop' or $page_name == 'manufacturer' or $page_name == 'sitemap' or $page_name == 'content' or $page_name == 'stores' or $page_name == 'search'}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' or $page_name == 'new-products' or $page_name == 'best-sales' or $page_name == 'prices-drop' or $page_name == 'manufacturer' or $page_name == 'sitemap' or $page_name == 'content' or $page_name == 'stores' or $page_name == 'search'}
            {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>

  • Thanks 2
Link to comment
Share on other sites