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

#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 /

перевод на русский:

http://translate.google.com/translate?sl=ptamp;tl=enamp;js=namp;prev=_tamp;hl=pt-BRamp;ie=UTF-8amp;eotf=1amp;u=http://www.fxplabs.com.br/blog/instanciando-blocos-em-qualquer-lugar-magento/

Комментарии:

1. пожалуйста, напишите о своем ответе здесь вместо публикации ссылки, спасибо!