1

I need two layered navigation blocks on the same page (one at the top with select dropdowns) and one in sidebar with more similar to default styling. Additionally, there could be restriction on attributes, so top and sidebar can have different attributes to filter.

My first thought was just make another instance of layered nav block and pass there different template file. But then it turned out that templates assignment is buried inside block logic. So, I decided to override block and create there methods like excludeAttribute or setStyling, and then call them within layout file for each block. Unfortunately, this doesn't work either, I guess because the logic for getting attributes and setting up child blocks in located under _prepareLayout method, which is being called before my methods. Then I tried to defer this evaluation, by creating wrapper block file, which has my methods for passing attributes and styling and save that data. Then, in _toHtml method of my wrapper block I create my overridden layer_view block, and pass there these settings. Constructor of layer_view block handles that data and calls _prepareLayout method using them, assigning different templates for child blocks and getting customized attributes collection to filter. Visually, that seems to work. I can set filters and both blocks are getting updated properly (though both shows global active filters). But for some reason filtering itself doesn't work (products in category stays the same). So in short: if I create my layer_view block within layout file the filtering works, but I can't pass anything there. If I create wrapper block which then creates layer_view block programmatically via $this->getLayout()->createBlock method, I can pass my settings but I lose filtering. What can possibly be wrong with creating this block programmatically?

Maybe I'm going in wrong direction and it should be done in different way?

  • I think it´s a kind of conflict problem. You have 2 lay. Nav Top and Bottom, both are used to generate some output depends on there filters -> Problem is now where does Magento knows which lay. Nav. filter to use, is there any logic for example priority or is the top lay. Nav like a sub filter for the bottom, or which filter or combination of filter is used to generate the output. – Samir Shaban Jun 26 '14 at 13:32
  • Yes, that might be the case. Actually, magento could've just parsed GET parameters in url, since all filters add corresponding parameters to the url. But I tried to remove every block related to layered nav, and just update the page - collection doesn't get filtered. So some filtering mechanics are inside that block. On the other hand, I tried to use single layer block with my wrapper, and it filtering doesn't work either. So it's not the conflict between two layer blocks, somehow calling block in xml file is different to generating it programmatically. – nevermourn Jun 26 '14 at 14:09
  • Well, actually the problem was that _toHtml method in my wrapper block was called too late. I moved block creation in my wrapper block from _toHtml method to its own _prepareLayout, where I just save resulting html to private field and then output it in _toHtml method. Now I'm getting nice sql error from somewhere deep, that I guess means that I can't use same attribute once (You cannot define a correlation name 'manufacturer_idx' more than once). So yes, the two instances of layer_view block indeed conflict. – nevermourn Jun 26 '14 at 14:31
2

This can be done by using below code

  echo  $this->getLayout()->getBlock('catalog.leftnav')->toHtml();
  • I don't quite understand where and how can I use it. This is default block which I removed from layout because of reasons described above (can't pass there my custom settings). I can get this block back to layout and call your code for area above products. But two layered navigations will be identical, while I need them to be different. – nevermourn Jun 26 '14 at 11:55
  • Well, after playing around it seems that this is the best way to deal with it. Because rewriting block leads to messing with magento layer logic, which I don't really want to do. I guess I can pass data to copy of this block via setData method, then catch it within template and don't output information that I don't need. Sounds ugly, but this is the best I came up with. – nevermourn Jun 26 '14 at 15:07

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.