Magento – How to Update Layout in Observer

event-observerlayout

I'm trying to change the layout of the success page with an observer at Mage_Checkout_OnepageController::successAction() on Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
This event is loaded after $this->loadLayout(); and before $this->loadLayoutUpdates();

My Observer

$update = Mage::app()->getLayout()->getUpdate();
$update->addHandle('my_personalized_handle');
$update->removeHandle('the_old_hanle');

Up to that point it works fine and on the controller I got the correct list of handles before the render. But at the render process it just ignores all what I changed even if I do $this->loadLayoutUpdates(); directly in the controller.

So at this point I'm a bit confused.

-== EDIT ==-

The other solution would be to redirect to another page than the success page, that would be to send a correct URL to Mage_Checkout_OnepageController::saveOrderAction() for $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();, I'm able to change the session when they land on the checkout page, but when they validate the payment the getRedirectUrl is empty and doesn't consider my new URL.

Do I set this problem as a second post?

Best Answer

Try using the event controller_action_layout_load_before. By setting up your events to listen to this you should be able to use the action and layout that are attached to this event.

<events>
    <controller_action_layout_load_before>
        <observers>
            <layout_test>
                <class>layout_test/observer</class>
                <method>changeLayoutEvent</method>
            </layout_test>
        </observers>
    </controller_action_layout_load_before>
</events>

Then you can check the action type in your observer. For example if you wanted to replace the standard success handle and add the customer account edit handle (just an idea don't think any shop would want the edit page here) then it would look it:

$action = $observer->getEvent()->getAction();
if ($action instanceof Mage_Checkout_OnepageController && $action->getRequest()->getRequestedActionName() == 'success') {
    $observer->getEvent()->getLayout()->getUpdate()
        ->addHandle('customer_account_edit')
        ->removeHandle('checkout_onepage_success');
}
Related Topic