Magento 2: Cara mengganti template blok tanpa "nama"


10

Saya ingin mengubah untuk mengganti template blok dengan template kustom saya. Tetapi tidak memiliki "nama", itu hanya memiliki "sebagai". Yang ingin saya timpa adalah:

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

Jawaban:


8

Cara mengganti template yang memiliki tata letak ALIAS.

Jawaban ini adalah contoh yang mungkin, Anda dapat mengikuti ini untuk mengganti template ALIAS.

Saya telah membuat dua contoh modul, Vendor_Modulememiliki tata letak dengan templat alias, Kami mengganti alias ini dengan Vendortwo_Moduletwomodul.

Asumsikan Anda tahu langkah-langkah untuk membuat modul, saya tidak memposting seluruh pembuatan modul.

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

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

Setelah menghapus cache, saya jalankan http: // localhost / magento210 / module / test / test

Templat alias ditimpa oleh Vendortwo_Moduletwo two/twoalias.phtml

masukkan deskripsi gambar di sini


Jadi, apakah ini mengganti blok dengan aliasnya? Bagaimana jika saya tidak ingin menimpanya tetapi menambahkan blok lain setelahnya?
Jānis Elmeris

3

Ini adalah cara melakukannya dengan benar, dan tanpa peretasan.

Saya tidak mencari use case OP, tetapi saya harus dapat memodifikasi renderers di dalam troli. Masalahnya adalah, seperti dalam kasus OP, theMagento_Checkout modul tidak memberikan nama kepada penyaji, yang berarti mereka tidak dapat direferensikan dan template mereka diubah menggunakan metode tradisional atau terdokumentasi. Namun, setelah melakukan sleuthing, saya menemukan cara melakukannya menggunakan alat yang disediakan Magento2 secara langsung dalam tata letak XML.

Perhatikan bahwa ada tempat lain di mana pendekatan yang sama ini bekerja, seperti di Magento\Sales\Block\Items\AbstractItemsblok. The Magento_Checkoutdan Magento_Salesmodul adalah dua yang membuat sebagian besar menggunakan penyaji item, sehingga mencakup ini banyak pertanyaan yang akan mengakibatkan seseorang untuk mengubah template blok tanpa nama. Alasan ini diposkan adalah karena tidak terhindarkannya orang lain yang mencari cara memodifikasi templat renderer di checkout atau modul penjualan.

Saya akan memberikan solusinya terlebih dahulu, dan kemudian menjelaskannya secara terperinci bagi siapa saja yang ingin tahu mengapa itu bekerja.

Larutan

Tambahkan berikut ini ke checkout_cart_index.xmlfile tata letak:

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

Perhatikan bahwa nama modul dan jalur perlu dimodifikasi untuk mencerminkan basis kode Anda.

Penjelasan

Ini berfungsi dengan memanfaatkan overridden_templatesdata blok, yang tidak didefinisikan secara default.

Di Magento_Checkout, checkout_cart_index.xmlfile layout mendefinisikan blok berikut:

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

Itu kemudian mendefinisikan beberapa renderers dalam checkout_cart_item_renderers.xmlfile tata letak:

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

Sayangnya, mereka tidak dapat dirujuk oleh alias mereka, defaultdan simple, masing-masing.

Namun, melihat ke dalam Magento\Checkout\Block\Cart\GridBlok, yang dinamai checkout.cart.form, dan merupakan induk dari penyaji, dapat dicatat bahwa ada panggilan ke getItemHtmlmetode dalam templat terkait cart/form.phtml,. Metode itu kemudian memanggil getItemRenderer. Kedua metode ini didefinisikan dalam Gridkelas induk AbstractBlock,. Di sinilah overridden_templatesdata digunakan:

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

Dengan pengetahuan ini, mengisi blok dengan data dari tata letak XML secara langsung menggunakan argumentssintaks Magento2 .


1
Ini harus diterima sebagai solusi sejati. Sederhana dan efektif. Cara Magento2 yang tepat. Penjelasan yang bagus. Terima kasih!
iva

2

Solusi saya tidak universal, ini adalah "hack kotor" tetapi dapat bermanfaat dalam kasus-kasus tertentu. Sampel saya adalah untuk renderer frontend, bukan untuk adminhtml (saya kira itu harus sama).

Setup break point \Magento\Framework\Data\Structure::getChildIddengan syarat " $ parentId == 'checkout.cart.item.renderers' " (ini adalah nama untuk blok induk seperti yang Anda lihat dalam checkout_cart_item_renderers.xmltata letak). Semua blok anak memiliki nama (dihitung) sendiri:

masukkan deskripsi gambar di sini

Gunakan nama ini di pembaruan tata letak modul Anda:

    <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
Bagi siapa pun yang melihat ini, sadarilah bahwa ini akan gagal jika Anda bahkan hanya menatapnya dengan pandangan menyendiri. Jangan membangun rumah Anda dengan kartu. Angka-angka itu tidak dijamin.
danemacmillan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.