Ориентация на несколько дескрипторов макета в макете XML

22

У меня есть пользовательский контроллер, доступный по пути, /custommodule/customer/infoкоторый загружает 2columns-left.phtmlшаблон на rootузле следующим образом:

<custommodule_customer_info>
    <reference name="root">
        <action method="setTemplate"><template>page/2columns-left.phtml</template></action>
    </reference>
</custommodule_customer_info>

Я хотел бы обновить корневой шаблон для клиентов, которые не вошли в систему, например:

<customer_logged_out>
    <custommodule_customer_info>
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
    </custommodule_customer_info>
</customer_logged_out>

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

Я думал, что могу нацелить ручку моего контроллера с помощью следующего:

<customer_logged_out>
    <reference name="custommodule_customer_info">
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
    </reference>
</customer_logged_out>

Это действительно обновляет корневой шаблон с помощью 1column.phtmlшаблона, но он делает это на том, что выглядит как все страницы, а не только страница, предназначенная для моего referenceузла.

Я пробовал несколько перестановок этого обновления макета, но, похоже, ни одна из них не работает. Как можно настроить таргетинг на этот дескриптор макета, одновременно используя customer_logged_outдескриптор макета?

- edit - Чтобы было понятно, это на самом деле сторонний модуль.

pspahn
источник

Ответы:

18

Поскольку вы используете свой собственный контроллер, вам не нужно использовать только ручки по умолчанию. Основываясь на статусе входа, вы можете добавить в свой метод infoAction

 $this->getLayout()->getUpdate()->addHandle('mymodule_customer_info_logged_in');

или

 $this->getLayout()->getUpdate()->addHandle('mymodule_customer_info_logged_out');

а затем в вашем файле layout.xml использовать

<mymodule_customer_info_logged_in>

а также

<mymodule_customer_info_logged_out>

- добавление после редактирования ниже -

Видя, что вы не хотите редактировать контроллер (так как это расширение стороннего производителя), я бы создал отдельное расширение, которое наблюдает только за controller_action_layout_load_before

    $update = $observer->getEvent()->getLayout()->getUpdate();
    $handles = $update->getHandles();

    if (in_array('custommodule_customer_info', $handles)) {

        //code to add the custom handles based on login
    }
Кристоф в Фуман
источник
Snazzy. Это не идеально, но является относительно чистым решением. Как я уже упоминал в своем другом комментарии ниже, я бы предпочел не изменять сторонний модуль, но, похоже, здесь нет большого выбора. Позор, потому что customer_logged_in/outручки могут быть такими мощными, но они ограничиваются из-за этого ограничения.
pspahn
14

Алан Шторм ответил примерно так:

/programming//a/5601579/1157493

Вы можете использовать помощника для проверки логики входа в систему.

<action method="setTemplate">
    <template helper="mymodule/myhelper/switchTemplateIf"/>
</action>

Он вызовет Mage::helper('mymodule/myhelper')->switchTemplateIf(); In the helper, вы можете решить переключить шаблон или просто оставить его таким.

Я считаю, что это устанавливает шаблон для того, что вы returnв этой функции.

Это будет выглядеть примерно так:

public function switchTemplateIf() {
    if (Mage::helper('customer')->isLoggedIn()) {
        return 'page/1column.phtml';
    } else {
        return 'page/2column-right.phtml';
    }
}

Непроверенные

Рик Кейперс
источник
У меня тоже была эта мысль, но я надеялся, что для выполнения этого нужно будет полагаться только на макет XML модуля без необходимости полагаться на дополнительные классы в модуле - философия «если это можно сделать в XML, сделайте это». в XML не создавайте дополнительные ресурсы модуля, если в этом нет необходимости ".
pspahn
@pspahn Конечно, цель состоит в том, чтобы попытаться сделать это с помощью системы макетов XML, которую предоставляет Magento, к сожалению, у нее есть свои ограничения, и я считаю, что это одна из них. Хотя я все еще думаю, что это вполне жизнеспособное решение, несмотря на дополнительный ресурс модуля.
Рик Кейперс
У @pspahn Fooman есть хорошее альтернативное решение, которое я бы рекомендовал по моему. Это требует меньше кодирования!
Рик Кейперс
В данном случае я на самом деле имею дело со сторонним модулем. Я бы предпочел не редактировать их модуль (так как обновления могут его нарушить), и я бы не стал помещать это в класс вспомогательного модуля (поскольку это связывает их модуль и модуль вместе в бедре).
pspahn
6

Недавно мне понадобился такой вид функциональности, и мне становилось все труднее добавлять все больше и больше дескрипторов макета для всех различных комбинаций существующих дескрипторов макета, поэтому я создал расширение magento, чтобы добавить возможность нацеливания на несколько дескрипторов макета непосредственно из XML-макета.

Вот ссылка на расширение - https://github.com/mridul89/MultipleHandles.git

Вы бы использовали это так

<customer_logged_out ifhandle="custommodule_customer_info">
    <reference name="root">
        <action method="setTemplate"><template>page/1column.phtml</template></action>
    </reference>
</customer_logged_out>

Это скажет magento использовать только этот конкретный customer_logged_outдескриптор макета, еслиcustommodule_customer_info макета, он также присутствует.

Мридул Аггарвал
источник