Магенто. Вставить блок в другой без изменения кода шаблона
Я пытался найти решение, но безрезультатно. Моя задача - написать модуль. Он должен вставить некоторый 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()
?
7 answers
Есть способ сделать это, хотя это не совсем элегантное решение. Это будет работать в большинстве случаев, хотя и иногда оказывалось полезным.
В основном идея заключается в том, что вы заменяете блок, который хотите отобразить до/после, в 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'); ?>
Как я уже сказал, это не подходит для каждой ситуации, и это не невероятно элегантно, но это работает.
Джон
Нет, универсального способа добавить ваш блок в любой другой блок не существует. Причина, по которой это иногда работает для вас, заключается в том, что есть некоторые типы блоков, которые просто перечисляют своих потомков (core/text_list
является одним из них), и некоторые шаблоны вручную делают то же самое (используя $this->getChild()
).
Если вы хотите добавить свой блок под блоком, который не соответствует ни одному из этих критериев, вам нужно будет изменить шаблон, чтобы повторить этот блок.
Вы можете попробовать добавить в xml - следующий метод вывод="toHtml" - поместит блок в родительский блок , но...
<reference name="product.info">
<block type='googlethis/link' name="googlethis" output="to Html" template="catalog/product/googlethis.phtml"/>
</reference>
Это возможно путем добавления в xml - следующий метод вывод="toHtml" - поместит блок в родительский блок
<reference name="product.info">
<block type='googlethis/link' name="googlethis" as="googlethis" output="toHtml" template="catalog/product/googlethis.phtml"/>
</reference>
С помощью метода output="toHtml" в макете блок отображается в конце документа. Я тестировал с помощью
<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-тега
Я считаю, что вы не можете вывести блок, не имея его в показанном шаблоне. Поэтому, если вы создадите свое расширение поверх создания своего блока, вам нужно вызвать его в шаблоне, где вы хотите. К сожалению, это означает, что кто-то может добавить ваше расширение на свой веб-сайт, и если он создал свою собственную копию файла шаблона, в который добавлен ваш блок, потому что он хотел изменить его в своей теме, ваш блок там не будет отображаться. Им придется разобраться сами, что вашему модулю нужна модификация шаблона, и сами внесите изменения в свой собственный шаблон.
Блок может выводиться без вызова в шаблоне, если вы добавите к нему атрибут output="toHtml"
, но, как указывали некоторые другие, это приведет к отображению блока после тега </html>
. Это нормально, потому что output="toHtml"
- это то, что заставляет работать корневой блок. Корневой блок не может быть включен в шаблон, поскольку у него нет родителя, поэтому он использует output="toHtml"
атрибут, и это заставляет его проявиться. Это работает, потому что, когда Magento отображает свой макет (создает HTML страницы), он вызывает метод getOutput() класса Mage_Core_Model_Layout, и этот метод действительно просто получает все блоки, у которых есть параметр вывода, и выводит их на странице 1 на 1. Обычно у вас должно быть только 2 таких блока, root и "core_profiler". (да, это означает, что профилировщик будет отображаться после закрывающего HTML-тега).
Я нашел элегантное решение с помощью Observer и написал пост в блоге компании: http://www.fxplabs.com.br/blog/instanciando-blocos-em-qualquer-lugar-magento/
Перевод на английский: