Magento 2: Changer le modèle d'un bloc

52

Dans Magento 1, en tant que développeur de module, il est possible de modifier le modèle d'un bloc à l'aide d'un code XML de présentation, comme ceci

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

puis en ajoutant votre modèle au thème de base.

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

Est-il possible, en tant que développeur de module, de faire quelque chose de similaire dans Magento 2? Ou aurais-je besoin d'utiliser du code XML de présentation ou du code PHP pour supprimer le bloc qui m'intéresse et insérer un nouveau bloc avec un modèle différent (dont la classe étend celle de la classe de bloc d'origine)

Je sais que je pourrais créer un thème personnalisé qui remplace un modèle, mais je souhaiterais créer un module qui modifie le modèle par défaut, tout en permettant à un thème personnalisé de le remplacer.

Alan Storm
la source

Réponses:

60

Bien sur, c'est possible:

<referenceBlock name="copyright">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Dfr_Backend::page/copyright.phtml</argument>
    </action>
</referenceBlock>
Mage2.PRO
la source
Pouvez-vous expliquer les étapes comment puis-je changer la disposition, En fait, je veux mettre à jour le fichier add to addtocart.phtml en fonction de la configuration du système et je souhaite également le mettre à jour à l'aide d'un module personnalisé
Deepak Mankotia
5
La solution de KAndy n'a pas fonctionné pour moi, mais celle-ci oui
csmarvz
J'ai changé le modèle du nom de bloc "customer_account_dashboard_top" <body> <referenceBlock name = "customer_account_dashboard_top"> <action method = "setTemplate"> <argument name = "modèle" xsi: type = "string"> Namespace_Modulename :: order /recentorder.phtml </ argument> </ action> </ referenceBlock> </ body> "mais ça ne fonctionne pas, merci de vérifier et de me faire savoir vos commentaires
senthil
43

Le nœud d'action est obsolète, mais vous pouvez utiliser des arguments de blocage

<referenceBlock name="block_to_change">
    <arguments>
        <argument name="template" xsi:type="string">[Vendor]_[Module]::/path/to/template.phtml</argument>
    </arguments>
</referenceBlock>
KAndy
la source
Pouvez-vous expliquer les étapes comment puis-je changer la disposition, En fait, je veux mettre à jour l'ajout au addtocart.phtmlfichier en fonction de la configuration du système et je souhaite également le mettre à jour à l'aide d'un module personnalisé
Deepak Mankotia
4
Merci - je laisserai simplement une référence à un rapport de bogue ici github.com/magento/magento2/issues/3356 - la méthode publiée dans cette réponse, bien que la manière de procéder future, ne fonctionne pas encore comme annoncé
Kristof à Fooman
2
@KAndy Votre exemple de code est-il correct à 100%? J'ai essayé et je n'arrive pas à le faire fonctionner. L'autre réponse de @ Mage2.PRO (qui utilise <action method='setTemplate'>) fonctionne sans problème.
maginfortis
1
Ça ne marche pas. Réponse acceptée fait cependant.
Milan Simek
29

Pour comprendre la différence entre <arguments>et, <action>vous devez comprendre le fonctionnement des constructeurs d’objets Magento 2. Si vous substituez un constructeur dans Magento, vous obtiendrez toujours un $data-parameterqui est un tableau. Ce sont les données telles que fournies dans les fichiers XML et traduites en interne $_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;
}

Cependant, dans le cas d'un modèle, si setTemplate()est utilisé dans le pseudo constructeur ( _construct(), un soulignement simple), cela signifie que le $dataest remplacé, peu importe s'il est défini dans le XML.

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

Dans ce scénario, il <action>est préférable, car cela est exécuté après le constructeur & pseudo constructeur.

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

Ce qui suit a fonctionné pour moi dans 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>

Remarque: si vous utilisez un module personnalisé pour modifier le modèle d'un core et que vous vous énervez parce que le code précédemment coupé ne fonctionne pas, assurez-vous que votre module est chargé après le core que vous essayez de modifier (module.xml) et que vous le souhaitez. exécuté bin/magento setup:upgrade:)

Diazwatson
la source
C'est la manière la plus propre à mon avis.
Ben Crook
2

Je ne sais pas pourquoi, mais je trouve ce moyen d'être le meilleur:

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

Cela ne fonctionnera que si votre bloc n'a pas été écrasé avant d'utiliser la setTemplateméthode. Magento 2.2.x et supérieur.

AleksLi
la source