कस्टम पेज पर कस्टम संग्रह के लिए स्तरित नेविगेशन - magento2


12

मैं कस्टम उत्पाद संग्रह के लिए magento2 में स्तरित नेविगेशन लाने पर काम कर रहा हूं। मुझे कस्टम संग्रह मिल रहा है पहले से ही कस्टम पेज पर स्तरित नेविगेशन दिखाने की आवश्यकता है। इस Magento1 समाधान को अनुकूलित करने की कोशिश की, लेकिन दूर नहीं जा सका।

किसी भी विचार मैं इसे magento2 में कैसे प्राप्त कर सकता था। मैंने अभी तक जो किया है वह नीचे है:

मेरे कस्टम पृष्ठ पर कस्टम उत्पाद सूची के लिए कैटलॉग ListProduct ब्लॉक विस्तारित करें।

class View extends \Magento\Catalog\Block\Product\ListProduct
{


    public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver,
    CategoryRepositoryInterface $categoryRepository,
    \Magento\Framework\Url\Helper\Data $urlHelper,
    array $data = [],
    \Custom\LayerNavigation\Model\Layer $testlayerobj
    ) {
        parent::__construct($context,$postDataHelper,$layerResolver,
        $categoryRepository,$urlHelper,$data);
        $this->_coreRegistry = $context->getRegistry();
        $this->_testlayer = $testlayerobj;
    }

    protected function _getProductCollection()
    {
        if ($this->_productCollection === null) {
          $this->_productCollection = $this->getLayer()->getProductCollection();
        }
        return $this->_productCollection;
     }

    public function getLayer()
    {

       $layer = $this->_coreRegistry->registry('current_layer');
       if ($layer) {
          return $layer;
        }
        return $this->_testlayer;
     }

}

लेआउट फ़ाइल में स्तरित नेविगेशन के लिए कोर खोज ब्लॉक का उपयोग किया

<referenceContainer name="sidebar.main">
        <block class="Magento\LayeredNavigation\Block\Navigation\Search" name="catalogsearch.leftnav" before="-" template="layer/view.phtml">
            <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalogsearch.navigation.state" as="state" />
            <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalogsearch.navigation.renderer" as="renderer" template="layer/filter.phtml"/>
        </block>
</referenceContainer>

विस्तारित कोर परत मॉडल संग्रह को संशोधित करने के लिए।

class Layer extends \Magento\Catalog\Model\Layer
{
    public function __construct(
      optionStoreFactory  $optionstoreFactory,
      Attrhelper $attrhelper,
      productCollectionFactory $productCollectionFactory,
      AttributevalueFactory $attributevalueFactory,
      CategoryRepositoryInterface $categoryRepository,
      \Magento\Store\Model\StoreManagerInterface $storeManager,
      \Magento\Framework\App\Request\Http $request,
      \Magento\Framework\Registry $registry,
      \Magento\Catalog\Model\Layer\Search\CollectionFilter $filter,
      array $data = []
    ) {
       $this->optionstoreFactory       = $optionstoreFactory;
       $this->attributevalueFactory    = $attributevalueFactory;
       $this->_attrhelper              = $attrhelper;
       $this->request                  = $request;
       $this->productCollectionFactory = $productCollectionFactory;
       $this->categoryRepository = $categoryRepository;
       $this->_storeManager = $storeManager;
       $this->filter = $filter;
       $this->registry = $registry;
    }

    public function getProductCollection()
    {
        $attributevalue = $this->getAttributeValue(); //eg: Manufacturer Attribute details
        $attr_code = $attributevalue->getAttributeCode();
        $attr_option_value = $attributevalue->getOptionId();
        $collection = $this->productCollectionFactory->create();
        $store_id = $this->request->getParam('store_id');
        $collection->addAttributeToSelect('*')
               ->addAttributeToFilter($attr_code , ['finset'=>$attr_option_value ])
               ->addAttributeToFilter('visibility','4')
               ->setStore($store_id)
               ->addFieldToFilter('status', array('eq' => 1))
               ->setOrder('id', 'DESC');
        $this->prepareProductCollection($collection);
        return $collection;
    }

    public function prepareProductCollection($collection)
    {
        $this->filter->filter($collection, $this->getCurrentCategory());
       return $this;
    }

    public function getCurrentCategory()
    {
       $category = $this->registry->registry('current_category');
       if ($category) {
           $this->setData('current_category', $category);
       } else {
           $category = $this->categoryRepository->get($this->getCurrentStore()->getRootCategoryId());
       $this->setData('current_category', $category);
       }
      return $category;
    }

    public function getCurrentStore()
    {
        return $this->_storeManager->getStore();
    }

}

अब तक मुझे लेयर नेविगेशन प्रदर्शित हो रहा है, लेकिन यह मेरे कस्टम संग्रह के लिए विशिष्ट नहीं है। मेरे डिबगिंग के अनुसार संग्रह को रूट श्रेणी (जिसमें संपूर्ण उत्पाद सूची शामिल है) से सभी तरह से फ़िल्टर किया जाता है और इसके अनुसार परतों को प्राप्त किया जाता है।


किसी भी सुझाव की बहुत सराहना की जाएगी ..!
एमपी 196

क्या आपको इसका कोई हल मिला? यदि हां, तो कृपया अपना उत्तर
नलिन सांवलिया

दोस्तों आप में से किसी को भी इस पर कोई लीड मिली है ??
aton1004

मैं अपने कस्टम संग्रह के लिए कस्टम पृष्ठ पर स्तरित नेविगेशन प्राप्त करने में सफल रहा ... समाधान को पोस्ट करने के लिए कुछ समय की आवश्यकता होगी क्योंकि यह बहुत लंबा है (संभवतः एक या दो दिन में मैं समाधान पोस्ट कर रहा
हूं

जवाबों:


3

मैं नीचे दिए गए परिवर्तनों के साथ नेविगेशन प्राप्त करने में सक्षम था, मैं इस समाधान के साथ पूरी तरह से सही नहीं हो सकता हूं इसलिए टिप्पणियों और सुझावों का सबसे स्वागत है।

1) नीचे दिए गए अनुभाग के लिए di.xml तैयार करें:

<!-- Magento only includes 2 type of layer resolvers i.e Category and search whereas our custom page is neither a category page nor a search page so we need to add a new layer resolver on our custom page-->
<type name="Magento\Catalog\Model\Layer\Resolver">
    <arguments>
        <argument name="layersPool" xsi:type="array">
            <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Category</item>
            <item name="search" xsi:type="string">Magento\Catalog\Model\Layer\Search</item>
            <item name="customlayer" xsi:type="string">Custom\Navigation\Model\Layer</item>
        </argument>
    </arguments>
</type>

<!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
<virtualType name="customFilterList" type="Custom\Navigation\Model\Layer\FilterList">
    <arguments>
        <argument name="filterableAttributes" xsi:type="object">Custom\Navigation\Model\Layer\FilterableAttributeList</argument>
        <argument name="filters" xsi:type="array">
            <item name="attribute" xsi:type="string">Custom\Navigation\Model\Layer\Filter\Attribute</item>
            <item name="category" xsi:type="string">Custom\Navigation\Model\Layer\Filter\Category</item>
        </argument>
    </arguments>
</virtualType>

<!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
<virtualType name="Custom\Navigation\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
    <arguments>
        <argument name="filterList" xsi:type="object">customFilterList</argument>
    </arguments>
</virtualType>

<!-- As we will be modifying the layer model collection we will need to extend the core model layer, Below virtual type will be required to extend the Catalog model layer else it will throw error for the context in construct method-->
<virtualType name="Custom\Navigation\Model\Layer\Context" type="Magento\Catalog\Model\Layer\Context">
    <arguments>
        <argument name="collectionProvider" xsi:type="object">Custom\Navigation\Model\Layer\ItemCollectionProvider</argument>
        <argument name="stateKey" xsi:type="object">Custom\Navigation\Model\Layer\StateKey</argument>
        <argument name="collectionFilter" xsi:type="object">Custom\Navigation\Model\Layer\CollectionFilter</argument>
    </arguments>
</virtualType>
<type name="Custom\Navigation\Model\Layer">
    <arguments>
        <argument name="context" xsi:type="object">Custom\Navigation\Model\Layer\Context</argument>
    </arguments>
</type>

2) मॉडल परत फ़ाइल: अपने कस्टम मॉडल के साथ मॉडल परत फ़ाइल का विस्तार करें और संग्रह को संशोधित करें।

namespace Custom\Navigation\Model;
class Layer extends \Magento\Catalog\Model\Layer
{

//Apart from the default construct argument you need to add your model from which your product collection is fetched.

    public function __construct(
        \Magento\Catalog\Model\Layer\ContextInterface $context,
        \Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
        AttributeCollectionFactory $attributeCollectionFactory,
        \Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Registry $registry,
        CategoryRepositoryInterface $categoryRepository,
        array $data = []
    ) {
    parent::__construct(
            $context,
            $layerStateFactory,
            $attributeCollectionFactory,
            $catalogProduct,
            $storeManager,
            $registry,
            $categoryRepository,
            $data
        );
    }

    public function getProductCollection()
    {

        /*Unique id is needed so that when product is loaded /filtered in the custom listing page it will be set in the
         $this->_productCollections array with unique key else you will not get the updated or proper collection.
        */

        if (isset($this->_productCollections['some_uinique_id'])) {
            $collection = $this->_productCollections['some_uinique_id'];
        } else {
            //$collection = Your logic to get your custom collection.
            $this->prepareProductCollection($collection);
            $this->_productCollections['some_unique_id'] = $collection;
        }

        return $collection;
    }

3) मैं नीचे दी गई फाइलों को बढ़ाता हूं जैसा कि di.xml में उपयोग किया गया है (केवल फाइल को बढ़ाकर रखा है, निर्माण विधि को तत्काल नहीं किया है क्योंकि मुझे इन फाइल में किसी भी बदलाव की आवश्यकता नहीं है, यदि आप विशिष्ट फ़ाइल में विशिष्ट फ़ंक्शन को संशोधित कर सकते हैं। तदनुसार), वर्तमान में मैंने जो समाधान लागू किया है, वह श्रेणी फ़िल्टर समस्या को हल करने में सक्षम नहीं था, इसमें अभी भी रूट श्रेणी के फ़िल्टर शामिल हैं ताकि faceteddata (4 बिंदु में वर्णित वर्कअराउंड) को शामिल करने के लिए वर्कअराउंड करना पड़े

- Custom\Navigation\Model\Layer\FilterList extends
           \Magento\Catalog\Model\Layer\FilterList



 - Custom\Navigation\Model\Layer\FilterableAttributeList extends
   \Magento\Catalog\Model\Layer\Category\FilterableAttributeList



 - Custom\Navigation\Model\Layer\Filter\Attribute extends
   \Magento\Catalog\Model\Layer\Filter\Attribute



 - Custom\Navigation\Model\Layer\Filter\Category extends
   \Magento\CatalogSearch\Model\Layer\Filter\Category (Why catalog
           search is used i have mentioned the same in 4th point)



 - Custom\Navigation\Model\Layer\ItemCollectionProvider extends
   \Magento\Catalog\Model\Layer\Category\ItemCollectionProvider



 - Custom\Navigation\Model\Layer\StateKey extends
   \Magento\Catalog\Model\Layer\Category\StateKey



 - Custom\Navigation\Model\Layer\CollectionFilter extends
   \Magento\Catalog\Model\Layer\Category\CollectionFilter

4) स्तरित नेविगेशन में श्रेणी फिल्टर के लिए एक वर्कअराउंड करना था क्योंकि यह फ़िल्टर किए गए संग्रह के संबंध में विकल्प नहीं दिखा रहा था, यदि कोई भी समाधान पाता है तो कृपया अपडेट करें। नीचे दिए गए कोड का उपयोग मैंने अपने कस्टमफ़िल्टरलिस्ट में श्रेणी को शामिल करते हुए सामने आई त्रुटि को ठीक करने के लिए किया है, इस पैच को लागू करने के कारण मेरे नेविगेशन के अनुसार श्रेणीकरण विकल्प प्रदर्शित नहीं किया गया था बाकी फिल्टर मेरे संग्रह के अनुसार उपयुक्त थे।

namespace Custom\Navigation\Model\Layer\Filter;

/**
 * Layer category filter
 */
class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category
{
     /**
      * @var \Magento\Framework\Escaper
      */
    private $escaper;

    /**
     * @var CategoryDataProvider
     */
    private $dataProvider;

    /**
     * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Catalog\Model\Layer $layer
     * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder
     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
     * @param \Magento\Framework\Escaper $escaper
     * @param CategoryManagerFactory $categoryManager
     * @param array $data
     */
    public function __construct(
        \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\Layer $layer,
        \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder,
        \Magento\Framework\Escaper $escaper,
        \Magento\Catalog\Model\Layer\Filter\DataProvider\CategoryFactory $categoryDataProviderFactory,
        array $data = []
    ) {
        parent::__construct(
            $filterItemFactory,
            $storeManager,
            $layer,
            $itemDataBuilder,
            $escaper,
            $categoryDataProviderFactory,
            $data
        );
        $this->_escaper = $escaper;
        $this->_requestVar = 'cat';
        $this->dataProvider = $categoryDataProviderFactory->create(['layer' => $this->getLayer()]);
    }

    /**
     * Get data array for building category filter items
     *
     * @return array
     */
    protected function _getItemsData()
    {
        /** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
        $productCollection = $this->getLayer()->getProductCollection();

        $optionsFacetedData = '' ;// $productCollection->getFacetedData('category'); (Here i have set $optionsFacetedData as blank so that category option will not be included in layered navigation)
        $category = $this->dataProvider->getCategory();
        $categories = $category->getChildrenCategories();

        $collectionSize = $productCollection->getSize();

        if ($category->getIsActive()) {
            foreach ($categories as $category) {
                if ($category->getIsActive()
                    && isset($optionsFacetedData[$category->getId()])
                    && $this->isOptionReducesResults($optionsFacetedData[$category->getId()]['count'], $collectionSize)
                ) {
                    $this->itemDataBuilder->addItemData(
                        $this->escaper->escapeHtml($category->getName()),
                        $category->getId(),
                        $optionsFacetedData[$category->getId()]['count']
                    );
                }
            }
        }
        return $this->itemDataBuilder->build();
    }
}

5) जब आपका कस्टम पृष्ठ आपके नियंत्रक निष्पादन विधि के अंदर लोड होता है, तो आपको अपनी कस्टम परत सेट करने की आवश्यकता होती है, जिसे हमने श्रेणी और खोज परत के साथ di.xml में जोड़ा है।

 - include the below argument in your controller construct method.

     "\Magento\Catalog\Model\Layer\Resolver $layerResolver",

 - inside execute method set your custom layer resolver for your module.

    $this->layerResolver->create('customlayer');

6) कस्टम पृष्ठ के लिए आपके लेआउट xml फ़ाइल में शरीर अनुभाग में नीचे कोड जोड़ें।

<attribute name="class" value="page-with-filter"/>

<referenceContainer name="sidebar.main">
<!-- below is the virtual type of the core navigation we created -->
    <block class="Custom\Navigation\Block\Navigation\Custnavigation" name="custom.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
        <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" />
        <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/>
    </block>
</referenceContainer>

मैं आपके कोड को Magento 2.1.7 में कस्टम संग्रह के साथ उपयोग कर रहा हूं। लेकिन मुझे खाली पेज मिल रहा है। मुझे लगता है कि ऊपर के कोड में कस्टम \ नेविगेशन \ ब्लॉक \ नेविगेशन \ कस्टर्नवेशन गायब है। क्या आप मुझे पूरा कोड दे सकते हैं?
मागोडेको

नहीं, ऐसा कोई ब्लॉक नहीं है इसके बजाय मैंने एक आभासी प्रकार बनाया था इसके लिए आप di.xml कोड की जांच कर सकते हैं और यहां पोस्ट किया गया कोड पूर्ण कोड ही है।
mp196

ठीक है, क्या आप मुझे पूरे कोड की ज़िप भेज सकते हैं?
मागोडेको

क्षमा करें, ज़िप नहीं भेजा जा सकता क्योंकि उपरोक्त उत्तर कोड हमारे द्वारा विकसित भुगतान एक्सटेंशन का एक छोटा सा हिस्सा था।
mp196

1
जाँच करें कि क्या आपने इसे $ जोड़ा है-> layerResolver = $ layerResolver; फ़ाइल कंस्ट्रक्टर में जोड़े गए वर्ग के लिए आपके निर्माण में। \ Magento \ Catalog \ Model \ Layer \ Resolver $ layerResolver
mp196

2

मैंने श्रेणी पृष्ठ के स्तरित नेविगेशन और टूलबार पर अपने कस्टम उत्पाद संग्रह को सफलतापूर्वक लागू किया।

उदाहरण के लिए, मैं उन उत्पादों का संग्रह ला रहा हूं जिनकी कीमत 100 से कम है।

चरण 1: नीचे कोड स्निपेट जोड़ें

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / etc / di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Catalog\Model\Layer">
        <plugin name="custom_product_model_layer" type="Vendor\Module\Plugin\Layer" />
    </type>

    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="custom_product_toolbar" type="Vendor\Module\Plugin\Toolbar" />
    </type>

    <virtualType name="categoryFilterList" type="Magento\Catalog\Model\Layer\FilterList">
        <arguments>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Attribute</item>
                <item name="price" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Price</item>
                <item name="decimal" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Decimal</item>
                <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

</config>

चरण 2: उत्पाद संग्रह के लिए प्लगइन बनाएं

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / प्लगइन / Layer.php

<?php
namespace Vendor\Module\Plugin;
class Layer
{
  public function aroundGetProductCollection(
    \Magento\Catalog\Model\Layer $subject,
    \Closure $proceed
  ) {

    $result = $proceed();
    $result->addAttributeToFilter('price', array('lt' => 100));
    return $result;
  }
}

चरण 3: टूलबार के लिए प्लगइन बनाएं

एप्लिकेशन / कोड / विक्रेता / मॉड्यूल / प्लगइन / Toolbar.php

<?php
namespace Vendor\Module\Plugin;
class Toolbar
{

  protected $_objectManager;
  protected $request;

  public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    \Magento\Framework\App\Request\Http $request
  ) {
    $this->_objectManager = $objectmanager;
    $this->request = $request;
  }

  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
    \Closure $proceed,
    $request
  ) {
    $result = $proceed($request);

    $this->_collection = $request;
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    if($category)
    {
      $page = $this->request->getParam('p');
      if($page == '')
      {
        $page = 1;
      }
      $this->_collection->getCurPage();
      $this->_collection->setCurPage($page);  
    }
    //else
    //{
    //  $this->_collection->setCurPage($this->getCurrentPage());
    //}

    return $result;
  }

}

नमस्कार, मैंने आपके कोड का उपयोग किया है यह उत्पाद संग्रह Correclty को अपडेट करता है, लेकिन यह श्रेणी, मूल्य, गुण और उनके उत्पाद की गणना जैसे FIlterList को अपडेट नहीं कर रहा है। क्या आप इसके लिए मदद कर सकते हैं, मेरे लिए इसका आग्रह ?? @ दिनेशयादव
सुजीत पंडित

आपके समाधान ने पूरी तरह से काम किया। मैंने कुछ श्रेणियों के लिए कुछ अतिरिक्त घंटियाँ और सीटी जोड़ी हैं और फिर उनके संग्रह को पूरी तरह से फिर से लिखना चाहता हूँ।
पिक्सीमेडिया

@pixiemedia आप मेरे जवाब को आगे बढ़ा सकते हैं अगर यह आपके लिए काम करे ines
दिनेश यादव

मेरे पास पहले से है;) वैसे एक छोटा सा मुद्दा मिला - प्लगइन कोड में, अंतिम भाग के बाद अंतिम भाग खोज परिणामों को तोड़ता है। टिप्पणी करें कि थोड़ा बाहर
पिक्सीमेडिया

M2.2 पर काम करना बंद कर दिया - sql error SQLSTATE [42S22]: कॉलम नहीं मिला: 1054 अज्ञात कॉलम 'e.min_price' में 'फ़ील्ड सूची' - समाधान का काम करना
pixiemedia

0

मैं स्तरित नेविगेशन प्राप्त करने में सक्षम था, जो ज्यादातर कस्टम पेज पर कस्टम उत्पाद संग्रह के लिए काम कर रहा था। मैंने अपने मॉड्यूल के लिए स्रोत कोड यहां अपलोड किया है । केवल समस्याएं यह हैं कि मूल्य फ़िल्टर सही उत्पाद की संख्या प्रदर्शित नहीं करता है। इस वजह से, मैंने मूल्य फ़िल्टर को छिपाने के लिए स्तरित नेविगेशन दृश्य को संशोधित किया। लेकिन क्योंकि मैंने एक कस्टम दृश्य फ़ाइल का उपयोग किया है, किसी कारण से साइडबार में फ़िल्टर अब और ढह नहीं सकते।

यदि कोई भी उस समस्या को ठीक कर सकता है, तो एक अनुरोध करने के लिए स्वतंत्र महसूस करें। मैं यह भी पता लगाने की कोशिश कर रहा हूं कि मैगेंटो 2 बैकएंड के माध्यम से बनाई गई सीएमएस पृष्ठ के लिए इसे कैसे लागू किया जाए, इसके बजाय मैन्युअल रूप से xml के माध्यम से बनाए गए पृष्ठ के लिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.