Magento 2: So ändern Sie die Vorlage eines Blocks ohne "Name"


9

Ich möchte ändern, um die Vorlage eines Blocks mit meiner benutzerdefinierten Vorlage zu überschreiben. Aber es hat keinen "Namen", es hat nur ein "wie". Das, was ich überschreiben möchte, ist:

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

Antworten:


7

So überschreiben Sie eine Vorlage mit Layout-ALIAS.

Diese Antwort ist ein mögliches Beispiel. Sie können dies befolgen, um die ALIAS-Vorlage zu überschreiben.

Ich habe zwei Beispielmodule erstellt, Vendor_Modulehat ein Layout mit Alias-Vorlage. Wir überschreiben diesen Alias ​​nach Vendortwo_ModuletwoModul.

Angenommen, Sie kennen die Schritte zum Erstellen eines Moduls. Ich veröffentliche nicht die gesamte Modulerstellung.

Modul 1

\ app \ code \ Vendor \ Module \ etc \ frontend \ route.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>

Modul 2

\ app \ code \ Vendortwo \ Moduletwo \ etc \ frontend \ route.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>

Nach dem Entfernen des Cache starte ich http: // localhost / magento210 / module / test / test

Die Alias-Vorlage wird von überschrieben Vendortwo_Moduletwo two/twoalias.phtml

Geben Sie hier die Bildbeschreibung ein


Überschreibt dies einen Block durch seinen Alias? Was ist, wenn ich es nicht überschreiben, sondern einen weiteren Block hinzufügen möchte?
Jānis Elmeris

3

So geht's richtig und ohne Hacks.

Ich habe den Anwendungsfall von OP nicht nachgeschlagen, aber ich musste in der Lage sein, die Renderer im Warenkorb zu ändern. Das Problem ist, dass das Magento_CheckoutModul , wie im Fall von OP, keine Namen für die Renderer bereitstellt, was bedeutet, dass sie nicht referenziert und ihre Vorlagen mit herkömmlichen oder dokumentierten Methoden geändert werden können. Nach einigem Hin und Her entdeckte ich jedoch, wie man es mit den Tools macht, die Magento2 uns direkt im Layout-XML zur Verfügung stellt.

Beachten Sie, dass es andere Stellen gibt, an denen der gleiche Ansatz funktioniert, z. B. im Magento\Sales\Block\Items\AbstractItemsBlock. Die Module Magento_Checkoutund Magento_Salessind die beiden, die Element-Renderer am häufigsten verwenden. Daher werden viele der Abfragen behandelt, die dazu führen würden, dass jemand die Vorlage eines Blocks ohne Namen ändert. Der Grund, warum dies veröffentlicht wurde, liegt in der Unvermeidlichkeit anderer, die nach Möglichkeiten zum Ändern von Renderer-Vorlagen in den Checkout- oder Verkaufsmodulen suchen.

Ich werde zuerst die Lösung bereitstellen und sie dann jedem ausführlich erklären, der wissen möchte, warum sie funktioniert.

Lösung

Fügen Sie der checkout_cart_index.xmlLayoutdatei Folgendes hinzu :

<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>

Beachten Sie, dass der Modulname und der Pfad geändert werden müssen, um Ihre Codebasis widerzuspiegeln.

Erläuterung

Dies funktioniert durch Nutzung der Blockdaten overridden_templates, die nicht standardmäßig definiert sind.

In Magento_Checkoutder checkout_cart_index.xmldefinierten Layout - Datei den folgenden Block:

<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>

Anschließend werden einige dieser Renderer in der checkout_cart_item_renderers.xmlLayoutdatei definiert:

<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>

Leider können sie nicht durch ihre Aliase defaultbzw. referenziert werden simple.

Wenn Sie sich jedoch den Magento\Checkout\Block\Cart\GridBlock ansehen, der benannt checkout.cart.formist und das übergeordnete Element der Renderer ist, können Sie feststellen, dass die getItemHtmlMethode in der zugehörigen Vorlage aufgerufen wird cart/form.phtml. Diese Methode ruft dann auf getItemRenderer. Beide Methoden sind in Gridder übergeordneten Klasse definiert AbstractBlock. Hier werden die overridden_templatesDaten verwendet:

/**
 * 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);
}

Mit diesem Wissen ist das Auffüllen des Blocks mit Daten aus Layout-XML mithilfe der Magento2- argumentsSyntax unkompliziert .


1
Dies sollte als die wahre Lösung akzeptiert werden. Einfach und effektiv. Richtiger Magento2-Weg. Tolle Erklärung. Danke!
iva

2

Meine Lösung ist nicht universell, es ist ein "schmutziger Hack", aber es kann in bestimmten Fällen nützlich sein. Mein Beispiel ist für den Frontend-Renderer, nicht für adminhtml (ich nehme an, es sollte dasselbe sein).

Richten Sie den Haltepunkt \Magento\Framework\Data\Structure::getChildIdmit der Bedingung " $ parentId == 'checkout.cart.item.renderers' " ein (dies ist ein Name für den übergeordneten Block, wie Sie im checkout_cart_item_renderers.xmlLayout sehen können). Alle untergeordneten Blöcke haben eigene (berechnete) Namen:

Geben Sie hier die Bildbeschreibung ein

Verwenden Sie diese Namen in der Layoutaktualisierung Ihres Moduls:

    <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
Wenn Sie sich das ansehen, sollten Sie sich darüber im Klaren sein, dass dies umfallen wird, wenn Sie es nur distanziert anstarren. Baue dein Haus nicht mit Karten. Diese Nummern sind nicht garantiert.
Danemacmillan

0

Bitte sehen Sie meine Antwort hier: /magento//a/239387/14403

Ich glaube, das ist die Lösung, die am besten für Sie funktioniert. Die Lösung umfasst das Überschreiben von Blöcken / Vorlagen, die keinen Alias ​​nur für Namen haben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.