4

Is it a way to hide an attribute in Layering Navigation for a specified category? I have a category which join products with different attribute sets. In this case layering navigation becomes very long as content. I would like to hide some attributes especially in that category, not in others.

Is there an extension or code to allow me using custom layout xml for that category to exclude some attributes?

2
  • Do you have using default magento Layering Navigation or use any 3-rd party module
    – Amit Bera
    Feb 17, 2016 at 13:03
  • Just Magento Layering Navigation.
    – ADDISON74
    Feb 17, 2016 at 13:17

4 Answers 4

1

In my opinion the best flexible way is using "Custom Layout Update" feature in a category the place where you can set some layout tags to hide one or more filters. It is like hiding Categories block in Layering Navigation when you search for something using local.xml (method unsetChild). – ADDISON74

We required this too and we use a very similiar solution as zhartaunik has suggested ...

You have to modifiy/rewrite Mage_Catalog_Block_Layer_View and

Add:

/**
 * Get all excluded attributes of current category
 *
 * @return array
 */
protected function _getExcludedAttributes()
{
    if (!is_array($this->getData('_excluded_attributes')))  {
        $attributes = array_map('trim', explode(',', $this->getData('_excluded_attributes')));
        $this->setData('_excluded_attributes', $attributes);
    }
    return $this->getData('_excluded_attributes');
}

And change

public function getFilters()
{
    $filters = array();
    if ($categoryFilter = $this->_getCategoryFilter()) {
        $filters[] = $categoryFilter;
    }

    $filterableAttributes = $this->_getFilterableAttributes();
    $excludedAttributes   = $this->_getExcludedAttributes(); # added
    foreach ($filterableAttributes as $attribute) {
        if (!in_array($attribute->getAttributeCode(), $excludedAttributes)) { # added
            $filters[] = $this->getChild($attribute->getAttributeCode() . '_filter');
        }
    }

    return $filters;
}

Now you can go to local.xml or "Custom Layout Update" and add this:

<reference name="catalog.leftnav">
    <action method="setData">
        <type>_excluded_attributes</type>
        <code>price,manufacturer</code>
    </action>
</reference>
1
  • This is an elegant solution. I will test it for sure.
    – ADDISON74
    Jul 23, 2017 at 9:17
3

Create an array for your category id and attribute title like below

$category = array('Your Category Id' => array('Price','Your attribute title'));

File: app/design/frontend/Your-Package/Your-Theme/template/catalog/layer/view.phtml edit code at line 48

<?php $currentCategory = Mage::registry('current_category')->getId(); ?>
     <?php foreach ($_filters as $_filter): ?>
            <?php if($_filter->getItemsCount()): ?>
               <?php if(in_array($_filter->getName(),$category[$currentCategory])){
                      continue; 
                 } ?> 
                <dt><?php echo $this->__($_filter->getName()) ?></dt>
                <dd><?php echo $_filter->getHtml() ?></dd>
            <?php endif; ?>
     <?php endforeach; ?>

EDIT You can check is it serchpage using below condition

if (Mage::app()->getFrontController()->getAction()->getFullActionName() == 'catalogsearch_result_index') {
    // The current page is the search page
}
3
  • This is a quick approach. I appreciate for your idea.
    – ADDISON74
    Feb 18, 2016 at 17:40
  • I am using this code pretty well. I came back here to let you know it should be a small change for Search page. This page has layering navigation. Method getId() is not available in a search result page. You have to evaluate if the currentCategory is not a search result. It can be achieved easy.
    – ADDISON74
    Nov 30, 2016 at 10:18
  • @ADDISON74 updated answer with serch page track Nov 30, 2016 at 10:31
0

I researched your task and do not recommend you to do that.

The better way will be duplicate attribute set and assign it on products of your new category

If you still want to implement it, here is what I have found:

In my opinion your task doesn't have any clear solution, so I can recommend solution which is not very pretty look...

All filters are added via method setChild. It means that it doesn't work with layout updates like <remove ... or <unsetChild ...

So we need to modify core files (you can do it via rewrite or smth like that...)

I'l give you an example of modified methods, so you can try to apply it on demo host...

Mage_Catalog_Block_Layer_View

protected function _prepareLayout()
{
    $stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
        ->setLayer($this->getLayer());

    $categoryBlock = $this->getLayout()->createBlock($this->_categoryBlockName)
        ->setLayer($this->getLayer())
        ->init();

    $this->setChild('layer_state', $stateBlock);
    $this->setChild('category_filter', $categoryBlock);

    $filterableAttributes = $this->_getFilterableAttributes();
    foreach ($filterableAttributes as $attribute) {
        if (
            Mage::registry('current_category')->getId() == 19
            && in_array($attribute->getAttributeCode(), array('style'))
        ) {
            continue;
        }

        if ($attribute->getAttributeCode() == 'price') {
            $filterBlockName = $this->_priceFilterBlockName;
        } elseif ($attribute->getBackendType() == 'decimal') {
            $filterBlockName = $this->_decimalFilterBlockName;
        } else {
            $filterBlockName = $this->_attributeFilterBlockName;
        }



        $this->setChild($attribute->getAttributeCode() . '_filter',
            $this->getLayout()->createBlock($filterBlockName)
                ->setLayer($this->getLayer())
                ->setAttributeModel($attribute)
                ->init());
    }

    $this->getLayer()->apply();

    return parent::_prepareLayout();
}

and

public function getFilters()
{
    $filters = array();
    if ($categoryFilter = $this->_getCategoryFilter()) {
        $filters[] = $categoryFilter;
    }

    $filterableAttributes = $this->_getFilterableAttributes();
    foreach ($filterableAttributes as $attribute) {
        $filters[] = $this->getChild($attribute->getAttributeCode() . '_filter');
    }

    foreach ($filters as $filter) {
        if ($filter !== false) {
            $result[] = $filter;
        }

    }

    return $result;
}




In first method I added this:

        if (
            Mage::registry('current_category')->getId() == 19
            && in_array($attribute->getAttributeCode(), array('style'))
        ) {
            continue;
        }

(modify here your category id and array of attribute codes)

In 2nd method I modify this:

    foreach ($filters as $filter) {
        if ($filter !== false) {
            $result[] = $filter;
        }

    }

    return $result;

In first file we just skip block creation for all these filters (there were some issues with swatch blocks, and probably you may face with some issues is you have customized layered) and in the 2nd method magento get all filterable attributes. And we need to exclude again our attribute from filter list

2
  • It seems there is an extension for getting this working: manadev.com/blog/hiding-or-showing-filters-in-categories. I will check it more in detail.
    – ADDISON74
    Feb 18, 2016 at 17:42
  • In my opinion the best flexible way is using "Custom Layout Update" feature in a category the place where you can set some layout tags to hide one or more filters. It is like hiding Categories block in Layering Navigation when you search for something using local.xml (method unsetChild).
    – ADDISON74
    Sep 7, 2016 at 17:12
0

FINAL SOLUTION

Based on the answers from @Prashant Valanda, here is the final solution for this post. It solves the issue with search results page too.

Just enter your category ID and attribute title in $filterCategory array (e.g. $filterCategory['Category_ID'] = array ('Attribute Title to Remove'). In my example filter named Price will not shown in category 63 list page.

<?php
/**
 * Category layered navigation
 *
 * @see Mage_Catalog_Block_Layer_View
 */
?>
<?php $pageIdentifier = Mage::app()->getFrontController()->getAction()->getFullActionName() ?>
<?php if ($pageIdentifier!='catalogsearch_result_index'): ?>
    <?php $currentCategory = Mage::registry('current_category')->getId() ?>
    <?php $filterCategory['63'] = array('Price') ?>
    <?php $filterCategory['89'] = array('Manufacturer') ?>
<?php endif; ?>
<?php if($this->canShowBlock()): ?>
<div class="block block-layered-nav">
    <div class="block-title">
         <strong><span><?php echo $this->__('Shop By') ?></span></strong>
    </div>
    <div class="block-content">
    <?php echo $this->getStateHtml() ?>
    <?php if ($this->getLayer()->getState()->getFilters()): ?>
        <div class="actions"><a href="<?php echo $this->getClearUrl() ?>"><?php echo $this->__('Clear All') ?></a></div>
    <?php endif; ?>
    <?php if($this->canShowOptions()): ?>
        <p class="block-subtitle"><?php echo $this->__('Shopping Options') ?></p>
        <dl id="narrow-by-list">
            <?php $_filters = $this->getFilters() ?>
            <?php foreach ($_filters as $_filter): ?>
            <?php if($_filter->getItemsCount()): ?>
            <?php if(in_array($_filter->getName(),$filterCategory[$currentCategory])) continue ?> 
                <dt><?php echo $this->__($_filter->getName()) ?></dt>
                <dd><?php echo $_filter->getHtml() ?></dd>
            <?php endif; ?>
            <?php endforeach; ?>
        </dl>
        <script type="text/javascript">decorateDataList('narrow-by-list')                               </script>
        <?php endif; ?>
    </div>
</div>
<?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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