1

In controller, for some condition, I want to set another parent block instead of the declared one in the layout XML. The goal is to have a possibility to make checks in template file like this:

if ($this instanceof My_Module_Block_CustomBlock) { 
    // ... custom stuff in template ... 
}

I have tried append my custom block in the layout, but parent block is still which was declared in layout XML. The appended block is shown as a child1 of parent block:

public function ConversationAction(){

    // some condition:
    $converation_id = (int) $this->getRequest()->getParam('id');

    if (is_int($converation_id) && $converation_id > 0) {
        // I want to set my parent block here instead of default registered in xml layout file

        $this->loadLayout();

        $block = $this->getLayout()->createBlock('MyModule/Conversation')
            ->setData('area', 'frontend')->setTemplate('customer/Conversation.phtml');
        $this->getLayout()->getBlock('content')->append($block);

        $this->renderLayout();

    } else {
        // ... default layout and block ...

        $this->loadLayout();
        $this->renderLayout();
    }
}

Is it possible to change the root block from controller somehow ?

2

I think it is possible, but in some cases the question is wrong. You do not want to do this. If I'm looking at what you are trying to achieve, then this is not the right solution.

Templates should be really dumb and should not care about which class they are being applied to. Templates should contain all HTML you want to render and you should try to have the least amount of coded logic in there.

There are multiple ways to change the behaviour of template from a controller.

Solution 1: Passing variables

You can pass variables to a block that represent the result of your logic.

Controller method:

$converationId = (int) $this->getRequest()->getParam('id');
$this->loadLayout();
$block = $this->getLayout()->getBlock('.....');
if ($block) {
     $block->setHasConversation(  $converationId > 0  );
}

Template:

<?php if ($this->getHasConversation()): ?>
    <!-- Do conversation stuff -->
<?php else: ?>
    <!-- Do other stuff -->
<?php endif; ?>

Solution 2: Unset one of the blocks

Based on a condition you can unset the block you DON'T want to be show/rendered.

Your page template contains the shared HTML and the child blocks will

Layout XML:

<reference name="content">
    <block type="core/template" name="mymodule_page" template="'customer/page.phtml'">
        <block type="MyModule/Conversation" name="mymodule_conversation" template="'customer/conversation.phtml'"/>
        <block type="MyModule/Other" name="mymodule_other" template="'customer/other.phtml'"/>
    </block>
</reference>

Controller method:

$converationId = (int) $this->getRequest()->getParam('id');
$this->loadLayout();
$pageBlock = $this->getLayout()->getBlock('mymodule_page');
if ($pageBlock) {
     $pageBlock->unsetChild(
         ($converationId > 0 ? 'mymodule_other' : 'mymodule_page')
     );
}

Template customer/page.phtml:

/** Call getChildHtml() with no param to render all children */
$this->getChildHtml();
3
  • Thank you so much for this reply ! Finally I figured out how to control blocks from controller! May I ask you another small question: is it a good practice, to receive and process data in block constructor ? for example, template has a form, a form has no action value (empty), and thus, after submitting the form, it sends the data to this controller itself. I get used to write the main logic for filtering and saving form data in block's constructor (calling parent::_construct() after) but i wonder if its a good idea at all ? maybe everything should be in the controller ? Thanks!!! – Ilja Nov 30 '15 at 1:19
  • @Anonymous, you should tie everything together in your controller. If you want me to go deeper into this, then please post this issue as a new question and add the code of one of your block constructors as an example. – 7ochem Nov 30 '15 at 9:37
  • would love to hear the details from you!!! posted the question: magento.stackexchange.com/questions/92089/… – Ilja Nov 30 '15 at 14:49

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.