Magento 产品详细信息页面上缺少面包屑类别名称

Magento 产品详细信息页面上缺少面包屑类别名称,magento,magento2,breadcrumbs,Magento,Magento2,Breadcrumbs,我正在研究Magento 2.1.1。当我从产品列表页面打开产品页面时,我无法在面包屑上看到类别名称。它只显示主页url,后跟产品名称。我很少能看到带有类别名称的完整面包屑 有人能给我一些解决此问题的方法吗?此问题已报告给Magento 2 GitHub存储库,如下所示: 评论中链接了一个要点,该要点有一个解决方法: 我没有尝试过上述解决方法,但人们说它并不总是有效的 同时,以下各项似乎运行良好(我刚刚对其进行了测试): [供应商]/[模块]/etc/frontend/events.xml

我正在研究Magento 2.1.1。当我从产品列表页面打开产品页面时,我无法在面包屑上看到类别名称。它只显示主页url,后跟产品名称。我很少能看到带有类别名称的完整面包屑


有人能给我一些解决此问题的方法吗?

此问题已报告给Magento 2 GitHub存储库,如下所示:

评论中链接了一个要点,该要点有一个解决方法:

我没有尝试过上述解决方法,但人们说它并不总是有效的

同时,以下各项似乎运行良好(我刚刚对其进行了测试):

  • [供应商]/[模块]/etc/frontend/events.xml

    <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>
    
    
    
  • [供应商]/[模块]//观察者/目录/产品/FullPathBreadcrumbs

    <?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
    。我刚刚做了一个测试,它仅在您来自类别页面且未刷新页面时有效,否则页面为空