magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.56k stars 9.32k forks source link

Problems with breadcrumbs #7967

Closed susmithaN closed 6 years ago

susmithaN commented 7 years ago

Preconditions

I have some problems with breadcrumbs . Im using

  1. Magento ver. 2.1.1
  2. PHP Version 7.1.0

Steps to reproduce

  1. Open Product from list page List page - http://prnt.sc/doeoxy

Expected result

  1. details page should contain breadcrumbs in this format Home -> Category name ->Product Name

    Home > Proteasome Inhibitors > MG-132

Actual result

  1. Home > MG-132 - Category missing Detail page - http://prnt.sc/doeqa2

Is it possible to get full breadcrumb with Magento 2 ?

veloraven commented 7 years ago

@susmithaN thank you for your submission. Please add exact steps how to reproduce the issue to the Steps section, without links to external resources.

susmithaN commented 7 years ago

Hi ,

Steps to reproduce

1 . GO to category page (product list page ) from home page . 2 . From category page to product detail page . 3 . On product detail page , breadcrumbs looks like Home > Product name But the expected result is Home > category name > product name

yumicom commented 7 years ago

I have same problem. How to display breadcrumbs with full path on product view pages?

ghost commented 7 years ago

Same issue on CE 2.1.3

veloraven commented 7 years ago

We have created internal ticket MAGETWO-63011

susmithaN commented 7 years ago

Hi , Kindly let us know if any updates regarding this issue .

susmithaN commented 7 years ago

Is there any updates regarding this issue ?

susmithaN commented 7 years ago

Anyone have any idea about this issue ?

ghost commented 7 years ago

Just made an update to version 2.1.4 via web wizard, still got those broken breadcrumbs.

susmithaN commented 7 years ago

Hi , I have checked this issue on Latest version , There also i faced the same breadcrumbs issues. I Found an option to add category with product url from back end . Once enabled it Breadcrumbs with category displayed on product detail page . But If I open the same product from any other page like home , search , its not displaying full breadcrumbs . Just showing Home-> product name . Can you please suggest any solution for this .

orlangur commented 7 years ago

PHP Version 7.1.0

Is it correct? This PHP version is not supported yet.

Is issue reproducible when you disable caches?

ghost commented 7 years ago

I am on PHP Version 5.3.6 and Magento 2 Version 2.1.4. Issue occures even with cache disabled. Dev and production mode are equally affected.

susmithaN commented 7 years ago

Hi , Anyone have any suggestion to solve this issue .

susmithaN commented 7 years ago

Hi , Please let me know if you have any suggestion regarding this issue.

akosglue commented 7 years ago

Hi @susmithaN , disclaimer: this is just an idea for a workaround and not yet tested completely, but maybe you can get a hint from it:

susmithaN commented 7 years ago

Hi , Thank you for your information . I tried this one . But Still got the same problem . I cant able to add missing categories on registry .

susmithaN commented 7 years ago

Hi , Any other suggestion to solve this problem .

sambolek commented 7 years ago

This was the case in M1 as well, if you had "Use category path for product URL" set to "No" https://www.creare.co.uk/wp-content/uploads/2014/03/fdf-2-658x328.jpg

Only with category path in URL, Magento could resolve which category should be in breadcrumbs path. This sure is unfortunate, but don't believe it's a bug, as we cannot simply guess what category to show at the top, unless we add some sort of query parameter to URL that would identify which category the product was accessed from.

orlangur commented 7 years ago

we cannot simply guess what category to show at the top, unless we add some sort of query parameter to URL

If a product belongs to only one category, we can use it in breadcrumbs. However, if in this issue Use category path for product URL = "No" it would be not correct to change breadcrumbs this way as breadcrumbs should reflect site navigation, not some random stuff.

sambolek commented 7 years ago

Exactly. I'm thinking that having inconsistent breadcrumbs, where we show a category path if product is in only one caregory, and nothing (or random/last assigned category) if it's in multiple categories would be more hurtful than this.

Presume we have two choices here: 1) Leave it as is, but maybe describe in documentation what are the consequences of setting "Use category path for product URL" to " No" 2) Figure out a way of implementing history-based breadcrumbs that work with Varnish/FPC (there were some M1 extensions that relied to HTTP referrer, but that would introduce another layer of problems with caching)

To conclude, this is more of a feature request than a bug report.

susmithaN commented 7 years ago

Thank you for the information ,

ghost commented 7 years ago

but don't believe it's a bug, as we cannot simply guess what category to show at the top, unless we add some sort of query parameter to URL that would identify which category the product was accessed from.

Fine but why do I sometimes get a full breadcrumb when I follow my category up to the product from the front page and sometimes not? That makes no sense.

MattSewing commented 7 years ago

Totally agree with salacis

I have the same problem, one moment i have full category path - the next i don't.

Sometimes I can have the full path in the breadcrumb, 5 mins later I can refresh the page, and it changes.

mbahar commented 7 years ago

As a solution; To override the inconsistent behaviour, I override the block; Magento\Catalog\Block\Breadcrumbs

with the following; https://gist.github.com/mbahar/82703c4b95d924d9bc8e6990202fdeba

gabriel-au commented 7 years ago

@MattSewing

Sometimes I can have the full path in the breadcrumb, 5 mins later I can refresh the page, and it changes.

It happens with TopMenu as well.

The normal behaviour is: show the full path on the breadcrumbs area and mark the actual category in orange (at the beginning of the cell)

@mbahar

As a solution; To override the inconsistent behaviour, I override the block; Magento\Catalog\Block\Breadcrumbs with the following; https://gist.github.com/mbahar/82703c4b95d924d9bc8e6990202fdeba

Is also a solution for top menu?

novakivskiy commented 7 years ago

You can also use event - catalog_controller_product_init_after 1) [Vendor]/[Module]/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>
  1. [Vendor]/[Module]//Observer/Catalog/Product/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);
        }
    }
}

}

pieal86 commented 7 years ago

same issue. still looking for a solution. Need to show always the longest path in breadcrumb.

MMaKenZi commented 7 years ago

Same problem with 2.1.8/PHP 7.0.22 still waiting for a permanent fix!

yumicom commented 7 years ago

same issue with 2.1.8. still looking for a solution.

yumicom commented 7 years ago

Working solution from mbahar https://gist.github.com/mbahar/82703c4b95d924d9bc8e6990202fdeba

pieal86 commented 7 years ago

This shows the last category if browse from homepage.. but if product is browsed from category>sub-category> it shows different breadcrumb. And still not showing full path.

Working solution from mbahar

https://gist.github.com/mbahar/82703c4b95d924d9bc8e6990202fdeba

Any product , even clicked from a direct link should always show full path.. Example:Home> category> sub-category> sub-sub-category> Product title. Any solution or work arround for this?

yumicom commented 7 years ago

Yes, solution from mbahar shows different breadcrumb.

orlangur commented 7 years ago

@yumicom @pieal86 the problem is that if there is no category path in product URL with FPC enabled there is no way to determine category structure.

This shows the last category if browse from homepage

It seems to be obtained from referer in core implementation.

Need to show always the longest path in breadcrumb.

It means you need a custom implementation with such logic, good news is that you can cache breadcrumbs on product page for all customers/visitors.

J-Fricke commented 7 years ago

Having the same issue where sometimes it's full Breadcrumb and sometimes it's missing category parts.

Behavior I'd expect is for it to default to the first top level category then follow that path down.

Example:

Product 1 exists in both 1 & 2 above will display Home > Category 1 ... > Product Product 2 exists in both 1 & 3 above will display Home > Category 1 ... > Product Product 3 exists in both 2 & 3 above will display Home > Category 2 ... > Product Product 3 exists in only 3 above will display Home > Category 3 ... > Product

In addition, there probably should be a way to override that behavior to force say Product 3 in the example to display Home > Category 3 ... > Product

Regardless of how we end up with a solution, it should be something which is saved and consistent across the catalog at all times.

For those who want the breadcrumbs to reflect the category someone most recently came from, I'd recommend creating an extension which cookies the last category a user was in or something as such to hold that state information. Or there is also the suggestion of appending something to the URL.

magento-engcom-team commented 7 years ago

@susmithaN, thank you for your report. We've created internal ticket(s) MAGETWO-63011, MAGETWO-80697 to track progress on the issue.

BigTonni commented 6 years ago

I have a same issue with 2.1.6. Still looking for a solution.

jonahellison commented 6 years ago

Breadcrumbs use catalog session data (the last category the user viewed) for rendering, which seems to be a flaw since this is then cached and displayed to other users.

One workaround is to use another event observer (such as layout_load_before) along with https://github.com/magento/magento2/issues/7967#issuecomment-315310890 to remove this data:

        // @var \Magento\Catalog\Model\Session $catalogSession
        $this->catalogSession
            ->unsetData('last_visited_category_id')
            ->unsetData('last_viewed_category_id');
magefan commented 6 years ago

Based on @novakivskiy suggestion we have created a temporary solution magefan/module-catalog.

You can simply install it via composer

elvinristi commented 6 years ago

I'm using this in following way so this doesn't affect performance - don't load unnecessary objects :

File contents for etc/module.xml :

<?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="Vendor_MyModuleName" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

File contents for etc/frontend/events.xml :

<?xml version="1.0"?>
<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\MyModuleName\Observer\Catalog\Product\InitAfter" name="execute"/>
    </event>
</config>

File contents for Observer/Catalog/Product/InitAfter.php :

<?php

namespace Vendor\MyModuleName\Observer\Catalog\Product;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

class InitAfter implements \Magento\Framework\Event\ObserverInterface
{
    const LEVEL_LARGER_THAN = 2;

    /**
     * @var \Magento\Framework\Registry
     */
    private $registry;

    /**
     * @var \Magento\Catalog\Api\CategoryRepositoryInterface
     */
    private $categoryRepository;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var \Magento\Framework\App\ResourceConnection
     */
    private $resource;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\Framework\DB\Adapter\AdapterInterface
     */
    private $connection;

    public function __construct(
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
        ScopeConfigInterface $scopeConfig,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->registry = $registry;
        $this->categoryRepository = $categoryRepository;
        $this->scopeConfig = $scopeConfig;

        $this->resource = $resource;
        $this->storeManager = $storeManager;
    }

    /**
     * Execute observer
     *
     * @param \Magento\Framework\Event\Observer $observer
     *
     * @return void
     */
    public function execute(
        \Magento\Framework\Event\Observer $observer
    ) {
        /** @var \Magento\Catalog\Model\Product $currentProduct */
        $currentProduct  = $observer->getEvent()->getProduct();
        /** @var \Magento\Catalog\Model\Category $currentCategory */
        $currentCategory = $this->registry->registry('current_category');

        $categoryIds = (array)$currentProduct->getAvailableInCategories();

        if ($currentCategory !== null
            && in_array($currentCategory->getId(), $categoryIds)
            && array_search($currentCategory->getId(), $categoryIds) === 0
        ) {
            return;
        }

        if (empty($categoryIds)) {
            return;
        }

        $connection = $this->resource->getConnection();

        $categoryId = $connection->fetchOne(
            $connection->select()->from(
                $this->resource->getTableName('catalog_category_product_index'), 'category_id'
            )->join(
                array('ce' => $this->resource->getTableName('catalog_category_entity')), 'ce.entity_id = category_id', array()
            )->where(
                'product_id = ?', $currentProduct->getId()
            )->where(
                'store_id = ?', $this->storeManager->getStore()->getId()
            )->where(
                'is_parent = 1'
            )->where(
                'category_id IN (?)', $categoryIds
            )->where('ce.level > ?', self::LEVEL_LARGER_THAN)
        );

        if (empty($categoryId)) {
            return;
        }

        if ($currentCategory) {
            $this->registry->unregister('current_category');
        }

        try {
            $category = $this->categoryRepository->get($categoryId);
        } catch (NoSuchEntityException $e) {
            $category = null;
        }

        if ($category) {
            $currentProduct->setCategory($category);
            $this->registry->register('current_category', $category, true);
        }
    }
}
pioneerathletics commented 6 years ago

Has this issue been fixed in any 2.1 version? I am also currently experiencing this in 2.1.10- Products will show home > category > category > product name and then after some time it just shows home > product name.

subbu1993 commented 6 years ago

Hello - @magento-engcom-team

Is there an update on this issue ?

Can we expect a fix anytime soon ?

sambolek commented 6 years ago

since 2.2.3 breadcrumbs are a JS widget that relies on page referer to get category path https://github.com/magento/magento2/blob/2.2-develop/app/code/Magento/Catalog/view/frontend/web/js/product/breadcrumbs.js

orlangur commented 6 years ago

@susmithaN @magento-engcom-team looks like the issue is fixed in 2.2.x.

MattSewing commented 6 years ago

Hi Guys

As the author of this post, I have come to the conclusion a year on, that it cannot be done. I am not a programmer. But I have asked a lot of programmers the question and have drawn a blank.

After some investigation, I believe this extension will sort the issue out: https://amasty.com/unique-product-url-for-magento-2.html

We will be launching this extension as part of a bigger upgrade later this month… after using the demo I see no reason why this won’t work for our website too.

Hope that helps…

Matt

From: Subramaniam Swamynathan notifications@github.com Sent: 02 July 2018 23:10 To: magento/magento2 magento2@noreply.github.com Cc: Matt Timmins Matt@thesewingstudio.co.uk; Mention mention@noreply.github.com Subject: Re: [magento/magento2] Problems with breadcrumbs (#7967)

Hello - @magento-engcom-teamhttps://github.com/magento-engcom-team

Is there an update on this issue ?

Can we expect a fix anytime soon ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/magento/magento2/issues/7967#issuecomment-401952876, or mute the threadhttps://github.com/notifications/unsubscribe-auth/Abt2087NJifcusJ4fdT4LA6dUQtbhGBWks5uCpocgaJpZM4LWN0f.

orlangur commented 6 years ago

@MattSewing,

As the author of this post, I have come to the conclusion a year on, that it cannot be done

Well, any kind of logic can be done :) But without referer and if product can be assigned to more than one category, logic is really not clear to me.

LucScu commented 6 years ago

@magento-engcom-team @orlangur please close this issue, because it is not an issue. It is clear that without a referer or parametrized url is not possible to construct the complete product's breadcrumbs with categories.

magento-engcom-team commented 6 years ago

Closing. Thank you

Yamaha32088 commented 5 years ago

The problem appears to be a typo in this file https://github.com/magento/magento2/blob/0eb8677b0b4e35606032e856cc1ef7c80e68829f/app/code/Magento/Catalog/ViewModel/Product/Breadcrumbs.php#L108 it should be useCategoryPathInUrl instead because https://github.com/magento/magento2/blob/0d9962302eb40c402c4080338fce45efa2744f93/app/code/Magento/Catalog/view/frontend/web/js/product/breadcrumbs.js#L17 is looking for it

sidolov commented 5 years ago

Hi @susmithaN. Thank you for your report. The issue has been fixed in magento/magento2#19760 by @Yamaha32088 in 2.2-develop branch Related commit(s):

The fix will be available with the upcoming 2.2.9 release.

robertbaum commented 4 years ago

yes I saw that the issue caused by the cache when someone opens the product from the search or from a custom widget the product page will be opened without category breadcrumbs and as well will be cached as it