Magento 2: изменение шаблона блока

52

В Magento 1, как разработчик модуля, можно изменить шаблон блока, используя макет XML-кода примерно так:

<reference name="block_to_change">
    <action method="setTemplate">
        <param>/path/to/template.phtml</param>
    </action>
</reference>

а затем добавить свой шаблон в базовую тему.

app/design/frontend/base/default/template/path/to/template.phtml

Возможно ли, как разработчик модуля, сделать что-то подобное в Magento 2? Или мне нужно использовать макет XML или PHP-код, чтобы удалить интересующий меня блок, и вставить новый блок с другим шаблоном (класс которого расширяет класс исходного блока)

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

Алан Сторм
источник

Ответы:

60

Конечно, это возможно:

<referenceBlock name="copyright">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Dfr_Backend::page/copyright.phtml</argument>
    </action>
</referenceBlock>
Mage2.PRO
источник
Можете ли вы объяснить шаги, как я могу изменить макет, На самом деле я хочу обновить файл add to addtocart.phtml в соответствии с конфигурацией системы, а также хочу обновить его с помощью пользовательского модуля
Deepak Mankotia
5
Решение KAndy не сработало для меня, но вот это да
csmarvz
Я изменил шаблон имени блока "customer_account_dashboard_top" <body> <referenceBlock name = "customer_account_dashboard_top"> <метод действия = "setTemplate"> <аргумент name = "template" xsi: type = "string"> Namespace_Modulename :: order /recentorder.phtml </ arguments> </ action> </ referenceBlock> </ body> ", но работа не получается, пожалуйста, проверьте и дайте мне знать ваши комментарии
senthil
43

Узел действия устарел, но вы можете использовать аргументы блока

<referenceBlock name="block_to_change">
    <arguments>
        <argument name="template" xsi:type="string">[Vendor]_[Module]::/path/to/template.phtml</argument>
    </arguments>
</referenceBlock>
Канди
источник
Можете ли вы объяснить шаги, как я могу изменить макет? На самом деле я хочу обновить addtocart.phtmlфайл add в соответствии с конфигурацией системы, а также хочу обновить его с помощью пользовательского модуля
Deepak Mankotia
4
Спасибо - я просто оставлю ссылку на сообщение об ошибке здесь github.com/magento/magento2/issues/3356 - метод, опубликованный в этом ответе, хотя, возможно, будущий способ сделать что-то еще, не работает так, как рекламируется
Кристоф в Fooman
2
@ КАndy Ваш пример кода на 100% правильный? Я попробовал это, и я никак не могу заставить его работать. Другой ответ от @ Mage2.PRO (который использует <action method='setTemplate'>) работает без проблем.
maginfortis
1
Это не работает Принятый ответ делает все же.
Милан Симек
29

Чтобы понять разницу между <arguments>и <action>вы должны понять, как работают конструкторы объектов Magento 2. Если вы переопределите конструктор в Magento, вы всегда получите $data-parameterмассив, представляющий собой массив. Это данные, представленные в файлах XML и переведенные во внутреннюю $_data-arrayчасть \Magento\Framework\DataObject:

<referenceBlock name="catalog.topnav">
    <arguments>
        <argument name="template" xsi:type="string">Foo_Bar::buzz.phtml</argument>
    </arguments>
</referenceBlock>    

...

public function __construct(array $data = [])
{
    // $_data is populated with the arguments from XML:
    // so $_data['template'] is now 'Foo_Bar::buzz.phtml'
    $this->_data = $data;
}

Однако в случае шаблона, если setTemplate()он используется в псевдо-конструкторе (с _construct()одним подчеркиванием), это означает, что $dataон переопределяется, независимо от того, установлен ли он в XML.

public function _construct()
{
    $this->setTemplate('foo/bar.phtml');
}

В этом случае <action>предпочтительнее, так как это выполняется после конструктора и псевдо-конструктора.

<referenceBlock name="catalog.topnav">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Foo_Bar::buzz.phtml</argument>
    </action>
</referenceBlock> 
Гиль Беркерс
источник
10

Следующее работает для меня в Magento EE 2.2.3

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="core.module.block.name" template="[Vendor]_[Module]::path/to/your/template.phtml" />
    </body>
</page>

Примечание: если вы используете пользовательский модуль для изменения шаблона ядра, и вы сходите с ума, потому что предыдущий фрагмент кода не работает, убедитесь, что ваш модуль загружен после модуля ядра, который вы пытаетесь изменить (module.xml), и вы выполнено bin/magento setup:upgrade:)

diazwatson
источник
Это самый чистый способ на мой взгляд.
Бен Крук
2

Я не знаю почему, но я считаю этот способ лучшим:

<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>
Aivoris
источник
1
<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>

Это будет работать, только если ваш блок не был перезаписан перед использованием setTemplateметода. Magento 2.2.x и выше.

AleksLi
источник