Магенто. Вставить блок в другой без изменения кода шаблона


Я пытался найти решение, но безрезультатно. Моя задача - написать модуль. Он должен вставить некоторый 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() ?

Author: Yaroslav, 2011-05-18

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'); ?>

Как я уже сказал, это не подходит для каждой ситуации, и это не невероятно элегантно, но это работает.

Джон

 21
Author: Jon, 2011-05-26 11:16:43

Нет, универсального способа добавить ваш блок в любой другой блок не существует. Причина, по которой это иногда работает для вас, заключается в том, что есть некоторые типы блоков, которые просто перечисляют своих потомков (core/text_list является одним из них), и некоторые шаблоны вручную делают то же самое (используя $this->getChild()).

Если вы хотите добавить свой блок под блоком, который не соответствует ни одному из этих критериев, вам нужно будет изменить шаблон, чтобы повторить этот блок.

 3
Author: Joseph Mastey, 2011-05-18 11:25:06

Вы можете попробовать добавить в xml - следующий метод вывод="toHtml" - поместит блок в родительский блок , но...

<reference name="product.info">
    <block type='googlethis/link' name="googlethis" output="to Html" template="catalog/product/googlethis.phtml"/>
</reference>
 2
Author: Magefast, 2012-05-26 12:44:33

Это возможно путем добавления в xml - следующий метод вывод="toHtml" - поместит блок в родительский блок

<reference name="product.info">
    <block type='googlethis/link' name="googlethis" as="googlethis" output="toHtml" template="catalog/product/googlethis.phtml"/>
</reference>
 2
Author: naveenos, 2014-01-31 12:05:45

С помощью метода 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-тега

 1
Author: Will, 2012-07-11 18:12:55

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

Блок может выводиться без вызова в шаблоне, если вы добавите к нему атрибут output="toHtml", но, как указывали некоторые другие, это приведет к отображению блока после тега </html>. Это нормально, потому что output="toHtml" - это то, что заставляет работать корневой блок. Корневой блок не может быть включен в шаблон, поскольку у него нет родителя, поэтому он использует output="toHtml" атрибут, и это заставляет его проявиться. Это работает, потому что, когда Magento отображает свой макет (создает HTML страницы), он вызывает метод getOutput() класса Mage_Core_Model_Layout, и этот метод действительно просто получает все блоки, у которых есть параметр вывода, и выводит их на странице 1 на 1. Обычно у вас должно быть только 2 таких блока, root и "core_profiler". (да, это означает, что профилировщик будет отображаться после закрывающего HTML-тега).

 0
Author: PVL, 2016-11-01 15:04:57

Я нашел элегантное решение с помощью Observer и написал пост в блоге компании: http://www.fxplabs.com.br/blog/instanciando-blocos-em-qualquer-lugar-magento/

Перевод на английский:

Http://translate.google.com/translate?sl=pt&tl=en&js=n&prev=_t&hl=pt-BR&ie=UTF-8&eotf=1&u=http%3A%2F%2Fwww.fxplabs.com.br%2Fblog%2Finstanciando-blocos-em-qualquer-lugar-magento%2F

 -2
Author: Ayrton Weiss, 2013-04-02 02:33:57