Điều hướng lớp cho bộ sưu tập tùy chỉnh trên trang tùy chỉnh - magento2


12

Tôi đang làm việc về tìm nạp điều hướng lớp trong magento2 cho một bộ sưu tập sản phẩm tùy chỉnh. Tôi đang nhận được bộ sưu tập tùy chỉnh đã có trên trang tùy chỉnh cần hiển thị điều hướng lớp. Đã thử điều chỉnh giải pháp magento1 này nhưng không thể đi xa được.

Bất kỳ ý tưởng làm thế nào tôi có thể đạt được nó trong magento2. Những gì tôi đã làm cho đến nay là như sau:

Mở rộng khối Danh mục sản phẩm cho danh sách sản phẩm tùy chỉnh trên trang tùy chỉnh của tôi.

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;
     }

}

Đã sử dụng khối Tìm kiếm cốt lõi để điều hướng lớp trong tệp bố cục

<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>

Mô hình lớp lõi mở rộng để sửa đổi bộ sưu tập.

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();
    }

}

Cho đến bây giờ tôi đang nhận được điều hướng lớp được hiển thị nhưng nó không cụ thể cho bộ sưu tập tùy chỉnh của tôi. Theo gỡ lỗi của tôi, bộ sưu tập được lọc tất cả các cách từ danh mục gốc (Bao gồm toàn bộ danh mục sản phẩm) và theo nó là tìm nạp các lớp.


Bất kỳ đề nghị sẽ được nhiều đánh giá cao ..!
mp196

Bạn đã tìm thấy bất kỳ giải pháp cho nó? Nếu vậy, xin vui lòng chia sẻ câu trả lời của bạn
Nalin Savaliya 7/11/2016

Các bạn có ai trong số các bạn có bất kỳ sự dẫn dắt nào về điều này không ??
aton1004

Tôi đã thành công khi nhận được điều hướng lớp trên trang tùy chỉnh cho bộ sưu tập tùy chỉnh của mình ... Sẽ cần một chút thời gian để đăng giải pháp ở đây vì nó rất dài (Có lẽ trong một hoặc hai ngày tôi sẽ đăng giải pháp)
mp196

Câu trả lời:


3

Tôi đã có thể đạt được điều hướng với các thay đổi bên dưới, tôi có thể không hoàn toàn chính xác với giải pháp này để nhận xét và đề xuất được chào đón nhất.

1) Chuẩn bị di.xml cho phần frontend như dưới đây:

<!-- 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) Tệp lớp mô hình: Mở rộng tệp lớp mô hình với mô hình tùy chỉnh của bạn và sửa đổi bộ sưu tập.

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) Tôi đã mở rộng các tệp bên dưới như được sử dụng trong di.xml (Đã giữ tệp bằng cách mở rộng chưa khởi tạo phương thức xây dựng vì tôi không yêu cầu bất kỳ thay đổi nào trong các tệp này nếu cần, bạn có thể sửa đổi chức năng cụ thể trong tệp mở rộng theo đó), hiện tại giải pháp tôi đã áp dụng không thể giải quyết vấn đề bộ lọc danh mục, nó vẫn bao gồm các bộ lọc danh mục gốc, do đó phải thực hiện một cách giải quyết để bao gồm các khía cạnh (cách giải quyết được đề cập ở điểm thứ 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) Phải thực hiện một cách giải quyết cho bộ lọc danh mục trong điều hướng lớp vì nó không hiển thị tùy chọn đối với bộ sưu tập được lọc, Nếu có ai tìm thấy giải pháp, vui lòng cập nhật. Dưới đây là mã tôi đã sử dụng để sửa lỗi facetdata gặp phải trong khi bao gồm danh mục trong danh sách tùy chỉnh của mình, do áp dụng bản vá này, tùy chọn danh mục không được hiển thị trong phần còn lại của bộ lọc điều chỉnh phù hợp theo bộ sưu tập của tôi.

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) Khi trang tùy chỉnh của bạn được tải bên trong phương thức thực thi bộ điều khiển của bạn, bạn cần đặt lớp tùy chỉnh mà chúng tôi đã thêm trong di.xml cùng với thể loại và lớp tìm kiếm.

 - 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) Trong tệp xml bố cục của bạn cho trang tùy chỉnh, thêm mã bên dưới vào phần thân.

<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>

Tôi đang sử dụng mã của bạn với bộ sưu tập tùy chỉnh trong magento 2.1.7. nhưng tôi đang nhận được trang trống. Tôi nghĩ Custom \ Navigation \ Block \ Navigation \ Custnavulation bị thiếu trong các mã trên. Bạn có thể vui lòng cho tôi mã đầy đủ?
Mã hóa

không, không có khối nào như vậy thay vào đó tôi đã tạo một loại ảo cho nó, bạn có thể kiểm tra mã di.xml và mã được đăng ở đây là mã đầy đủ.
mp196

Ok bạn có thể vui lòng gửi cho tôi zip của toàn bộ mã?
Magecode

Xin lỗi không thể gửi zip vì mã trả lời ở trên chỉ là một phần nhỏ của tiện ích mở rộng phải trả tiền mà chúng tôi đã phát triển.
mp196

1
kiểm tra xem bạn đã thêm $ this-> layerResolver = $ layerResolver; trong cấu trúc của bạn cho lớp được thêm vào trong hàm tạo tệp. \ Magento \ Catalog \ Model \ Layer \ Resolver $ layerResolver
mp196

2

Tôi đã áp dụng thành công bộ sưu tập sản phẩm tùy chỉnh của mình trên thanh điều hướng và thanh công cụ xếp lớp của trang danh mục.

Ví dụ: tôi đang tìm nạp bộ sưu tập những sản phẩm có giá dưới 100.

Bước 1: Thêm đoạn mã dưới đây

ứng dụng / mã / Nhà cung cấp / Mô-đun / 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>

Bước 2: Tạo plugin cho bộ sưu tập sản phẩm

ứng dụng / mã / Nhà cung cấp / Mô-đun / Plugin / 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;
  }
}

Bước 3: Tạo plugin cho thanh công cụ

ứng dụng / mã / Nhà cung cấp / Mô-đun / Plugin / Thanh công cụ.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;
  }

}

Xin chào, tôi đã sử dụng Mã của bạn Nó cập nhật Bộ sưu tập sản phẩm Correclty Nhưng nó không cập nhật FIlterList như Danh mục, Giá cả, Thuộc tính và Số lượng sản phẩm của họ. Bạn có thể giúp cho việc này, nó khẩn cấp cho tôi ?? @DineshYadav
Sujeet Pandit

giải pháp của bạn đã làm việc hoàn hảo. Tôi đã thêm một số chuông và còi để nghe cho một số loại nhất định và sau đó viết lại hoàn toàn bộ sưu tập của họ.
pixiemedia

@pixiemedia Bạn có thể nêu lên câu trả lời của tôi nếu nó hiệu quả với bạn ☺️
Dinesh Yadav

tôi đã có;) đã tìm thấy một vấn đề nhỏ bằng cách này - trong mã plugin, phần cuối cùng sau khi phần cuối cùng phá vỡ kết quả tìm kiếm. bình luận rằng bit out
pixiemedia

đã ngừng hoạt động trên M2.2 - lỗi sql SQLSTATE [42S22]: Không tìm thấy cột: 1054 Cột không xác định 'e.min_price' trong 'danh sách trường' - thực hiện giải pháp
pixiemedia

0

Tôi đã có thể nhận được điều hướng lớp chủ yếu làm việc cho một bộ sưu tập sản phẩm tùy chỉnh trên một trang tùy chỉnh. Tôi đã tải lên mã nguồn cho mô-đun của mình ở đây . Vấn đề duy nhất là bộ lọc Giá không hiển thị số lượng sản phẩm chính xác. Vì điều này, tôi đã sửa đổi chế độ xem điều hướng lớp để ẩn bộ lọc Giá. Nhưng vì tôi đã sử dụng tệp xem tùy chỉnh, vì một số lý do, các bộ lọc trong thanh bên không thể bị thu gọn nữa.

Nếu bất cứ ai có thể khắc phục vấn đề đó, vui lòng thực hiện yêu cầu kéo. Tôi cũng đang cố gắng tìm ra cách triển khai điều này cho một trang CMS được tạo thông qua phụ trợ Magento 2, thay vì cho một trang được tạo thủ công thông qua xml.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.