M2.3 - How to set Catalog -> Categories -> Content -> Description cms block based on shop by attributes selection programmatically?

magento.stackexchange https://magento.stackexchange.com/questions/330282

Question

I want to set the category description cms block based on the shop by attributes selection on product listing page,

enter image description here

Was it helpful?

Solution

Vendor/Module/view/frontend/layout/catalog_category_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">
    <body>
        <referenceBlock name="category.description">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Vendor_Module::catalog/category/description.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

Vendor/Module/view/frontend/templates/catalog/category/description.phtml

<?php
$blockObj= $block->getLayout()->createBlock('Vendor\Module\Block\ActiveFilter');
$filterLabel = 'my_'.$blockObj->getActiveFilter();
echo $this->getLayout()
    ->createBlock('Magento\Cms\Block\Block')
    ->setBlockId($filterLabel)
    ->toHtml();
?>

Vendor/Module/Block/ActiveFilter.php

<?php

namespace Vender\Module\Block;

use Magento\Catalog\Model\Layer\Resolver;
use Magento\Framework\View\Element\Template;

/**
 * Class ActiveFilter
 * @package Vendor\Module\Block
 */
class ActiveFilter extends Template
{
    /**
     * @var Resolver
     */
    protected $layerResolver;

    /**
     * ActiveFilter constructor.
     * @param Resolver $layerResolver
     * @param Template\Context $context
     * @param array $data
     */
    public function __construct(
        Resolver $layerResolver,
        Template\Context $context,
        array $data = []
    ) {
        $this->layerResolver = $layerResolver;
        parent::__construct($context, $data);
    }

    public function getActiveFilter()
    {
        $layer = $this->layerResolver->get();
        $activeFilters = $layer->getState()->getFilters();
        $filterLabel = "";
        foreach ($activeFilters as $filter) {
            $filterLabel = $filter->getLabel();
            $filterValue = $filter->getValue();
        }
        return $filterLabel;
    }
}

And Also remove catalog_product_collection_load_after event..

OTHER TIPS

Assume that your block class name for this description section is Magento\Catalog\Block\Category\View and name in Layout is category.description,

Create a View model class that checks the current page has filters

View Model Class

<?php

namespace StackExchange\MagentoModule\ViewModel;

use Magento\Framework\View\Element\Block\ArgumentInterface;

class CategoryDescription implements ArgumentInterface
{
    /**
     * @var \Magento\Catalog\Model\Layer\Resolver
     */
    private $layerResolver;
    /**
     * @var \Magento\Framework\App\Request\Http
     */
    private $request;

    public function __construct(
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Framework\App\Request\Http $request
    ) {
        $this->layerResolver = $layerResolver;
        $this->request = $request;
    }
    public function  hasFilterList()
    {
        $listOfFilter = [];
        $filters = $this->layerResolver->get()->getState()->getFilters();
        if (!is_array($filters)) {
            $filters = [];
        }

        foreach ($filters as $item) {
            $listOfFilter[$item->getFilter()->getRequestVar()] =
            $this->request->getQueryValue($item->getFilter()->getRequestVar());
        }
        return $listOfFilter;
    }
}

Called view model class for catalog_category_view_type_layered.xml

Create catalog_category_view_type_layered.xml or add the below code at catalog_category_view_type_layered.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>
        <referenceBlock name="category.description" template="StackExchange_MagentoModule::category/description.phtml">
            <arguments>
                <argument name="description_view" xsi:type="object">StackExchange\MagentoModule\ViewModel\CategoryDescription</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

That would be outside of the existing Magento functionality.

You could write a few generic descriptions that could apply to which ever attribute. Something like "Here at StackOverflow we love coders that use %1" and then have a knockout observer listening to the filter selection (you'd need to look into the filtering js to know what that is handled by)

That way you could append to the standard category description and be like <my_description> + renderSelectedAttributeMessage().

My point being you would have to roll your own solution for this as far as I'm aware.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top