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?

  • Do you have using default magento Layering Navigation or use any 3-rd party module – Amit Bera Feb 17 '16 at 13:03
  • Just Magento Layering Navigation. – ADDISON74 Feb 17 '16 at 13:17
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>
| improve this answer | |
  • This is an elegant solution. I will test it for sure. – ADDISON74 Jul 23 '17 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
}
| improve this answer | |
  • This is a quick approach. I appreciate for your idea. – ADDISON74 Feb 18 '16 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 '16 at 10:18
  • @ADDISON74 updated answer with serch page track – Prashant Valanda Nov 30 '16 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

| improve this answer | |
  • 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 '16 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 '16 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; ?>
| improve this answer | |

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.