7

I'm trying to add a block to the product listing:

<?xml version="1.0"?>
<layout version="0.1.0">
    <catalog_category_view translate="label">
        <reference name="product_list">
            <remove name="product_list_toolbar"/>
            <block type="core/template" name="helloworld" as="helloworld" template="helloworld.phtml"/>
        </reference>
        <reference name="footer">
            <block type="core/template" name="helloworld" as="helloworld" template="helloworld.phtml"/>
        </reference>
    </catalog_category_view>
</layout>

In catalog/product/list.phtml I have this:

<?php Zend_Debug::dump($this->getSortedChildren()); ?>
<?php echo $this->getChildHtml('helloworld'); ?>

In page/html/footer.phtml I have this:

<?php Zend_Debug::dump($this->getSortedChildren()); ?>
<?php echo $this->getChildHtml('helloworld'); ?>

Note that I only added <remove name="product_list_toolbar"/> so that I can test if my reference to product_list works correctly, by seeing if product_list_toolbar is removed from the sorted children list. It is.

So what I now have is identical code in the product list and the footer, and it only works in the footer. After doing some digging, I can't find any instance of a block being added to product_list other than product_list_toolbar. So, is there something about this block that makes adding children not work?

  • actually this is a good question and I dont understand why community is trying to close this question ! This is not surely an opinion based question. We should appreciate this type of questions. – Rajeev K Tomy Jan 23 '15 at 4:43
8

The issue here is the order in which the blocks are specified in the layout XML.

catalog_category_view is technically the right handle, BUT in that handle the product_list block doesn't exist (yet!).

The product_list block only gets created in the catalog_category_default and catalog_category_layered handles. (And those handles are specified later in the XML than catalog_category_view.)

In short, when all the layout XML gets merged, your reference to product_list won't get executed, because it doesn't exist yet at that point.

The solution is to add your block in both catalog_category_default and catalog_category_layered, OR, create your own custom handle, add your block in that handle, and use the <update> directive to include your handle in catalog_category_default and catalog_category_layered.

Hope that worked for you.

| improve this answer | |
  • Any page with catalog_category_layered also seems to have catalog_category_default so it seems that I only needed catalog_category_default. Other than that, this was spot on, and helped me understand why it was doing this. Thanks. – Tyler V. Jan 23 '15 at 3:27
  • @TylerV. you are wrong on your comment. See my answer for more details. – Rajeev K Tomy Jan 23 '15 at 5:00
3

Indeed catalog_category_view is get processed for every category view page and you selected a layout handle correctly. However the problem here exists is that, we need to take care of the order in which layout handles are get processed in magento.

In this context, that is for category product list viewing page, layout handles are processed in this order (refering to )

  0 => 'default'
  1 =  'STORE_default' 
  2 => 'THEME_frontend_rwd_default'
  3 => 'catalog_category_view'
  4 => 'catalog_category_layered' 
  5 => 'CATEGORY_4'
  6 => 'customer_logged_out'
  7 => 'SHORTCUT_popup'
  8 => 'SHORTCUT_uk_popup' 
  9 => 'product_list' 

This means when magento process loadLayout action, it will first consider default layout handle first and include blocks defined in this layout handle through layout update files. Then it will process STORE_default and so on. This means catalog_category_view layout handle is processing before catalog_category_default or catalog_category_layered. This is the important point here to note.

Magento is defining product_list block inside the layout handle catalog_category_default and catalog_category_layered. Since catalog_category_view is processing just before these two layout handles, product_list block which is referenced in your definition is totally stranger and hence magento simply neglect the contents inside it.

About your comment

I think you have misunderstood it. There are two types of categories based on layout. They are

  1. default category
  2. layered category

Magento will add different layout update handle for these two types of categories. For default categories it will process only catalog_category_default. For layered cateogries, magento process only catalog_category_layered. In both these cases magento will definitely process action layout handle catalog_category_view and category specific layout handle CATEGORY_{ID}. ie in short, action layout handle will get processed for every category view page. (category specific layout handle will be different for different categories.) See the proof here

File : app/code/core/Mage/Catalog/Model/Category.php

public function getLayoutUpdateHandle()
{
    $layout = 'catalog_category_';
    if ($this->getIsAnchor()) {
        $layout .= 'layered';
    }
    else {
        $layout .= 'default';
    }
    return $layout;
}

see catalog_category_layered will get included in layout update only when if category's isAnchor property is set to yes (we are doing this through admin side.). Otherwise it will process catalog_category_default

In short : order in which layout handles are get processed in magento is the villain and hero in this case.

| improve this answer | |
  • You're correct about catalog_category_layered and catalog_category_default not appearing together. I saw catalog_category_layered_nochildren and got them mixed up. Oddly enough, catalog_category_layered_nochildren is added even on non-layered categories. – Tyler V. Jan 23 '15 at 6:03
  • catalog_category_layered_nochildren is considered only when viewing category has no children categories. For categories that is holding some children categories, this specific layout handle will not get processed. Does that sound logical ? – Rajeev K Tomy Jan 23 '15 at 6:08
0

I put my reference and update under the handle catalog_category_view however the product_list block is defined under the handle catalog_category_default. It seems like this should cascade and still work, and I invite someone to tell me why it doesn't. But changing the handle used for this update fixed the issue.

| 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.