Magento 2: Alterando o modelo de um bloco

52

No Magento 1, como desenvolvedor de módulos, é possível alterar o modelo de um bloco usando o código XML de layout, algo como isto

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

e adicionando seu modelo ao tema base.

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

É possível, como desenvolvedor de módulos, fazer algo semelhante no Magento 2? Ou seria necessário usar o código XML ou PHP do layout para remover o bloco em que estou interessado e inserir um novo bloco com um modelo diferente (cuja classe estende a classe de bloco original)

Sei que poderia criar um tema personalizado que substitui um modelo, mas estou interessado em criar um módulo que altere o modelo padrão, mas ainda permita que um tema personalizado substitua esse modelo.

Alan Storm
fonte

Respostas:

60

Obviamente, é possível:

<referenceBlock name="copyright">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Dfr_Backend::page/copyright.phtml</argument>
    </action>
</referenceBlock>
Mage2.PRO
fonte
Você pode explicar os passos Como posso alterar o layout, na verdade eu quiser atualizar o suplemento para addtocart.phtml arquivo de acordo com a configuração do sistema e também deseja atualizar isso usando módulo personalizado
Deepak Mankotia
5
Solução de Kandy não funcionou para mim, mas este sim
csmarvz
Alterei o modelo do nome do bloco "customer_account_dashboard_top" <body> <referenceBlock name = "customer_account_dashboard_top"> <action method = "setTemplate"> <argument name = "template" xsi: type = "string"> Namespace_Modulename :: order /recentorder.phtml </ argumento> </ action> </ referenceBlock> </ body>" mas não começar o trabalho, verifique o e deixe-me saber os seus comentários
Senthil
43

O nó de ação está obsoleto, mas você pode usar argumentos de bloco

<referenceBlock name="block_to_change">
    <arguments>
        <argument name="template" xsi:type="string">[Vendor]_[Module]::/path/to/template.phtml</argument>
    </arguments>
</referenceBlock>
KAndy
fonte
Você pode explicar os passos Como posso alterar o layout, na verdade eu quiser atualizar o suplemento de addtocart.phtmlarquivo de acordo com a configuração do sistema e também deseja atualizar isso usando módulo personalizado
Deepak Mankotia
4
Obrigado - vou deixar aqui uma referência a um relatório de bug aqui github.com/magento/magento2/issues/3356 - o método publicado nesta resposta, embora possivelmente a maneira futura de fazer as coisas, ainda não funcione como anunciado
Kristof em Fooman 21/03
2
@KAndy O seu exemplo de código está 100% correto? Eu tentei isso e não consigo fazê-lo funcionar de forma alguma. A outra resposta do @ Mage2.PRO (que usa <action method='setTemplate'>) funciona sem problemas.
Maginfortis
11
Isso não funciona. Resposta aceita faz embora.
Milan Simek
29

Para entender a diferença entre <arguments>e <action>você deve entender como os construtores dos objetos Magento 2 funcionam. Se você substituir um construtor no Magento, sempre obterá um $data-parameterque é uma matriz. Esses são os dados fornecidos nos arquivos XML e traduzidos para o interno $_data-arrayde \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;
}

No entanto, no caso de um modelo, se setTemplate()for usado no pseudo construtor ( _construct(), sublinhado único), isso significa que ele $dataserá substituído, independentemente de estar definido no XML.

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

Nesse cenário, <action>é preferível, pois isso é executado após o construtor e pseudo construtor.

<referenceBlock name="catalog.topnav">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Foo_Bar::buzz.phtml</argument>
    </action>
</referenceBlock> 
Giel Berkers
fonte
10

O seguinte funcionou para mim no 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>

Nota: se você estiver usando um módulo personalizado para alterar o modelo de um núcleo e estiver ficando louco porque o código anterior cortado não funciona, verifique se o seu módulo está carregado após o módulo principal que você está tentando alterar (module.xml) e se você executado bin/magento setup:upgrade:)

diazwatson
fonte
Esta é a maneira mais limpa na minha opinião.
Ben Crook
2

Não sei por que, mas acho que é o melhor:

<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>
Aivoris
fonte
1
<referenceBlock name="sales.order.items.renderers.default" template="Foo_Bar::sales/order/items/renderer/default.phtml"/>

Isso funcionará apenas se seu bloco não tiver sido substituído antes de usar o setTemplatemétodo Magento 2.2.xe superior.

AleksLi
fonte