Magento 2: Comment changer le modèle d'un bloc sans «nom»


10

Je souhaite modifier pour remplacer le modèle d'un bloc par mon modèle personnalisé. Mais il n'a pas de "nom", il n'a qu'un "comme". Celui que je veux remplacer est:

<block class="Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer"
       as="default"
       template="order/view/items/renderer/default.phtml"/>

Réponses:


8

Comment remplacer un modèle ayant une disposition ALIAS.

Cette réponse est un exemple possible, vous pouvez suivre ceci pour remplacer le modèle ALIAS.

J'ai créé deux exemples de modules, Vendor_Modulea une disposition avec un modèle d'alias, nous remplaçons cet alias par Vendortwo_Moduletwomodule.

Supposons que vous connaissez les étapes pour créer un module, je ne publie pas la création de module entière.

Module 1

\ app \ code \ Vendor \ Module \ etc \ frontend \ routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="module" frontName="module">
            <module name="Vendor_Module" />
        </route>
    </router>
</config>

\ app \ code \ Vendor \ Module \ view \ frontend \ layout \ module_test_test.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>     
        <referenceContainer name="content">         
            <block class="Vendor\Module\Block\Test\Test" name="test_test" template="test/test.phtml">
                <block class="Vendor\Module\Block\Test\Test" as="testali" template="test/testali.phtml"/>
            </block>
        </referenceContainer>      
    </body>
</page>

Module 2

\ app \ code \ Vendortwo \ Moduletwo \ etc \ frontend \ routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="moduletwo" frontName="moduletwo">
            <module name="Vendortwo_Moduletwo" />
        </route>
    </router>
</config>

\ app \ code \ Vendortwo \ Moduletwo \ view \ frontend \ layout \ default.xml

<?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">
        <referenceBlock name="test_test">
            <block class="Vendortwo\Moduletwo\Block\Two\Two" as="testali" template="two/twoalias.phtml"/>
        </referenceBlock>
</page>

Après avoir supprimé le cache, j'exécute http: // localhost / magento210 / module / test / test

Le modèle d'alias est remplacé par Vendortwo_Moduletwo two/twoalias.phtml

entrez la description de l'image ici


Alors, cela remplace-t-il un bloc par son alias? Que faire si je ne veux pas le remplacer mais ajouter un autre bloc après?
Jānis Elmeris

3

Voici comment le faire correctement et sans piratage.

Je n'ai pas recherché le cas d'utilisation d'OP, mais j'avais besoin de pouvoir modifier les moteurs de rendu dans le panier. Le problème est que, comme dans le cas d'OP, le Magento_Checkoutmodule ne fournit pas de noms aux moteurs de rendu, ce qui signifie qu'ils ne peuvent pas être référencés et leurs modèles modifiés à l'aide de méthodes traditionnelles ou documentées. Cependant, après quelques recherches, j'ai découvert comment le faire en utilisant les outils que Magento2 nous fournit directement dans la mise en page XML.

Notez qu'il existe d'autres endroits où cette même approche fonctionne, comme dans le Magento\Sales\Block\Items\AbstractItemsbloc. Les modules Magento_Checkoutet Magento_Salessont les deux qui utilisent le plus les rendus d'élément, donc cela couvre la plupart des requêtes qui conduiraient quelqu'un à changer le modèle d'un bloc sans nom. La raison pour laquelle cela a été publié est à cause de l'inévitabilité de ceux qui cherchent à modifier les modèles de rendu dans les modules de paiement ou de vente.

Je vais d'abord fournir la solution, puis l'expliquer en détail à tous ceux qui veulent savoir pourquoi cela fonctionne.

Solution

Ajoutez ce qui suit au checkout_cart_index.xmlfichier de mise en page:

<referenceBlock name="checkout.cart.form">
    <arguments>
        <argument name="overridden_templates" xsi:type="array">
            <item name="default" xsi:type="string">LinusShops_Moneymaker::Magento_Checkout/cart/item/default.phtml</item>
            <item name="simple" xsi:type="string">LinusShops_Moneymaker::Magento_Checkout/cart/item/simple.phtml</item>
            <item name="configurable" xsi:type="string">LinusShops_Moneymaker::Magento_Checkout/cart/item/configurable.phtml</item>
        </argument>
    </arguments>
</referenceBlock>

Notez que le nom et le chemin du module doivent être modifiés pour refléter votre base de code.

Explication

Cela fonctionne en exploitant les overridden_templatesdonnées de bloc, qui ne sont pas définies par défaut.

Dans Magento_Checkout, le checkout_cart_index.xmlfichier de mise en page définit le bloc suivant:

<block class="Magento\Checkout\Block\Cart\Grid" name="checkout.cart.form" as="cart-items" template="cart/form.phtml" after="cart.summary">
    <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.item.renderers" as="renderer.list"/>
    <block class="Magento\Framework\View\Element\Text\ListText" name="checkout.cart.order.actions"/>
</block>

Il définit ensuite quelques-uns de ces moteurs de rendu dans le checkout_cart_item_renderers.xmlfichier de disposition:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="checkout_item_price_renderers"/>
    <body>
        <referenceBlock name="checkout.cart.item.renderers">
            <block class="Magento\Checkout\Block\Cart\Item\Renderer" as="default" template="cart/item/default.phtml">
                <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions" name="checkout.cart.item.renderers.default.actions" as="actions">
                    <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions\Edit" name="checkout.cart.item.renderers.default.actions.edit" template="Magento_Checkout::cart/item/renderer/actions/edit.phtml"/>
                    <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions\Remove" name="checkout.cart.item.renderers.default.actions.remove" template="Magento_Checkout::cart/item/renderer/actions/remove.phtml"/>
                </block>
            </block>
            <block class="Magento\Checkout\Block\Cart\Item\Renderer" as="simple" template="cart/item/default.phtml">
                <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions" name="checkout.cart.item.renderers.simple.actions" as="actions">
                    <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions\Edit" name="checkout.cart.item.renderers.simple.actions.edit" template="Magento_Checkout::cart/item/renderer/actions/edit.phtml"/>
                    <block class="Magento\Checkout\Block\Cart\Item\Renderer\Actions\Remove" name="checkout.cart.item.renderers.simple.actions.remove" template="Magento_Checkout::cart/item/renderer/actions/remove.phtml"/>
                </block>
            </block>
        </referenceBlock>
    </body>
</page>

Malheureusement, ils ne peuvent pas être référencés par leurs alias defaultet simplerespectivement.

Cependant, en regardant dans le Magento\Checkout\Block\Cart\Gridbloc, qui est nommé checkout.cart.form, et est le parent des équarrisseurs, on peut noter qu'il ya un appel à la getItemHtmlméthode dans le modèle associé, cart/form.phtml. Cette méthode appelle ensuite getItemRenderer. Sont définis ces deux méthodes dans Gridla classe parente de », AbstractBlock. C'est là que les overridden_templatesdonnées sont utilisées:

/**
 * Retrieve item renderer block
 *
 * @param string|null $type
 * @return \Magento\Framework\View\Element\Template
 * @throws \RuntimeException
 */
public function getItemRenderer($type = null)
{
    if ($type === null) {
        $type = self::DEFAULT_TYPE;
    }
    $rendererList = $this->_getRendererList();
    if (!$rendererList) {
        throw new \RuntimeException('Renderer list for block "' . $this->getNameInLayout() . '" is not defined');
    }
    $overriddenTemplates = $this->getOverriddenTemplates() ?: [];
    $template = isset($overriddenTemplates[$type]) ? $overriddenTemplates[$type] : $this->getRendererTemplate();
    return $rendererList->getRenderer($type, self::DEFAULT_TYPE, $template);
}

Avec ces connaissances, le remplissage du bloc avec des données provenant de la mise en page XML est simple en utilisant la argumentssyntaxe de Magento2 .


1
Cela devrait être accepté comme la vraie solution. Simple et efficace. Bonne façon Magento2. Grande explication. Je vous remercie!
iva

2

Ma solution n'est pas universelle, c'est un "hack sale" mais elle peut être utile dans certains cas. Mon exemple est pour le rendu frontal, pas pour adminhtml (je suppose que ce devrait être le même).

Configurez le point d'arrêt \Magento\Framework\Data\Structure::getChildIdavec la condition " $ parentId == 'checkout.cart.item.renderers' " (c'est un nom pour le bloc parent comme vous pouvez le voir dans la checkout_cart_item_renderers.xmldisposition). Tous les blocs enfants ont leurs propres noms (calculés):

entrez la description de l'image ici

Utilisez ces noms dans la mise à jour de la mise en page de votre module:

    <referenceBlock name="checkout.cart.item.renderers_schedule_block4">
        <action method="setTemplate">
            <argument name="template" xsi:type="string">Vendor_Module::cart/item/default.phtml</argument>
        </action>
    </referenceBlock>

2
Pour quiconque regarde cela, sachez que cela tombera si vous ne faites que lui donner un regard distant. Ne construisez pas votre maison avec des cartes. Ces chiffres ne sont pas garantis.
danemacmillan

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.