14

I have a layered navigation, and the customer wants to have <select/> fields instead of a long list of links.

I thought about just changing the template with a observer if the name/id of the filter matches.

Any better ideas or recommendations? Alternatives to changing the template, maybe overwrite/rewrite the block or only change the block class for the two filters?

What event to use for changing the template?

I have then the same problem as here https://stackoverflow.com/questions/14524791/magento-enable-or-disable-a-module-in-code/14529629 because I have an observer who changes layout things. This is only theme relevant. So chechking the theme before running the updates might be a good idea?

5
  • "customer wants to have fields instead of a long list of links" I have no idea what you mean by this. Jan 26 '13 at 13:25
  • damn, stackexchange ate my <select> Jan 26 '13 at 13:29
  • 1
    I'd say just overwrite the catalog/layer/filter.phtml template and change what you need to, it will be theme specific as well. The only thing you have to deal with is the selected filters bit. I'm guessing you want to show all the filter selected in the <select> that might require adding some Block functions, because once a filter is selected the other options disappear. Jan 26 '13 at 13:39
  • no, the customer want to have the categories and "subcategories" (attribute) as select boxes, everything else with checkboxes (work to do) and additionally filter by rating :-) But then I'll implement everything in the template. Jan 26 '13 at 14:03
  • 1
    This comment serves as a note for me. I have an answer for this but am on my phone. Love working in the layered Nav. I extended it to support selecting multiple fields in a previous project (think checkboxes) Jan 26 '13 at 15:02
6

Ok, things you need to do: 1. Override the 'catalog/layer_view' block to set your own template. I put my layered nav in the header area as part of a 1 column layout

<layout>
    <catalog_category_layered>        
        <reference name="header">
            <block type="catalog/layer_view" name="mylayered"  template="mymodule/catalog/layer/view.phtml"/>
        </reference>    
    </catalog_category_layered>
</layout>

In that template file you need to specify the overridden template for your individual elements.

<?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 /* !!! HERE !!! */ ?>
                <?php if(some_condition == true){ $_filter->setTemplate('path/to/your/new/filter.phtml'); } ?>
                <?php if($_filter->getItemsCount()): ?>
                    <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; ?>

Finally, you need to create the drop down filter.phtml. That should be straight forward. This is poorly formatted as I am having trouble with this editor, but the general idea is here. Some Javascript will be needed as well.

<ol>

    <li><select>
    <?php foreach ($this->getItems() as $_item): ?>
        <option value="<?php echo $this->urlEscape($_item->getUrl()); ?>">
        <?php if ($_item->getCount() > 0): ?>
        <a href="<?php echo $this->urlEscape($_item->getUrl()) ?>"><?php echo $_item->getLabel() ?></a>
        <?php else: echo $_item->getLabel() ?>
        <?php endif; ?>
        <?php if ($this->shouldDisplayProductCount()): ?>
        (<?php echo $_item->getCount() ?>)
        <?php endif; ?>
    </option>
<?php endforeach ?>
</select></li>
</ol>
7
  • why bother doing the layout rewrite? Why not just copy the base template to the sites theme folder? Am I missing something here (a bit tired, been up all night with my ill newborn daughter)
    – ProxiBlue
    Jan 27 '13 at 0:30
  • @dedmeet congratz on your daughter and I have the same question. A simple theme template override would do. Jan 27 '13 at 9:28
  • @Tim: My mobile post seemed to have swallowed the [at]Tim, so this just so Tim get a notification.
    – ProxiBlue
    Jan 27 '13 at 15:21
  • @dedmeet When you comment, the original poster of the post will always be notified even if you do not mention him :)
    – mpaepper
    Jan 27 '13 at 22:22
  • Sorry, yes, the template rewrite would work. I mentioned that I moved my layered nav to the center of the page below the menu. That was irrelevant to the answer so I should have left it out. Jan 28 '13 at 15:41
10

You can use core_block_abstract_prepare_layout_after event on Mage_Catalog_Block_Layer_View block to change the template of your particular attribute filter.

It could be something like this:

public function yourObserver($observer) 
{
    $block = $observer->getBlock();
    if ($block instanceof Mage_Catalog_Block_Layer_View) {
        $block->getChild($yourAttributeCodeGoesHere . '_filter')
           ->setTemplate('your/template.phtml');
    }
}

Summary:

Every child filter block has alias in layered navigation block as [attribute_code]_filter, and all of them created in _prepareLayout() method so you can easily modify its template on core_block_abstract_prepare_layout_after event.

Also you can check within your observer that current theme is the same as expected one by calling:

$design = Mage::getSingleton('core/design_package')
$design->getPackageName(); // Returns current design package
$design->getTheme('layout'); // Returns current design layout

Sincerely, Ivan

2
  • If the child filter block gets assigned attribute_code_filter alias, why cant you simply set the template in a layout xml?
    – pspahn
    Jan 28 '13 at 5:52
  • 1
    @pspahn Because you cannot access it by alias though layout. If you check output of getNameInLayout() you'll see, that each of these blocks have unique name as ANNONYMOUS_30, ANNONYMOUS_23, etc. So you cannot rely on it. Jan 28 '13 at 19:48

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.