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

\ Приложение \ код \ Vendor \ модуль \ и т.д. \ внешний интерфейс \ 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>

\ Приложение \ код \ Поставщик \ Module \ вид \ внешний интерфейс \ расположение \ 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

\ Приложение \ код \ Vendortwo \ Moduletwo \ и т.д. \ фронтенд \ 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>

\ Приложение \ код \ Vendortwo \ Moduletwo \ вид \ фронтенд \ расположение \ 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

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


Итак, переопределяет ли блок его псевдоним? Что если я не хочу переопределять это, а добавить еще один блок после него?
Янис Элмерис

3

Это как сделать это правильно и без взломов.

Я не искал сценарий использования OP, но мне нужно было иметь возможность изменять средства визуализации в корзине. Проблема заключается в том, что, как и в случае с OP, 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родительском классе 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. Отличное объяснение. Спасибо!
ива

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

Я считаю, что это решение, которое будет работать лучше для вас. Решение включает в себя переопределение любого блока / шаблона, который не имеет псевдонима только для имени.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.