Как правильно обновлять макет с помощью страниц CMS? - PullRequest
8 голосов
/ 26 апреля 2011

У меня есть модуль рекомендуемых продуктов, который я написал, который помещает пользовательский блок на страницу со списком продуктов, которые соответствуют атрибутам, которые я определил в блоке.Первоначально я работал, добавив строку {{block...}} в раздел «Содержимое» на странице CMS.Это работало нормально, но я не получил пейджер.Итак, я исправил это, удалив строку {{block...}} из раздела Content и добавив XML в раздел XML обновления макета следующим образом:

<reference name="content">
    <block type="cms/block" name="product_list_top" />
    <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml">
        <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
            <block type="page/html_pager" name="product_list_toolbar_pager"/>
        </block>
        <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
        <action method="setAttributeName"><name>my_attribute</name></action>
    </block>
</reference>

Это также отлично работает.Затем я решил, так как экземпляров этого блока так много, что было бы намного чище, если бы я добавил XML-файл в папку макета для моей темы и поместил туда этот код.Затем, в разделе Обновление макета, я мог бы просто получить это вместо:

<reference name="vps_featured_list">
    <action method="setAttributeName"><name>other_attribute</name></action>
</reference>

Итак, я создал файл с именем vps_featured.xml и добавил к нему:

<layout version="0.1.0">
    <default>
        <reference name="content">
            <block type="cms/block" name="product_list_top" />
            <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml">
                <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                    <block type="page/html_pager" name="product_list_toolbar_pager" />
                </block>
                <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
            </block>
        </reference>
    </default>
</layout>

ЭтоXML-файл обновления макета был указан в config.xml для моего пользовательского модуля.Я наивно предполагал, что vps_featured.xml будет включен в макет страницы только тогда, когда мой блок VPS Featured находится на странице, что может произойти только в этих нескольких случаях на специальных страницах CMS.Видимо, это не так.Это сломало все остальные страницы, я думаю, потому что это переопределяло дескриптор по умолчанию.

Так что это приводит меня к вопросу № 1: Когда XML-файлы макета включены в макет страницы?Используются ли они для ВСЕХ страниц, независимо от того, используется ли модуль, ссылающийся на них, на самом деле?

Затем я решил попробовать добавить новый дескриптор макета, на который я мог бы ссылаться, когда я хочу на своих страницах CMS.,Я изменил свой XML-файл макета, чтобы основная часть находилась в тегах <vps_featured_list>, а не в тегах <default>.Это вернуло к жизни другие страницы, но, конечно, мои CMS-страницы больше не работали, потому что этот дескриптор обновления макета не используется на этих страницах.Я попытался добавить <update handle="vps_featured_list" /> в раздел XML обновления макета страницы CMS, но это не сработало (я не ожидал, что это произойдет).

Так что это подводит меня к вопросу №2: Какой правильный способ сделать это?

Не похоже, что это должно быть так сложно, но, очевидно, я что-то упускаю.Я прочитал все, что я могу найти на макетах, но это всегда простые примеры, такие как «добавить это на КАЖДУЮ страницу продукта».Я не хочу, чтобы что-то добавлялось на КАЖДУЮ страницу cms ... только некоторые из них.Я застрял, используя раздел XML обновления макета для рассматриваемых страниц CMS?Я чувствую, что должен быть более чистый путь.

Спасибо,

Брайан

Ответы [ 2 ]

17 голосов
/ 26 апреля 2011

Узел <default/> - это то, что называется «дескриптором макета». Каждый запрос в Magent генерирует несколько таких ручек. Посетите вкладку Layout на демо-сайте Commerce Bug , чтобы получить представление о сгенерированных дескрипторах.

Magento объединяет все макеты XML-файлов в одно гигантское дерево, называемое макетом пакета. Затем дескрипторы определяют, какие фрагменты Layout XML Update используются для конкретного запроса. Эти фрагменты объединяются в макет страницы. Как вы интуитивно понимали, дескриптор <default/> добавляется всегда , поэтому вы размещаете все сайты в своей системе.

Плохая новость заключается в том, что, хотя есть дескриптор для страниц CMS (<cms_page_view />), это все равно будет делом "все или ничего". Вы можете добавить что-то на все страницы CMS, но не на определенные страницы CMS. Так что да, раздел XML обновления макета администратора CMS - это «правильный» способ сделать то, что вы хотите.

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

В своем XML-файле добавьте фрагмент XML-кода Layout Update в пользовательский дескриптор.

<pre><layout version="0.1.0"> <my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names> <reference name="content"> <block type="cms/block" name="product_list_top" /> <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml"> <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml"> <block type="page/html_pager" name="product_list_toolbar_pager" /> </block> <action method="setToolbarBlockName"><name>product_list_toolbar</name></action> </block> </reference> </my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names> </layout>

Затем в CMS Admin добавьте следующий XML-код Layout Update для нужных вам страниц

<update handle="my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names" />

Magento позволяет XML-фрагментам Layout Update добавлять дополнительные дескрипторы к запросу. Это то, что вы делаете выше. Это немного проясняет ситуацию, и если вы хотите изменить часть XML, есть централизованное место для этого.

Обновление : Оказывается, что команда может только использоваться из самих XML-файлов Layout. Код, который загружает XML-код Layout Update для страниц CMS, - это не тот код, который загружает и обрабатывает обновления для файлов XML. Magento буквально добавит что-либо в форму CMS в качестве обновления макета. Он не будет обрабатывать его для рекурсивных обновлений. Таким образом, добавление чего-то подобного к local.xml будет работать

<mock_product_list>
    <reference name="head">
    <label>Mock Product List</label>        
                <action method="addItem"><type>skin_js</type><name>js/sw/wall.js</name></action>
    </reference>    
</mock_product_list>

<cms_page_view>
    <update handle="mock_product_list" />
</cms_page_view>

Но вы не можете сделать это напрямую с помощью обновления, примененного через администратора CMS. Живи и учись.

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

  1. Создание пользовательского модуля с пользовательским классом блока

  2. Класс блока не отображает HTML

  3. Класс блока содержит единственный метод с именем что-то вроде «addFooToLayout»

Затем на своей странице CMS добавьте обновление, подобное этому

<block type="yourmodule/yourblock" name="unique_name" alias="unique_name">
    <action method="addFooToLayout" />
</block>

и затем в вашем определении блока

public addFooToLayout()
{
    $layout = Mage::getSingleton('core/layout');
    $head   = $layout->getBlock('head');
    $head->addItem('skin_js','js/sw/wall.js');
    //etc...
}

Что-то в этом роде должно работать и будет немного понятнее (в зависимости от того, сколько XML Layout Update вы хотите добавить). Однако, я не проверял это, и мой авторитет подорван на этом, поэтому покупатель остерегается.

Второй подход состоит в том, чтобы создать отдельный виджет , который включает в себя то, что вы хотите добавить на страницу, а затем с помощью администратора экземпляра виджета добавить этот виджет в определенные блоки на определенных страницах. Эти ссылки должны помочь вам начать.

Наконец, рискуя стать шиллом, я недавно самостоятельно опубликовал книгу о макетах Magento , в которой подробно рассматриваются вопросы такого рода. Это стоит вашего времени, если вы заинтересованы в понимании того, как работает вся система.

3 голосов
/ 07 ноября 2014

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

Вчера, когда я прочитал этот вопрос и ответ, а также это и это сообщений, я совершенно уверен, что невозможно или довольно сложно переопределить / расширить страницу CMS Дескриптор макета только для определенных страниц. Это привело меня к разработке одного небольшого расширения, которое вставляет любой пользовательский дескриптор макета на любую конкретную страницу. Я скоро обновлю этот пост публичной ссылкой на расширение.

Но затем я обнаружил, что на самом деле можно просто создать новый шаблон для страницы CMS и назначить для этого шаблона любой пользовательский дескриптор макета, см. этот вопрос и ответ от Marius, например. Вот важный фрагмент этого примера кода:

<global>
    <page>
        <layouts> 
            <lookbook module="page" translate="label">
                <label>Lookbook</label>
                <template>page/1column-lookbook.phtml</template>
                <layout_handle>lookbook</layout_handle>
            </lookbook> 
        </layouts>
    </page>
</global>

Довольно просто внедрить любой пользовательский дескриптор макета на любую страницу и делать все, что вы хотите, только со страницами, которые используют этот шаблон и ваш собственный дескриптор макета. Хотелось бы знать, что раньше, надеюсь, этот пост сэкономит кому-то время.

...