I have created an Extension to show a button named Shop By Collection on product page based on the condition that shop_by_collection dropdown attribute option is assigned to product. This part is working fien and I can get a button with link and attribue code option id in the url. After clicking the button I am redirected to a new custom collection page where I am showing all relevent products this is working fine but toolbar and layered navigation is not showing.
Here is my complete code, plz guide me what is the issue.
Block/ProductList.php
<?php /** * Mica ShopByCollection Product List Block */ namespace Mica\ShopByCollection\Block\Collection; use Magento\Catalog\Block\Product\ListProduct; use Magento\Catalog\Block\Product\Context; use Magento\Catalog\Model\Layer\Resolver; use Magento\Framework\Data\Helper\PostHelper; use Magento\Framework\Url\Helper\Data; use Magento\Framework\App\RequestInterface; use Magento\Framework\Registry; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Catalog\Api\CategoryRepositoryInterface; class ProductList extends ListProduct { /** * @var RequestInterface */ protected $request; /** * @var Registry */ protected $registry; /** * @var CollectionFactory */ protected $productCollectionFactory; /** * @param Context $context * @param PostHelper $postDataHelper * @param Resolver $layerResolver * @param CategoryRepositoryInterface $categoryRepository * @param RequestInterface $request * @param Registry $registry * @param CollectionFactory $productCollectionFactory * @param Data $urlHelper * @param array $data */ public function __construct( Context $context, PostHelper $postDataHelper, Resolver $layerResolver, CategoryRepositoryInterface $categoryRepository, RequestInterface $request, Registry $registry, CollectionFactory $productCollectionFactory, Data $urlHelper, array $data = [] ) { $this->request = $request; $this->registry = $registry; $this->productCollectionFactory = $productCollectionFactory; parent::__construct( $context, $postDataHelper, $layerResolver, $categoryRepository, $urlHelper, $data ); } /** * Get loaded product collection * * @return \Magento\Catalog\Model\ResourceModel\Product\Collection */ protected function _getProductCollection() { if ($this->_productCollection === null) { // Try to get collection from layer first $layer = $this->getLayer(); if ($layer) { $this->_productCollection = $layer->getProductCollection(); } // If layer collection is empty, create our own if ($this->_productCollection === null || $this->_productCollection->count() === 0) { $this->_productCollection = $this->productCollectionFactory->create(); $this->_productCollection->addAttributeToSelect('*'); $this->_productCollection->addMinimalPrice(); $this->_productCollection->addFinalPrice(); $this->_productCollection->addTaxPercents(); $this->_productCollection->addUrlRewrite(); $this->_productCollection->addStoreFilter(); } // Apply shop_by_collection filter $attributeValue = $this->request->getParam('attribute_value'); if ($attributeValue) { // Add the filter directly to the collection $this->_productCollection->addAttributeToFilter('shop_by_collection', $attributeValue); } // Filter out configurable child products // This joins the collection with the super link table and excludes any // products that are children of configurable products $this->_productCollection->getSelect()->joinLeft( ['super_link' => $this->_productCollection->getTable('catalog_product_super_link')], 'e.entity_id = super_link.product_id', [] )->where('super_link.product_id IS NULL'); } return $this->_productCollection; } } Block/CollectionButton.php
<?php /** * Mica ShopByCollection Button Block */ namespace Mica\ShopByCollection\Block\Product; use Magento\Catalog\Model\Product; use Magento\Framework\Registry; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Element\Template\Context; class CollectionButton extends Template { /** * @var Registry */ private $registry; /** * @param Context $context * @param Registry $registry * @param array $data */ public function __construct( Context $context, Registry $registry, array $data = [] ) { $this->registry = $registry; parent::__construct($context, $data); } /** * Get current product * * @return Product|null */ public function getProduct() { return $this->registry->registry('current_product'); } /** * Check if product has collection attribute * * @return bool */ public function hasCollection() { $product = $this->getProduct(); if ($product && $product->getData('shop_by_collection')) { return true; } return false; } /** * Get collection attribute value * * @return string */ public function getCollectionValue() { $product = $this->getProduct(); if ($product) { $attributeValue = $product->getAttributeText('shop_by_collection'); if ($attributeValue) { return $attributeValue; } return $product->getData('shop_by_collection'); } return ''; } /** * Get collection URL * * @return string */ public function getCollectionUrl() { $product = $this->getProduct(); if ($product) { // Log the attribute value for debugging $this->_logger->debug('Collection attribute value: ' . $product->getData('shop_by_collection')); return $this->getUrl('collection/collection/view', [ 'attribute_value' => $product->getData('shop_by_collection') ]); } return '#'; } /** * Get collection attribute options for debugging * * @return array */ public function getAttributeOptions() { $options = []; $product = $this->getProduct(); if ($product) { $attribute = $product->getResource()->getAttribute('shop_by_collection'); if ($attribute) { foreach ($attribute->getOptions() as $option) { $options[$option->getValue()] = $option->getLabel(); } } } return $options; } } Controller/Collection/View.php
<?php /** * Mica ShopByCollection Collection View Controller */ namespace Mica\ShopByCollection\Controller\Collection; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\App\RequestInterface; use Magento\Framework\View\Result\PageFactory; use Magento\Framework\Registry; use Magento\Catalog\Model\Layer\Resolver; class View extends Action { /** * @var PageFactory */ protected $resultPageFactory; /** * @var Registry */ protected $registry; /** * @var Resolver */ protected $layerResolver; /** * @param Context $context * @param PageFactory $resultPageFactory * @param Registry $registry * @param Resolver $layerResolver */ public function __construct( Context $context, PageFactory $resultPageFactory, Registry $registry, Resolver $layerResolver ) { $this->resultPageFactory = $resultPageFactory; $this->registry = $registry; $this->layerResolver = $layerResolver; parent::__construct($context); } /** * Collection view action * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { // FIXED: Use a valid layer type - 'search' is always available $this->layerResolver->create('search'); $resultPage = $this->resultPageFactory->create(); $attributeValue = $this->getRequest()->getParam('attribute_value'); // Register attribute value for use in blocks if ($attributeValue) { $this->registry->register('current_collection_attribute_value', $attributeValue); $attributeText = $this->getAttributeText($attributeValue); $resultPage->getConfig()->getTitle()->set(__('Products in %1 Collection', $attributeText)); } else { $resultPage->getConfig()->getTitle()->set(__('Collection')); } return $resultPage; } /** * Get attribute text value * * @param string $attributeValue * @return string */ private function getAttributeText($attributeValue) { // Get attribute text from option value $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $attributeRepository = $objectManager->get(\Magento\Eav\Api\AttributeRepositoryInterface::class); try { $attribute = $attributeRepository->get('catalog_product', 'shop_by_collection'); foreach ($attribute->getOptions() as $option) { if ($option->getValue() == $attributeValue) { return $option->getLabel(); } } } catch (\Exception $e) { return $attributeValue; } return $attributeValue; } } etc/frontend/routes.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="standard"> <route id="mica_collection" frontName="collection"> <module name="Mica_ShopByCollection" /> </route> </router> </config> 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\Search\FilterableAttributeList"> <plugin name="mica_collection_filter_search" type="Mica\ShopByCollection\Plugin\Layer\CollectionFilterList" /> </type> <type name="Magento\Catalog\Model\Layer\Category\FilterableAttributeList"> <plugin name="mica_collection_filter_category" type="Mica\ShopByCollection\Plugin\Layer\CollectionFilterList" /> </type> </config> Model/CollectionProducts.php
<?php /** * Mica ShopByCollection Collection Products Model */ namespace Mica\ShopByCollection\Model; use Magento\Catalog\Model\ResourceModel\Product\Collection; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Framework\App\RequestInterface; class CollectionProducts { /** * @var CollectionFactory */ protected $collectionFactory; /** * @var RequestInterface */ protected $request; /** * @param CollectionFactory $collectionFactory * @param RequestInterface $request */ public function __construct( CollectionFactory $collectionFactory, RequestInterface $request ) { $this->collectionFactory = $collectionFactory; $this->request = $request; } /** * Get product collection filtered by attribute value * * @return Collection */ public function getFilteredCollection() { $collection = $this->collectionFactory->create(); $collection->addAttributeToSelect('*'); $attributeValue = $this->request->getParam('attribute_value'); if ($attributeValue) { $collection->addAttributeToFilter('shop_by_collection', $attributeValue); } return $collection; } } view/frontend/layout/mica_collection_collection_view.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="catalog_category_view_type_layered"/> <body> <referenceContainer name="content"> <!-- Product listing --> <block class="Mica\ShopByCollection\Block\Collection\ProductList" name="collection.products" template="Magento_Catalog::product/list.phtml" cacheable="false"> <container name="category.product.list.additional" as="additional" /> <block class="Magento\Framework\View\Element\RendererList" name="category.product.type.details.renderers" as="details.renderers"> <block class="Magento\Framework\View\Element\Template" name="default" as="default"/> </block> <block class="Magento\Catalog\Block\Product\ProductList\Toolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml"> <block class="Magento\Theme\Block\Html\Pager" name="product_list_toolbar_pager"/> </block> <action method="setToolbarBlockName"> <argument name="name" xsi:type="string">product_list_toolbar</argument> </action> </block> </referenceContainer> <referenceContainer name="sidebar.main"> <block class="Magento\LayeredNavigation\Block\Navigation\Category" name="catalog.leftnav" 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> <referenceContainer name="head.additional"> <block class="Magento\Framework\View\Element\Template" name="mica.shopbycollection.custom.css" template="Mica_ShopByCollection::custom-styles.phtml"/> </referenceContainer> </body> </page> view/frontend/layout/catalog_product_view.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="product.info.price"> <block class="Mica\ShopByCollection\Block\Product\CollectionButton" name="product.info.collection.button" template="Mica_ShopByCollection::product/collection_button.phtml" after="-" /> </referenceContainer> </body> </page> view/frontend/templates/collection_button.phtml
<?php /** * @var $block \Mica\ShopByCollection\Block\Product\CollectionButton */ ?> <?php if ($block->hasCollection()): ?> <div class="collection-button-container"> <a href="<?= $block->escapeUrl($block->getCollectionUrl()) ?>" class="action primary collection-button" title="<?= $block->escapeHtml(__('Shop by %1 Collection', $block->getCollectionValue())) ?>"> <span><?= $block->escapeHtml(__('Shop by %1 Collection', $block->getCollectionValue())) ?></span> </a> </div>