Magento 2.2.4 - Breadcrumbs do not show on product pages when default navigation is not present
With help of some posts on stackexchange, I found out this solution, This approach does not require you to override with di.xml
YOUR_THEME\Magento_Catalog\layout\catalog_product_view.xml
<referenceContainer name="content.top">
<block class="Vendor\Module\Block\Breadcrumbs" name="breadcrumbs" as="breadcrumbs" />
</referenceContainer>
Create a module with the following block:
Vendor/Module/Block/Breadcrumbs.php
<?php
namespace Vendor\Module\Block;
use Magento\Catalog\Helper\Data;
use Magento\Framework\View\Element\Template\Context;
use Magento\Store\Model\Store;
use Magento\Framework\Registry;
class Breadcrumbs extends \Magento\Theme\Block\Html\Breadcrumbs
{
/**
* Catalog data
*
* @var Data
*/
protected $_catalogData = null;
/**
* @param Context $context
* @param Data $catalogData
* @param array $data
*/
public function __construct(Context $context, Data $catalogData, Registry $registry, array $data = [])
{
$this->_catalogData = $catalogData;
$this->registry = $registry;
parent::__construct($context, $data);
}
/**
* Retrieve HTML title value separator (with space)
*
* @param null|string|bool|int|Store $store
* @return string
*/
public function getTitleSeparator($store = null)
{
$separator = (string)$this->_scopeConfig->getValue('catalog/seo/title_separator', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
return ' ' . $separator . ' ';
}
public function getCrumbs() {
return $this->_crumbs;
}
/**
* Preparing layout
*
* @return \Magento\Catalog\Block\Breadcrumbs
*/
protected function _prepareLayout() {
$title = [];
if ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) {
$breadcrumbsBlock->addCrumb(
'home', [
'label' => __('Home'),
'title' => __('Go to Home Page'),
'link' => $this->_storeManager->getStore()->getBaseUrl()
]
);
$path = $this->_catalogData->getBreadcrumbPath();
$product = $this->registry->registry('current_product');
if ($product && count($path) == 1) {
$categoryCollection = clone $product->getCategoryCollection();
$categoryCollection->clear();
$categoryCollection->addAttributeToSort('level', $categoryCollection::SORT_ORDER_DESC)->addAttributeToFilter('path', array('like' => "1/" . $this->_storeManager->getStore()->getRootCategoryId() . "/%"));
$categoryCollection->setPageSize(1);
$breadcrumbCategories = $categoryCollection->getFirstItem()->getParentCategories();
foreach ($breadcrumbCategories as $category) {
$catbreadcrumb = array("label" => $category->getName(), "link" => $category->getUrl());
$breadcrumbsBlock->addCrumb("category" . $category->getId(), $catbreadcrumb);
$title[] = $category->getName();
}
//add current product to breadcrumb
$prodbreadcrumb = array("label" => $product->getName(), "link" => "");
$breadcrumbsBlock->addCrumb("product" . $product->getId(), $prodbreadcrumb);
$title[] = $product->getName();
} else {
foreach ($path as $name => $breadcrumb) {
$breadcrumbsBlock->addCrumb($name, $breadcrumb);
$title[] = $breadcrumb['label'];
}
}
$this->pageConfig->getTitle()->set(join($this->getTitleSeparator(), array_reverse($title)));
return parent::_prepareLayout();
}
$path = $this->_catalogData->getBreadcrumbPath();
foreach ($path as $name => $breadcrumb) {
$title[] = $breadcrumb['label'];
}
$this->pageConfig->getTitle()->set(join($this->getTitleSeparator(), array_reverse($title)));
return parent::_prepareLayout();
}
}
YOUR_THEME\Magento_Catalog\templates\product\breadcrumbs.phtml
<?php if ($crumbs && is_array($crumbs)) : ?>
<div class="breadcrumbs">
<ul class="items">
<?php foreach ($crumbs as $crumbName => $crumbInfo) : ?>
<?php
$label = $block->escapeHtml($crumbInfo['label']);
$link = $block->escapeUrl($crumbInfo['link']);
?>
<li class="item <?php /* @escapeNotVerified */ echo $block->escapeHtml($crumbName) ?>">
<?php if ($link) : ?>
<a href="<?php /* @escapeNotVerified */ echo $link ?>"
title="<?= $block->escapeHtml($crumbInfo['title']) ?>">
<?= $label ?>
</a>
<?php elseif ($crumbInfo['last']) : ?>
<strong><?= $label ?></strong>
<?php else: ?>
<?= $label ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
Thank you it work for me ! juste some improvement to get the key in phtml like default breadcrumb
public function getCrumbs()
{
$evercrumbs = array();
$evercrumbs[] = array(
'label' => 'Home',
'title' => 'Go to Home Page',
'link' => $this->_storeManager->getStore()->getBaseUrl(),
'key' => 'home'
);
$path = $this->_catalogData->getBreadcrumbPath();
$product = $this->registry->registry('current_product');
$categoryCollection = clone $product->getCategoryCollection();
$categoryCollection->clear();
$categoryCollection->addAttributeToSort('level', $categoryCollection::SORT_ORDER_DESC)->addAttributeToFilter('path', array('like' => "1/" . $this->_storeManager->getStore()->getRootCategoryId() . "/%"));
$categoryCollection->setPageSize(1);
$breadcrumbCategories = $categoryCollection->getFirstItem()->getParentCategories();
foreach ($breadcrumbCategories as $category) {
$evercrumbs[] = array(
'label' => $category->getName(),
'title' => $category->getName(),
'link' => $category->getUrl(),
'key' => $category->getUrlKey()
);
}
$evercrumbs[] = array(
'label' => $product->getName(),
'title' => $product->getName(),
'link' => '',
'key' => $product->getUrlKey()
);
return $evercrumbs;
}
and in phtml file replace
<li class="item <?= /* @escapeNotVerified */ $crumbName ?>">
by
<li class="item <?= /* @escapeNotVerified */ $crumbInfo['key'] ?>">
I also have error with the file module.xml in your github so i change it to
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Harrigo_EverCrumbs" active="true" setup_version="1.0.1"/>
In design/frontend/VendorTheme/ThemeName/Magento_Catalog/layout/catalog_product_view.xml
<?xml version="1.0"?>
<page>
<body>
<referenceBlock name="breadcrumbs" remove="true" />
<referenceContainer name="page.top">
<block class="VendorName\Breadcrumbs\Block\CatalogBreadcrumbs" name="product.view.breadcrumbs" template="VendorName_Breadcrumbs::breadcrumbs.phtml" />
</referenceContainer>
</body>
</page>
In app/design/frontend/VendorTheme/ThemeName/Magento_Theme/templates/html/breadcrumbs.phtml:
<?php $crumbs = $block->getBreadcrumb(); ?>
<?php if ($crumbs && is_array($crumbs)) : ?>
<div class="breadcrumbs">
<ul class="items">
<?php foreach ($crumbs as $crumbName => $crumbInfo) : ?>
<li class="item <?= /* @escapeNotVerified */ $crumbName ?>">
<?php if ($crumbInfo['link']) : ?>
<a href="<?= /* @escapeNotVerified */ $crumbInfo['link'] ?>" title="<?= $block->escapeHtml($crumbInfo['title']) ?>"><?= $block->escapeHtml($crumbInfo['label']) ?></a>
<?php else: ?>
<?= $block->escapeHtml($crumbInfo['label']) ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
In Block/CatalogBreadcrumbs.php:
<?php
namespace VendorName\Breadcrumbs\Block;
use Magento\Catalog\Helper\Data;
use Magento\Framework\View\Element\Template\Context;
class CatalogBreadcrumbs extends \Magento\Theme\Block\Html\Breadcrumbs
{
/**
* Catalog data
*
* @var Data
*/
protected $_catalogData = null;
protected $path = array();
/**
* @param Context $context
* @param Data $catalogData
* @param array $data
*/
public function __construct(Context $context, Data $catalogData, array $data = [])
{
$this->_catalogData = $catalogData;
parent::__construct($context, $data);
}
public function getTitleSeparator($store = null)
{
$separator = (string) $this->_scopeConfig->getValue('catalog/seo/title_separator', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
return ' ' . $separator . ' ';
}
public function getBreadcrumb()
{
$this->addCrumb(
'home', [
'label' => __('Home'),
'title' => __('Go to Home Page'),
'link' => $this->getBaseUrl()
]
);
foreach ((array) $this->path as $name => $breadcrumb) {
$this->addCrumb($name, $breadcrumb);
}
return $this->getCrumbs();
}
protected function _prepareLayout()
{
$this->path = $this->_catalogData->getBreadcrumbPath();
$title = [];
foreach ((array) $this->path as $name => $breadcrumb) {
$title[] = $breadcrumb['label'];
}
return $this->pageConfig->getTitle()->set(join($this->getTitleSeparator(), array_reverse($title)));
//return parent::_prepareLayout();
}
public function getCrumbs()
{
return $this->_crumbs;
}
public function getBaseUrl()
{
return $this->_storeManager->getStore()->getBaseUrl();
}
}
If you got it, let me know.