Динамическое переключение тем на маршрутах, у которых нет дескриптора макета


Проблема

При реализации динамического переключателя тем с использованием controller_action_layout_load_before оказывается, что некоторые маршруты не имеют дескрипторов макета. Это связано с тем, как они загружают макет; технически это не так.

Рассмотрим оформление заказа/на странице/прогресс:

public function progressAction()
{
    // previous step should never be null. We always start with billing and go forward
    $prevStep = $this->getRequest()->getParam('prevStep', false);

    if ($this->_expireAjax() || !$prevStep) {
        return null;
    }

    $layout = $this->getLayout();
    $update = $layout->getUpdate();
    /* Load the block belonging to the current step*/
    $update->load('checkout_onepage_progress_' . $prevStep);
    $layout->generateXml();
    $layout->generateBlocks();
    $output = $layout->getOutput();
    $this->getResponse()->setBody($output);
    return $output;
}

Он генерирует XML и блокирует, но на самом деле никогда не вызывает loadLayout или renderlayout.

Из-за этого мы не можем использовать дескрипторы макета, чтобы повлиять на изменения. Это не идеально.

В вопрос

Из-за этого при изменении темы для оформления заказа на странице я вынужден анализировать запрошенный маршрут. Мне это не нравится:

public function controllerActionLayoutLoadBefore()
{
    $request = Mage::app()->getRequest();

    if($request->getModuleName()=='checkout' && $request->getControllerName()=='onepage'){
        //do the theme switching
    }
}

Есть ли лучший способ? Я рассматривал, по крайней мере, выпуск loadLayout из перезаписи OnepageController, но для этого требуется переписать, и мне это не нравится.

Author: philwinkle, 2015-03-16

1 answers

Вы можете прослушать событие predispatch. Он всегда срабатывает и содержит необходимую вам информацию о маршруте.

Используйте это в своем config.xml

<frontend>
    <events>
        <controller_action_predispatch_checkout_onepage_progress>
            <observers>
                <magento_test>
                    <class>magento_test/observer</class>
                    <method>changeTheme</method>
                </magento_test>
            </observers>
        </controller_action_predispatch_checkout_onepage_progress>
    </events>
</frontend>

Тогда в наблюдателе вы могли бы иметь -

public function changeTheme($observer) {
    Mage::getDesign()->setPackageName('hello')->setTheme('world');
}
 2
Author: Mridul Aggarwal, 2015-03-17 16:02:25