Magento 2: Cambiar la plantilla de un bloque

52

En Magento 1, como desarrollador de módulos, es posible cambiar la plantilla de un bloque usando un código XML de diseño similar a este

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

y luego agregando su plantilla al tema base.

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

¿Es posible, como desarrollador de módulos, hacer algo similar en Magento 2? ¿O necesitaría usar código XML o PHP de diseño para eliminar el bloque que me interesa e insertar un nuevo bloque con una plantilla diferente (cuya clase extiende la clase de bloque original)

Sé que podría crear un tema personalizado que reemplace una plantilla, pero estoy interesado en crear un módulo que cambie la plantilla predeterminada, pero que aún permita que un tema personalizado reemplace esa plantilla.

Alan Storm
fuente

Respuestas:

60

Por supuesto, es posible:

<referenceBlock name="copyright">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Dfr_Backend::page/copyright.phtml</argument>
    </action>
</referenceBlock>
Mage2.PRO
fuente
¿Puede explicar los pasos Cómo se puede cambiar la disposición, en realidad yo quiero actualizar el complemento a addtocart.phtml archivo de acuerdo con la configuración del sistema y también quiero actualizar este módulo personalizado utilizando
Deepak Mankotia
55
La solución de KAndy no funcionó para mí, pero esta sí
csmarvz
He cambiado la plantilla del nombre de bloque "customer_account_dashboard_top" <body> <referenceBlock name = "customer_account_dashboard_top"> <action method = "setTemplate"> <argumento name = "template" xsi: type = "string"> Namespace_Modulename :: order /recentorder.phtml </argument> </action> </referenceBlock> </body> "pero no funciona, compruebe y hágame saber sus comentarios
enviado el
43

El nodo de acción está en desuso, pero puede usar argumentos de bloque

<referenceBlock name="block_to_change">
    <arguments>
        <argument name="template" xsi:type="string">[Vendor]_[Module]::/path/to/template.phtml</argument>
    </arguments>
</referenceBlock>
Kandy
fuente
¿Puede explicar los pasos Cómo se puede cambiar la disposición, en realidad yo quiero actualizar el complemento de addtocart.phtmlarchivo de acuerdo con la configuración del sistema y también quiero actualizar este módulo personalizado utilizando
Deepak Mankotia
44
Gracias. Dejaré una referencia a un informe de error aquí github.com/magento/magento2/issues/3356 : el método publicado en esta respuesta, aunque posiblemente la forma futura de hacer las cosas, aún no funciona como se anuncia
Kristof en Fooman
2
@KAndy ¿Es su código de ejemplo 100% correcto? Lo intenté y no puedo hacer que funcione de ninguna manera. La otra respuesta de @ Mage2.PRO (que usa <action method='setTemplate'>) funciona sin problemas.
maginfortis
1
Esto no funciona Sin embargo, la respuesta aceptada sí.
Milan Simek
29

Para comprender la diferencia entre <arguments>y <action>debe comprender cómo funcionan los constructores de objetos Magento 2. Si anula un constructor en Magento, siempre obtendrá un $data-parameterque es una matriz. Estos son los datos provistos en los archivos XML y traducidos al 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;
}

Sin embargo, en el caso de una plantilla, si setTemplate()se usa en el pseudoconstructor ( _construct(), subrayado simple), esto significa que $datase anula, sin importar si está configurado en el XML.

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

En ese escenario, <action>se prefiere, ya que esto se ejecuta después del constructor y pseudoconstructor.

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

Lo siguiente funcionó para mí en 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: si está utilizando un módulo personalizado para cambiar la plantilla de un núcleo y se está volviendo loco porque el código recortado anterior no funciona, asegúrese de que su módulo esté cargado después del módulo central que está intentando cambiar (module.xml) y usted ejecutado bin/magento setup:upgrade:)

diazwatson
fuente
Esta es la forma más limpia en mi opinión.
Ben Crook
2

No sé por qué, pero creo que esta es la mejor manera:

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

Esto funcionará solo si su bloque no se sobrescribió antes de usar el setTemplatemétodo. Magento 2.2.xy superior.

AleksLi
fuente