Magento 2: Як змінити шаблон блоку без "імені"


10

Я хочу змінити, щоб замінити шаблон блоку зі своїм спеціальним шаблоном. Але воно не має "імені", воно має лише "як". Я хочу змінити це:

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

Відповіді:


8

Як замінити шаблон із макетом ALIAS.

Ця відповідь є можливим прикладом, ви можете слідувати за цим, щоб змінити шаблон ALIAS.

Я створив два приклади модулів, Vendor_Moduleмає макет із шаблоном псевдоніму, ми переосмислюємо цей псевдонім Vendortwo_Moduletwoмодулем.

Припустимо, ви знаєте кроки по створенню модуля, я не розміщую повідомлення про створення всього модуля.

Модуль 1

\ app \ code \ Постачальник \ Модуль \ тощо \ 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 \ Постачальник \ Модуль \ 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 \ тощо \ 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

введіть тут опис зображення


Отже, чи це перекриття блоку своїм псевдонімом? Що робити, якщо я не хочу переосмислити його, але додати ще один блок після нього?
Jānis Elmeris

3

Це як зробити це правильно і без злому.

Я не шукав випадку використання ОП, але мені потрібно було змінити рендері в кошику. Проблема полягає в тому, що, як і у випадку з ОП, Magento_Checkoutмодуль не надає імена рендерам, а це означає, що на них не можна посилатися, а їх шаблони змінюватись традиційними або документованими методами. Однак, після декількох випробовувань, я дізнався, як це зробити за допомогою інструментів Magento2 надає нам безпосередньо в макет XML.

Зауважте, що є й інші місця, де працює цей самий підхід, як, наприклад, у Magento\Sales\Block\Items\AbstractItemsблоці. Magento_CheckoutІ Magento_Salesмодулі є двома , які роблять максимально використовувати візуалізації елементів, так це охоплює багато з запитів , які привели б до кого - то зміни шаблону блоку без імені. Причина цього була розміщена через те, що інші люди шукають, як змінити шаблони рендерінгу в касах або модулях продажу.

Я спершу надам рішення, а потім детально поясню його всім, хто хоче знати, чому воно працює.

Рішення

Додайте до 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_Checkout, то checkout_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, і є батьком з рендерів, можна відзначити , що є виклик getItemHtmlметоду в шаблоні пов'язаного, cart/form.phtml. Потім цей метод викликає getItemRenderer. Обидва ці методи визначені в Grid«S батьківського класу, 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);
}

З огляду на це знання, заповнення блоку даними з макета XML просте, використовуючи argumentsсинтаксис Magento2 .


1
Це слід сприймати як справжнє рішення. Простий і ефективний. Правильний Magento2 спосіб. Чудове пояснення. Дякую!
iva

2

Моє рішення не є універсальним, воно є "брудним злом", але воно може бути корисним у певних випадках. Мій зразок призначений для фронтенд-рендерінга, а не для адміністратора (я думаю, він повинен бути таким же).

Точка перерви у програмі \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

Я вважаю, що це рішення, яке найкраще підійде для вас. Рішення включає переосмислення будь-якого блоку / шаблону, який не має лише імені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.