5

How can I remove Category Filter from Magento 2 Product List Page.

  • magento\vendor\magento\module-layered-navigation\view\frontend\layout\catalog_category_view_type_layered.xml & magento\vendor\magento\module-layered-navigation\view\frontend\templates\layer\view.phtml – Ankit Shah Dec 13 '16 at 7:00
10

You have to override core file into your theme, Category layered navigation comes form core file,

vendor/magento/module-layered-navigation/view/frontend/templates/layer/view.phtml

You have to get files from core and keep in your theme,

app/design/frontend/{Vendor}}/{themename}}/Magento_LayeredNavigation/templates/layer/view.phtml

Now you can set condition for this,

<?php  if($filter->getName() != __('Category')) { } ?>

in code.

<?php

/**
 * Category layered navigation
 *
 * @var $block \Magento\LayeredNavigation\Block\Navigation
 */
?>
<?php if ($block->canShowBlock()): ?>
    <div class="block filter">
        <div class="block-title filter-title">
            <strong><?php /* @escapeNotVerified */ echo __('Shop By') ?></strong>
        </div>

        <div class="block-content filter-content">
            <?php echo $block->getChildHtml('state') ?>

            <?php if ($block->getLayer()->getState()->getFilters()): ?>
                <div class="block-actions filter-actions">
                    <a href="<?php /* @escapeNotVerified */ echo $block->getClearUrl() ?>" class="action clear filter-clear"><span><?php /* @escapeNotVerified */ echo __('Clear All') ?></span></a>
                </div>
            <?php endif; ?>
            <?php $wrapOptions = false; ?>
            <?php foreach ($block->getFilters() as $filter): ?>
                <?php if (!$wrapOptions): ?>
                    <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?php /* @escapeNotVerified */ echo __('Shopping Options') ?></strong>
                    <dl class="filter-options" id="narrow-by-list">
                <?php $wrapOptions = true; endif; ?>
                <?php  if($filter->getName() != __('Category')) { ?>
                    <?php if ($filter->getItemsCount()): ?>
                        <dt role="heading" aria-level="3" class="filter-options-title"><?php echo $block->escapeHtml(__($filter->getName())) ?></dt>
                        <dd class="filter-options-content"><?php /* @escapeNotVerified */ echo $block->getChildBlock('renderer')->render($filter); ?></dd>
                    <?php endif; ?>
                    <?php } ?>
            <?php endforeach; ?>
            <?php if ($wrapOptions): ?>
                </dl>
            <?php endif; ?>
        </div>
    </div>
<?php endif; ?>
  • 2
    The IF clause should actually be $filter->getName() != 'Category' since translating the string with _ would cause the filter to appear in other languages. – DreamWave Jan 25 '18 at 10:18
  • hi@Rakesh, this removes the category filter totally from layered navigation? if mannually we enter url will it work? – jafar pinjar Jan 3 at 7:50
5

Better to use as:

<?php  if($filter->getRequestVar() != 'cat') { 
// ...
} 
?>
  • This should be the accepted answer – PY Yick Jun 7 '18 at 7:41
0

magento\vendor\magento\module-layered-navigation\view\frontend\layout\catalog_category_view_type_layered.xml orverride file

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <attribute name="class" value="page-with-filter"/>
        <referenceContainer name="sidebar.main">
            <block class="Magento\LayeredNavigation\Block\Navigation\Category" name="catalog.leftnav" before="-" template="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="layer/filter.phtml"/>
            </block>
        </referenceContainer>
    </body>
</page>

Remove Block

  • Hi @Ankit Shah, Actually We need filters only I need to exclude category (dropdown) filters.All other Attribute Filters Need.Category Is not attribute na to exclude that from filters.So How we exclude only that category filter. – shankar boss Dec 13 '16 at 7:04
  • What have u tried so far? – Ankit Shah Dec 13 '16 at 7:06
  • I tried searching that category rendering phtml but all are coming in single array.So Just now find that model file to stop rendering that filters. – shankar boss Dec 13 '16 at 7:09
  • 2
    "magento\vendor\magento\module-catalog\Model\Layer\FilterList.php" This file we need to override and comment the 70,71,72 lines in our local file – shankar boss Dec 13 '16 at 7:19
  • 1
    Yes, Without touching model file we can stop it in phtml itself as our friend @Rakesh told :) – shankar boss Dec 13 '16 at 7:29
0

Sadly the fix from Rakesh is not working for me. The filter is not collapsible anymore. How can we still remove the categorie filter in our code? On default we have the filters collapsible.

<?php if ($block->canShowBlock()): ?>
<div class="block filter" id="layered-filter-block" data-mage-init='{"collapsible":{"openedState": "active", "collapsible": true, "active": false, "collateral": { "openedState": "filter-active", "element": "body" } }}'>
    <?php $filtered = count($block->getLayer()->getState()->getFilters()) ?>
    <div class="block-title filter-title" data-count="<?= /* @escapeNotVerified */ $filtered ?>">
        <strong data-role="title"><?= /* @escapeNotVerified */ __('Shop By') ?></strong>
    </div>
    <div class="block-content filter-content">
        <?= $block->getChildHtml('state') ?>

        <?php if ($block->getLayer()->getState()->getFilters()): ?>
            <div class="block-actions filter-actions">
                <a href="<?= /* @escapeNotVerified */ $block->getClearUrl() ?>" class="action clear filter-clear"><span><?= /* @escapeNotVerified */ __('Clear All') ?></span></a>
            </div>
        <?php endif; ?>
        <?php $wrapOptions = false; ?>
        <?php foreach ($block->getFilters() as $filter): ?>
            <?php if ($filter->getItemsCount()): ?>
                <?php if (!$wrapOptions): ?>
                    <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?= /* @escapeNotVerified */ __('Shopping Options') ?></strong>
                    <?php $range = implode(' ', range(0, $filter->getItemsCount())); ?>
                    <div class="filter-options" id="narrow-by-list" data-role="content" data-mage-init='{"accordion":{"openedState": "active", "collapsible": true, "active": "<?php echo $range; ?>", "multipleCollapsible": true}}'>
                <?php  $wrapOptions = true; endif; ?>
                <?php  if($filter->getName() != __('Category')) { } ?>
                <div data-role="collapsible" class="filter-options-item">
                    <div data-role="title" class="filter-options-title"><?= /* @escapeNotVerified */ __($filter->getName()) ?></div>
                    <div data-role="content" class="filter-options-content"><?= /* @escapeNotVerified */ $block->getChildBlock('renderer')->render($filter) ?></div>
                </div>
            <?php endif; ?>
        <?php endforeach; ?>
        <?php if ($wrapOptions): ?>
            </div>
        <?php else: ?>
            <script>
                require([
                    'jquery'
                ], function ($) {
                    $('#layered-filter-block').addClass('filter-no-options');
                });
            </script>
        <?php endif; ?>
    </div>
</div>
0

Since this is the top result in Google for my search "magento 2 remove category filter from layered navigation", and all the answers suggest entirely replacing a template file (which is subject to Theme-level discrepancies) I thought I'd provide an answer that does not involve a .phtml template replacement.

The Category filter can be removed from Layered Navigation "Shopping Options" list by using a Plugin.

In your module's etc/di.xml file, define the plugin and class DI properties:

    <type name="Magento\Catalog\Model\Layer\FilterList">
        <plugin name="remove_layered_nav_category_filter" type="Vendor\Module\Plugin\Catalog\Model\Layer\FilterList" sortOrder="1" disabled="false" />
    </type>

    <type name="Vendor\Module\Plugin\Catalog\Model\Layer\FilterList">
        <arguments>
            <argument name="categoryFilters" xsi:type="array">
                <item name="catalogsearch_category" xsi:type="string">Magento\CatalogSearch\Model\Layer\Filter\Category</item>
                <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </type>

And declare the Plugin class:

namespace Vendor\Module\Plugin\Catalog\Model\Layer;


class FilterList
{
    const CATALOG_CATEGORY_FILTER = 'category';
    const CATALOG_SEARCH_CATEGORY_FILTER = 'catalogsearch_category';

    /**
     * @var array
     */
    protected $categoryFilterTypes = [
        self::CATALOG_SEARCH_CATEGORY_FILTER => \Magento\CatalogSearch\Model\Layer\Filter\Category::class,
        self::CATALOG_CATEGORY_FILTER        => \Magento\Catalog\Model\Layer\Filter\Category::class
    ];

    /**
     * FilterList constructor.
     *
     * @param array $categoryFilters
     */
    public function __construct(array $categoryFilters)
    {
        $this->categoryFilterTypes = array_merge($this->categoryFilterTypes, $categoryFilters);
    }


    /**
     * Remove Category Filter from FilterList
     *
     * @param \Magento\Catalog\Model\Layer\FilterList $subject
     * @param                                         $result
     * @param \Magento\Catalog\Model\Layer            $layer
     * @return array
     */
    public function afterGetFilters(
        \Magento\Catalog\Model\Layer\FilterList $subject,
        $result,
        \Magento\Catalog\Model\Layer $layer
    ) {
        foreach ($result as $idx => $filter) {
            if ($this->isCategoryFilter($filter)) {
                unset($result[$idx]);
                break;
            }
        }

        return array_values($result);
    }

    /**
     * Determine if given Filter is one of the declared Category Filter types
     *
     * @param $filter
     * @return bool
     */
    private function isCategoryFilter($filter)
    {
        return \in_array(get_class($filter), $this->categoryFilterTypes);
    }
}

This leaves other Filters (e.g., Attribute, Price, Decimal) in place while removing any of the possible Category filters. Should additional Category filters be introduced, a simple change to DI configuration is all that is necessary to extend the functionality.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.