Magento 2:如何更改没有“名称”的块的模板


10

我想更改为使用自定义模板覆盖块的模板。但是它没有“名称”,只有一个“ as”。我要覆盖的是:

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

Answers:


8

如何覆盖具有布局ALIAS的模板。

此答案是一个可能的示例,您可以按照此方法覆盖ALIAS模板。

我创建了两个示例模块,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

在此处输入图片说明


那么,这是通过其别名覆盖块吗?如果我不想覆盖它,但在它之后添加另一个块怎么办?
贾尼斯·埃默里斯(JānisElmeris)'17

3

这是正确执行且没有黑客攻击的方法。

我没有查找OP的用例,但是我需要能够修改购物车中的渲染器。问题是,就像在OP的情况下一样,该Magento_Checkout模块不向渲染器提供名称,这意味着它们无法被引用,并且其模板使用传统或有记载的方法进行更改。但是,经过一番探索之后,我发现了如何使用Magento2直接在布局XML中为我们提供的工具来执行此操作。

请注意,在其他地方也可以使用这种方法,例如在代码Magento\Sales\Block\Items\AbstractItems块中。在Magento_CheckoutMagento_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_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名为的Block,它是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);
}

有了这些知识,使用Magento2的arguments语法就可以很容易地用来自布局XML的数据填充块。


1
这应该被视为真正的解决方案。简单有效。正确的Magento2方式。很好的解释。谢谢!
iva

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.