#php #xml #layout #magento
#php #xml #макет #magento
Вопрос:
Я пытался найти решение, но безрезультатно. Моя задача — написать модуль. Он должен вставить некоторый html в существующий блок.
Я заметил, что когда я использовал файлы layout .xml, я могу просто вставить свой блок в некоторую ссылку, например
<reference name="product.info">
<block type='googlethis/link' name="googlethis"
template="catalog/product/googlethis.phtml"/>
</reference>
и мой блок тоже отображается.
В других случаях я должен вызывать getChildHtml()
метод, и это нехорошо, потому что это приводит к изменению файлов template .phtml.
Итак, есть ли способ вставить мой блок phtml в любой другой блок phtml без вызова getChildHtml()
?
Ответ №1:
Есть способ сделать это, хотя это не совсем элегантное решение. Это будет работать в большинстве случаев, хотя и иногда оказывалось полезным.
По сути, идея заключается в том, что вы заменяете блок, который хотите отобразить в своем блоке до / после, в вашем макете XML, помещаете этот блок как дочерний в свой блок, а затем отображаете его выходные данные до / после вашего.
Итак, допустим, вы хотели вывести блок перед блоком итогов на странице сведений о корзине, вы могли бы сделать следующее в коде вашего расширения layout.xml
<checkout_cart_index>
<reference name="checkout.cart">
<block type="myextension/block" name="myextension.block" as="myextension_block" template="myextension/template.phtml">
<action method="setChild"><name>totals</name><block>totals</block></action>
</block>
<action method="setChild"><name>totals</name><block>myextension.block</block></action>
</reference>
</checkout_cart_index>
Тогда в вашем файле template.phtml у вас будет:
<div id="myextension">
// Your template code
</div>
// Render the totals block that you placed inside your block
<?php echo $this->getChildHtml('totals'); ?>
Как я уже сказал, это подойдет не для каждой ситуации и это не невероятно элегантно, но это работает.
Джон
Комментарии:
1. это отличное решение, мне оно нравится
2. Отлично! Это то, что я искал!
Ответ №2:
Нет, не существует универсального способа добавить ваш блок в любой другой блок. Причина, по которой это иногда срабатывает у вас, заключается в том, что есть некоторые типы блоков, которые просто перечисляют своих дочерних элементов ( core/text_list
являясь одним из них), и некоторые шаблоны вручную делают то же самое (используя $this->getChild()
).
Если вы хотите добавить свой блок под блок, который не соответствует ни одному из этих критериев, вам нужно будет изменить шаблон, чтобы отобразить этот блок.
Комментарии:
1. Также. Можем ли мы как-то определить, какой блок можно использовать в качестве ссылки в конфигурации макета для вывода без getChildHtml(), а какой нет? Спасибо
2. Проверка типа блока
core/text_list
была бы первым шагом. В противном случае, grep каталог шаблонов для$this->getChild()
вызовов.
Ответ №3:
Вы можете попробовать добавить в xml — следующий метод output=»toHtml» — поместит блок в родительский блок, но…
<reference name="product.info">
<block type='googlethis/link' name="googlethis" output="to Html" template="catalog/product/googlethis.phtml"/>
</reference>
Ответ №4:
Это возможно путем добавления в xml — следующий метод output=»toHtml» — поместит блок в родительский блок
<reference name="product.info">
<block type='googlethis/link' name="googlethis" as="googlethis" output="toHtml" template="catalog/product/googlethis.phtml"/>
</reference>
Ответ №5:
С помощью метода output=»toHtml» в layout блок перерисовывается в конце документа. Я тестировал с
<catalog_product_view>
<reference name="media">
<block type="pricetag/catalog_product_view" name="catalog.product.price.tag" template="pricetag/price.phtml" output="toHtml" />
</reference>
</catalog_product_view>
И magento отрисовал мой блок после тега html end
Ответ №6:
Я считаю, что вы не можете вывести блок, не имея его в показанном шаблоне. Итак, если вы создаете свое расширение поверх создания своего блока, вам нужно вызвать его в шаблоне, где вы этого хотите. К сожалению, это означает, что кто-то мог добавить ваше расширение на свой веб-сайт, и если они создали свою собственную копию файла шаблона, в который добавлен ваш блок, потому что они хотели изменить его в своей теме, то ваш блок там отображаться не будет. Им придется самим выяснить, что вашему модулю требуется модификация шаблона, и самим внести эту модификацию в свой собственный шаблон.
Блок может выводиться сам по себе без вызова в шаблоне, если вы добавите к нему output="toHtml"
атрибут, но, как указывали некоторые другие, это приведет к отображению блока после </html>
тега. Это нормально, потому что output="toHtml"
это то, что заставляет работать корневой блок. Корневой блок не может быть включен в шаблон, потому что у него нет родительского элемента, поэтому он использует output="toHtml"
атрибут и выводит его наружу. Это работает, потому что, когда Magento визуализирует свой макет (создает HTML страницы), он вызывает метод getOutput () класса Mage_Core_Model_Layout, и этот метод на самом деле просто получает все блоки, которые имеют выходной параметр, и выводит их на страницу 1 на 1. Обычно у вас должно быть только 2 таких блока, root и «core_profiler». (да, это означает, что профилировщик отобразится после закрывающего HTML-тега).
Ответ №7:
Я нашел элегантное решение с помощью Observer и написал сообщение в блог компании: http://www.fxplabs.com.br/blog/instanciando-blocos-em-qualquer-lugar-magento /
перевод на русский:
Комментарии:
1. пожалуйста, напишите о своем ответе здесь вместо публикации ссылки, спасибо!