Magento 2:「名前」のないブロックのテンプレートを変更する方法


10

カスタムテンプレートでブロックのテンプレートを上書きするように変更したい。ただし、「名前」はなく、「as」のみがあります。私がオーバーライドしたいのは:

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

回答:


8

レイアウトエイリアスを持つテンプレートを上書きする方法。

この回答は考えられる例です。これに従って、ALIASテンプレートをオーバーライドできます。

私は2つのサンプルモジュールを作成Vendor_Moduleし、エイリアステンプレートを使用してレイアウトしましたVendortwo_Moduletwo。このエイリアスをモジュールでオーバーライドしています。

モジュールを作成する手順を知っていると仮定します。モジュール全体の作成は投稿していません。

モジュール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>

モジュール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>

キャッシュを削除した後、http:// localhost / magento210 / module / test / testを実行します

エイリアステンプレートは、 Vendortwo_Moduletwo two/twoalias.phtml

ここに画像の説明を入力してください


それで、これはそのエイリアスによってブロックを上書きしていますか?それを上書きしたくないが、その後に別のブロックを追加したい場合はどうなりますか?
ジャニスElmeris

3

これは、ハックなしで適切に行う方法です。

OPの使用例は調べませんでしたが、カート内のレンダラーを変更できる必要がありました。問題は、OPの場合と同様に、Magento_Checkoutモジュールがレンダラーに名前を提供しないことです。つまり、それらは参照できず、従来の方法または文書化された方法を使用してテンプレートが変更されます。しかし、少し調べてみると、Magento2がレイアウトXMLで直接提供するツールを使用してそれを行う方法を発見しました。

Magento\Sales\Block\Items\AbstractItemsブロック内など、この同じアプローチが機能する他の場所があることに注意してください。Magento_CheckoutそしてMagento_Salesモジュールは、アイテムレンダラーの最も利用して2つですので、名前のないブロックのテンプレートを変更するには、誰かがつながるクエリのこのカバーは、多くの。これが投稿された理由は、チェックアウトまたは販売モジュールでレンダラーテンプレートを変更する方法を探している他の人の必然性のためです。

最初にソリューションを提供し、次にそれが機能する理由を知りたい人のために詳細に説明します。

解決

以下をcheckout_cart_index.xmlレイアウトファイルに追加します。

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

モジュール名とパスは、コードベースを反映するように変更する必要があることに注意してください。

説明

これoverridden_templatesは、デフォルトでは定義されていないブロックデータを活用することで機能します。

ではMagento_Checkoutcheckout_cart_index.xmlレイアウトファイルは次のブロックを定義します。

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

次に、これらのレンダラーをcheckout_cart_item_renderers.xmlレイアウトファイルでいくつか定義します。

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

残念ながら、それらはそれぞれエイリアス、defaultおよびsimpleで参照できません。

ただし、Magento\Checkout\Block\Cart\Gridという名前checkout.cart.formでレンダラーの親であるBlock を見るgetItemHtmlと、関連付けられているテンプレートのメソッドへの呼び出しがあることがわかりますcart/form.phtml。次に、そのメソッドはを呼び出しますgetItemRenderer。これらのメソッドはどちらも、Gridの親クラスで定義されていAbstractBlockます。これはoverridden_templatesデータが使用される場所です:

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

この知識があれば、Magento2のarguments構文を使用して、レイアウトXMLからのデータをブロックに入力することは簡単です。


1
これは真の解決策として受け入れられるべきです。シンプルで効果的。適切なMagento2の方法。素晴らしい説明。ありがとうございました!
iva 2018

2

私の解決策は普遍的なものではなく、「ダーティーハック」ですが、場合によっては役立つことがあります。私のサンプルは、フロントエンドレンダラー用であり、adminhtml用ではありません(同じはずです)。

\Magento\Framework\Data\Structure::getChildId条件「$ parentId == 'checkout.cart.item.renderers'」でブレークポイントを設定します(これは、checkout_cart_item_renderers.xmlレイアウトで確認できるように、親ブロックの名前です)。すべての子ブロックには、独自の(計算された)名前があります。

ここに画像の説明を入力してください

モジュールのレイアウト更新でこの名前を使用します。

    <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
これを見ている人にとっては、それを高慢に見つめても、これは転倒することに注意してください。カードで家を建てないでください。これらの数値は保証されていません。
danemacmillan

0

ここで私の答えを参照してください:https : //magento.stackexchange.com/a/239387/14403

私はそれがあなたにとって最も効果的な解決策であると信じています。ソリューションには、名前のみのエイリアスを持たないブロック/テンプレートを上書きすることが含まれます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.