5

I can pretty easily remove various blocks from a given page through an event observer on, for instance, the controller_action_layout_general_blocks_before action. Here is an example:

    $action = $observer->getEvent()->getAction();
    $layout = $observer->getEvent()->getLayout();
    $update = $layout->getUpdate();

    $update->addUpdate('
        <reference name="product.info">
            <remove name="product.info.addtocart" />
        </reference>
    ');

    $layout->generateXml();

However, I can't find a way to remove the price block, even straight from the catalog.xml file. It seems like Mage_Catalog_Block_Product->getPriceHtml($product) creates the block dynamically. (I think it ultimately uses Mage_Catalog_Block_Product_Abstract->_getPriceBlock() which is in a file I can't really override.)

My goal here is to remove the price block from catalog view pages in certain situations, but I can't seem to remove that block. Instead, it seems I have to change the template file itself, which I want to avoid doing for this particular task.

(Magento 1.9.0.1)


This is the solution that I came up with Fabian Blechschmidt's help.

In my config.xml

<frontend>
    <events>
        <core_block_abstract_to_html_before>
            <observers>
                <custom_to_html_before>
                    <class>mymodule/observer</class>
                    <method>coreBlockAbstractToHtmlBefore</method>
                </custom_to_html_before>
            </observers>
        </core_block_abstract_to_html_before>
    </events>
</frontend>

In my observer model

public function coreBlockAbstractToHtmlBefore(Varien_Event_Observer $observer) {
    // Simple example logic
    $hidePrice = true;

    $block = $observer->getBlock();

    if (get_class($block) == 'Mage_Catalog_Block_Product_View') {
        if ($hidePrice) {
            $block->getProduct()->setCanShowPrice(false);
        }
    }
}
2

I think you are right. The block is created dynamically, so I think you have three options:

  1. change the template
  2. hook into core_block_abstract_to_html_after and remove everything from html
  3. set $this->getProduct()->getCanShowPrice() to false before the price block is rendered
  • getCanShowPrice() seems to be a Magic Method to pulls an attribute. Wouldn't doing something like $product->setCanShowPrice() change the database, and have a chance at affecting how the product is displayed for other users? – Tyler V. Jun 4 '14 at 22:19
  • I ended up using core_block_abstract_to_html_after, though I don't like that the server does all of the work to generate the HTML just to have it erased. Thanks. – Tyler V. Jun 5 '14 at 0:11
  • 1
    I think it is better to use core_block_abstract_to_html_before and just setCanShowPrice(false) - after a night of thinking :) – Fabian Blechschmidt Jun 5 '14 at 6:14
  • 1
    canShowPrice is no attribute, so it is only temporary – Fabian Blechschmidt Jun 5 '14 at 6:14
1

I nice trick to force remove a block is to set the template to empty string. So, you can overwrite the block class and do something like this:

protected function _beforeToHtml()
{
    // Simple example logic
    $hidePrice = true;
    if ($hidePrice) {
        $this->setTemplate('');
    }

    return $this;
}

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.