Answers:
如何覆盖具有布局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
这是正确执行且没有黑客攻击的方法。
我没有查找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
名为的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的数据填充块。
我的解决方案不是通用的,它是“肮脏的骇客”,但在某些情况下可能很有用。我的示例用于前端渲染器,而不用于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>
请在这里查看我的答案:https : //magento.stackexchange.com/a/239387/14403
我相信这是最适合您的解决方案。该解决方案包括覆盖没有唯一名称别名的任何块/模板。