0

How i can change block type programmatically from controller.

1 Answer 1

1

Here i change login form url without change .phtml and layout xml file.

Original login handler is

<customer_account_login translate="label">
    <label>Customer Account Login Form</label>
    <!-- Mage_Customer -->
    <remove name="right"/>
    <remove name="left"/>

    <reference name="root">
        <action method="setTemplate"><template>page/1column.phtml</template></action>
    </reference>
    <reference name="content">
        <block type="customer/form_login" name="customer_form_login" template="customer/form/login.phtml" />
    </reference>
</customer_account_login>

I going to change "customer_form_login" block block type

Create Controller which extend Mage_Customer_AccountController which contain loginAction()

class Namespace_ModuleName_AccountController extends Mage_Customer_AccountController{
public function loginAction()   {
  if ($this->_getSession()->isLoggedIn()) {
        $this->_redirect('*/*/');
        return;
    }
    $this->getResponse()->setHeader('Login-Required', 'true');
    $this->loadLayout();

    $update = $this->getLayout()->getUpdate();
    $update->addHandle('customer_account_login');
    $this->loadLayoutUpdates();
    $this->generateLayoutXml();
    $this->generateLayoutBlocks();
    $this->_isLayoutLoaded = true;

    $blockList = $this->getLayout()->getBlock('customer_form_login');
    $template = $blockList->getTemplate();
    $blockChildBlock = $blockList->getChild();

    $this->getLayout()->unsetBlock('customer_form_login');
    $parentBlock = $this->getLayout()->createBlock('blockname/customer_form_login','customer_form_login')->setTemplate($template);

    if($blockChildBlock){
        foreach($blockChildBlock as $childBlock){
            $this->getChildBlockLogin($parentBlock,$childBlock);
        }
    }
    $this->_initLayoutMessages('customer/session');
    $this->_initLayoutMessages('catalog/session');
    $this->renderLayout();   
 }
}

public function getChildBlockLogin($parentBlock,$childBlock){

    /*echo "ChildB: ".$childBlock->getNameInLayout()."<br/>";
    echo "Alias: ".$childBlock->getBlockAlias()."<br/>";
    echo "Child: ".$childBlock->countChildren()."<br/>";
    echo "Type: ".$childBlock->getType()."<br/>";
    echo "Template: ".$childBlock->getTemplate()."<br/>";*/
    $childName = $childBlock->getNameInLayout();

    if($childBlock->getBlockAlias()!=''){
        $childName = $childBlock->getBlockAlias();
    }
    if($childBlock->getTemplate()!=''){
        //$child = $this->getLayout()->createBlock($childBlock->getType(),$childName)->setTemplate($childBlock->getTemplate());
        $parentBlock->setChild($childName,$childBlock);
    }
    else{
        //$child = $this->getLayout()->createBlock($childBlock->getType(),$childName);
        $parentBlock->setChild($childName,$childBlock);
    }
    $parentBlockData = $this->getLayout()->getBlock($childBlock->getNameInLayout());
    $blockChildBlockData = $parentBlockData->getChild();
    if($blockChildBlockData){
        foreach($blockChildBlockData as $childBlockData){
            $this->getChildBlockLogin($parentBlockData,$childBlockData);
        }
    }       
 }
}

Create block "\app\code\local\Namespace\ModuleName\Block\Customer\Form\Login.php"

class ModuleName_ModuleName_Block_Customer_Form_Login extends Mage_Customer_Block_Form_Login{
  public function getPostActionUrl(){
     return Mage::getUrl('modulefrontname/account/loginPost');
 }
}

From this code you can also copy original block child block in new created block. Try below code to test child blocks

<customer_account_login translate="label">
    <label>Customer Account Login Form</label>
    <!-- Mage_Customer -->
    <remove name="right"/>
    <remove name="left"/>

    <reference name="root">
        <action method="setTemplate"><template>page/1column.phtml</template></action>
    </reference>
    <reference name="content">
        <block type="customer/form_login" name="customer_form_login" template="customer/form/login.phtml">
            <block type="core/template" name="test.block" template="customer/form/test.phtml" >
                <block type="core/template" name="test.block1" as="testB1" template="customer/form/test1.phtml" />
            </block>
        </block>
    </reference>
</customer_account_login>

Create file in "\app\design\frontend\base\default\template\customer\form\test.phtml"

<?php echo $this->getChildHtml('testB1')?>

Create file in "\app\design\frontend\base\default\template\customer\form\test1.phtml"

Child Block<br/>

This code return error while enable cache from admin. To fixed that issue we have to comment below code

/*$update = $this->getLayout()->getUpdate();
$update->addHandle('customer_account_login');
$this->loadLayoutUpdates();
$this->generateLayoutXml();
$this->generateLayoutBlocks();
$this->_isLayoutLoaded = true;*/

and created layout file in "\app\design\frontend\base\default\layout\layoutname.xml "

<?xml version="1.0"?>
<layout version="0.1.0">
    <layout_handler translate="label">
        <update handle="customer_account_login"/>
    </handler>
</layout>

This is not best solution for me because i did not want to use .xml file. Please suggest me if any one get good solution for this issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.