Magento 产品详细信息页面上缺少面包屑类别名称
我正在研究Magento 2.1.1。当我从产品列表页面打开产品页面时,我无法在面包屑上看到类别名称。它只显示主页url,后跟产品名称。我很少能看到带有类别名称的完整面包屑Magento 产品详细信息页面上缺少面包屑类别名称,magento,magento2,breadcrumbs,Magento,Magento2,Breadcrumbs,我正在研究Magento 2.1.1。当我从产品列表页面打开产品页面时,我无法在面包屑上看到类别名称。它只显示主页url,后跟产品名称。我很少能看到带有类别名称的完整面包屑 有人能给我一些解决此问题的方法吗?此问题已报告给Magento 2 GitHub存储库,如下所示: 评论中链接了一个要点,该要点有一个解决方法: 我没有尝试过上述解决方法,但人们说它并不总是有效的 同时,以下各项似乎运行良好(我刚刚对其进行了测试): [供应商]/[模块]/etc/frontend/events.xml
有人能给我一些解决此问题的方法吗?此问题已报告给Magento 2 GitHub存储库,如下所示: 评论中链接了一个要点,该要点有一个解决方法:
我没有尝试过上述解决方法,但人们说它并不总是有效的 同时,以下各项似乎运行良好(我刚刚对其进行了测试):
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_controller_product_init_after">
<observer instance="[Vendor]\[Module]\Observer\Catalog\Product\FullPathBreadcrumbs" name="addProductFullPathBreadcrumbs"/>
</event>
</config>
<?php
namespace [Vendor]\[Module]\Observer\Catalog\Product;
class FullPathBreadcrumbs implements \Magento\Framework\Event\ObserverInterface
{
protected $_registry;
protected $_categoryRepository;
public function __construct(
\Magento\Framework\Registry $registry,
\Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
) {
$this->_registry=$registry;
$this->_categoryRepository = $categoryRepository;
}
/**
* Execute observer
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(
\Magento\Framework\Event\Observer $observer
) {
$product = $observer->getEvent()->getProduct();
if ($product != null && !$this->_registry->registry('current_category')) {
$cats = $product->getAvailableInCategories();
if(sizeof($cats)===1){
$last = $cats[0];
}else{
end($cats);
$last = prev($cats);
}
if($last) {
$category = $this->_categoryRepository->get($last);
$this->_registry->register('current_category', $category, true);
}
}
}
}
我找到了解决方案,已获得Magento团队的批准。因为如果您使用块重写或插件的方法,并且您有一些使用Breadcrumbs block或Magento\Catalog\Controller\Product\View.php的扩展,那么您将遇到问题。
因此,您只需定制app/code/Magento/Catalog/view/frontend/web/js/product/breadcrumbs.js。
下面是完整的代码:
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'Magento_Theme/js/model/breadcrumb-list'
], function ($, breadcrumbList) {
'use strict';
return function (widget) {
$.widget('mage.breadcrumbs', widget, {
options: {
categoryUrlSuffix: '',
useCategoryPathInUrl: false,
product: '',
menuContainer: '[data-action="navigation"] > ul'
},
/** @inheritdoc */
_render: function () {
this._appendCatalogCrumbs();
this._super();
},
/**
* Append category and product crumbs.
*
* @private
*/
_appendCatalogCrumbs: function () {
var categoryCrumbs = this._resolveCategoryCrumbs();
categoryCrumbs.forEach(function (crumbInfo) {
breadcrumbList.push(crumbInfo);
});
if (this.options.product) {
breadcrumbList.push(this._getProductCrumb());
}
},
/**
* Resolve categories crumbs.
*
* @return Array
* @private
*/
_resolveCategoryCrumbs: function () {
var menuItem = this._resolveCategoryMenuItem(),
categoryCrumbs = [];
if (menuItem !== null && menuItem.length) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
}
}
return categoryCrumbs;
},
/**
* Returns crumb data.
*
* @param {Object} menuItem
* @return {Object}
* @private
*/
_getCategoryCrumb: function (menuItem) {
return {
'name': 'category',
'label': menuItem.text(),
'link': menuItem.attr('href'),
'title': ''
};
},
/**
* Returns product crumb.
*
* @return {Object}
* @private
*/
_getProductCrumb: function () {
return {
'name': 'product',
'label': this.options.product,
'link': '',
'title': ''
};
},
/**
* Find parent menu item for current.
*
* @param {Object} menuItem
* @return {Object|null}
* @private
*/
_getParentMenuItem: function (menuItem) {
var classes,
classNav,
parentClass,
parentMenuItem = null;
if (!menuItem) {
return null;
}
classes = menuItem.parent().attr('class');
classNav = classes.match(/(nav\-)[0-9]+(\-[0-9]+)+/gi);
if (classNav) {
classNav = classNav[0];
parentClass = classNav.substr(0, classNav.lastIndexOf('-'));
if (parentClass.lastIndexOf('-') !== -1) {
parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');
parentMenuItem = parentMenuItem.length ? parentMenuItem : null;
}
}
return parentMenuItem;
},
/**
* Returns category menu item.
*
* Tries to resolve category from url or from referrer as fallback and
* find menu item from navigation menu by category url.
*
* @return {Object|null}
* @private
*/
_resolveCategoryMenuItem: function () {
var categoryUrl = this._resolveCategoryUrl(),
menu = $(this.options.menuContainer),
categoryMenuItem = null;
if (categoryUrl && menu.length) {
categoryMenuItem = menu.find('a[href="' + categoryUrl + '"]');
}
return categoryMenuItem;
},
/**
* Returns category url.
*
* @return {String}
* @private
*/
_resolveCategoryUrl: function () {
var categoryUrl;
if (this.options.useCategoryPathInUrl) {
// In case category path is used in product url - resolve category url from current url.
categoryUrl = window.location.href.split('?')[0];
categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +
this.options.categoryUrlSuffix;
} else {
// In other case - try to resolve it from referrer (without parameters).
categoryUrl = document.referrer;
if (categoryUrl.indexOf('?') > 0) {
categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));
}
}
return categoryUrl;
}
});
return $.mage.breadcrumbs;
};
});
这里有一个指向合并请求的链接:我找到了解决上述问题的方法。请检查下面的js文件。
供应商/magento/module catalog/view/frontend/web/js/product/breadcrumbs.js
通过使用菜单,breadcrumbs.js文件接受了一些类。如果您正在自定义菜单,则“面包屑产品详细信息”页面中将缺少类别名称。
菜单必须具有以下类别:
1) 菜单导航部分必须有“数据操作=“导航”。
2) 菜单li元素必须具有“类别项”类。
3) 父li元素必须具有“nav-1”、“nav-2”、“类”,子li(“nav-1”)元素必须具有“nav-1-1”、“nav-1-2”等
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'Magento_Theme/js/model/breadcrumb-list'
], function ($, breadcrumbList) {
'use strict';
return function (widget) {
// calling menu class and data-action "categoryItemSelector","menuContainer"**
$.widget('mage.breadcrumbs', widget, {
options: {
categoryUrlSuffix: '',
useCategoryPathInUrl: false,
product: '',
categoryItemSelector: '.category-item',
menuContainer: '[data-action="navigation"] > ul'**
},
/** @inheritdoc */
_render: function () {
this._appendCatalogCrumbs();
this._super();
},
/**
* Append category and product crumbs.
*
* @private
*/
_appendCatalogCrumbs: function () {
var categoryCrumbs = this._resolveCategoryCrumbs();
categoryCrumbs.forEach(function (crumbInfo) {
breadcrumbList.push(crumbInfo);
});
if (this.options.product) {
breadcrumbList.push(this._getProductCrumb());
}
},
/**
* Resolve categories crumbs.
*
* @return Array
* @private
*/
_resolveCategoryCrumbs: function () {
var menuItem = this._resolveCategoryMenuItem(),
categoryCrumbs = [];
if (menuItem !== null && menuItem.length) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
}
}
return categoryCrumbs;
},
/**
* Returns crumb data.
*
* @param {Object} menuItem
* @return {Object}
* @private
*/
_getCategoryCrumb: function (menuItem) {
return {
'name': 'category',
'label': menuItem.text(),
'link': menuItem.attr('href'),
'title': ''
};
},
/**
* Returns product crumb.
*
* @return {Object}
* @private
*/
_getProductCrumb: function () {
return {
'name': 'product',
'label': this.options.product,
'link': '',
'title': ''
};
},
/**
* Find parent menu item for current.
*
* @param {Object} menuItem
* @return {Object|null}
* @private
*/
_getParentMenuItem: function (menuItem) {
var classes,
classNav,
parentClass,
parentMenuItem = null;
if (!menuItem) {
return null;
}
classes = menuItem.parent().attr('class');
// calling menu nav class**********
**classNav = classes.match(/(nav\-)[0-9]+(\-[0-9]+)+/gi);**
if (classNav) {
classNav = classNav[0];
parentClass = classNav.substr(0, classNav.lastIndexOf('-'));
if (parentClass.lastIndexOf('-') !== -1) {
parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');
parentMenuItem = parentMenuItem.length ? parentMenuItem : null;
}
}
return parentMenuItem;
},
/**
* Returns category menu item.
*
* Tries to resolve category from url or from referrer as fallback and
* find menu item from navigation menu by category url.
*
* @return {Object|null}
* @private
*/
_resolveCategoryMenuItem: function () {
var categoryUrl = this._resolveCategoryUrl(),
menu = $(this.options.menuContainer),
categoryMenuItem = null;
if (categoryUrl && menu.length) {
categoryMenuItem = menu.find(
this.options.categoryItemSelector +
' > a[href="' + categoryUrl + '"]'
);
}
return categoryMenuItem;
},
/**
* Returns category url.
*
* @return {String}
* @private
*/
_resolveCategoryUrl: function () {
var categoryUrl;
if (this.options.useCategoryPathInUrl) {
// In case category path is used in product url - resolve category url from current url.
categoryUrl = window.location.href.split('?')[0];
categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +
this.options.categoryUrlSuffix;
} else {
// In other case - try to resolve it from referrer (without parameters).
categoryUrl = document.referrer;
if (categoryUrl.indexOf('?') > 0) {
categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));
}
}
return categoryUrl;
}
});
return $.mage.breadcrumbs;
};
});
您好,这是正常的行为。在Magento2和1中。假设您的产品P属于类别B,其父类别为a。他打开搜索页面=>无面包屑。他打开a类别,产品P=>面包屑将成为a/P。他打开类别B,则产品=>面包屑将成为a/B/P。因此,相同的产品但不是相同的面包屑。这允许magento为多个类别的产品正确处理面包屑。嗨,我同意你的观点。但对我来说,类别面包屑不能像上面那样工作。当打开类别B时,产品=>面包屑将是A/B/P,但在我的情况下,面包屑就像这个Home/P一样,类别会丢失gHi,有关于这个问题的更新吗?嗨,如果有关于这个问题的更新,请告诉我。嗨,任何人对这个问题都有任何想法。检查最新版本有一个版本,它基于您上次所在的类别/位置创建面包屑。如果您有多个选项卡/窗口作为一个cate打开,这有点奇怪如果您使用相同的会话空间在另一个选项卡/窗口中导航到某个类别,则不在类别中的gory可以显示面包屑。感谢您的回答,这对我很有帮助,因为我使用了此js代码,但仍然无法在产品详细信息页上获取类别名称。@Vladishev这是新添加的功能吗?我的2.2.2版本中没有n、 另外,当产品url中未包含的类别似乎不正确时,请使用文档查看resolveCategoryUrl
中的breadcrumbs.js
。我刚刚做了一个测试,它仅在您来自类别页面且未刷新页面时有效,否则页面为空