Magento 2: Cách thay đổi mẫu của một khối mà không cần tên


9

Tôi muốn thay đổi để ghi đè lên mẫu của khối bằng mẫu tùy chỉnh của mình. Nhưng nó không có "tên", nó chỉ có "như". Cái tôi muốn ghi đè là:

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

Câu trả lời:


7

Làm thế nào để ghi đè một mẫu có bố cục ALIAS.

Câu trả lời này là một ví dụ có thể, bạn có thể làm theo điều này để ghi đè lên mẫu ALIAS.

Tôi đã tạo hai mô-đun mẫu, Vendor_Modulecó bố cục với mẫu bí danh, Chúng tôi đang ghi đè bí danh này bằng Vendortwo_Moduletwomô-đun.

Giả sử bạn biết các bước để tạo mô-đun, tôi không đăng toàn bộ quá trình tạo mô-đun.

Mô-đun 1

\ app \ code \ Vendor \ Module \ etc \ frontend \ Rout.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>

Mô-đun 2

\ app \ code \ Vendortwo \ Moduletwo \ etc \ frontend \ Rout.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>

Sau khi xóa bộ đệm, tôi chạy http: // localhost / magento210 / module / test / test

Mẫu bí danh được ghi đè bởi Vendortwo_Moduletwo two/twoalias.phtml

nhập mô tả hình ảnh ở đây


Vì vậy, đây có phải là ghi đè một khối bởi bí danh của nó? Điều gì xảy ra nếu tôi không muốn ghi đè lên nó nhưng thêm một khối khác sau nó?
Jāni Elmeris

3

Đây là cách để làm điều đó đúng, và không có hack.

Tôi đã không tra cứu trường hợp sử dụng của OP, nhưng tôi cần có thể sửa đổi các trình kết xuất trong giỏ hàng. Vấn đề là, giống như trong trường hợp của OP, Magento_Checkoutmô-đun không cung cấp tên cho trình kết xuất, điều đó có nghĩa là chúng không thể được tham chiếu và các mẫu của chúng thay đổi bằng phương pháp truyền thống hoặc tài liệu. Tuy nhiên, sau một số điều tra, tôi đã khám phá ra cách thực hiện bằng cách sử dụng các công cụ Magento2 cung cấp cho chúng tôi trực tiếp trong bố cục XML.

Lưu ý rằng có những nơi khác mà cách tiếp cận tương tự này hoạt động, chẳng hạn như trong Magento\Sales\Block\Items\AbstractItemskhối. Các mô-đun Magento_CheckoutMagento_Saleshai mô-đun là hai sử dụng hầu hết các trình kết xuất vật phẩm, vì vậy điều này bao gồm nhiều truy vấn sẽ dẫn đến việc ai đó thay đổi mẫu của một khối mà không có tên. Lý do điều này được đăng là vì không thể tránh khỏi những người khác đang tìm cách sửa đổi các mẫu trình kết xuất trong thanh toán hoặc mô-đun bán hàng.

Tôi sẽ cung cấp giải pháp trước, và sau đó giải thích chi tiết cho bất kỳ ai muốn biết lý do tại sao nó hoạt động.

Giải pháp

Thêm phần sau vào checkout_cart_index.xmltệp bố cục:

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

Lưu ý rằng tên mô-đun và đường dẫn cần được sửa đổi để phản ánh cơ sở mã của bạn.

Giải trình

Điều này hoạt động bằng cách tận dụng overridden_templatesdữ liệu khối, không được xác định theo mặc định.

Trong Magento_Checkout, checkout_cart_index.xmltệp bố trí xác định khối sau:

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

Sau đó, nó định nghĩa một vài trình kết xuất trong checkout_cart_item_renderers.xmltệp bố cục:

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

Thật không may, chúng không thể được tham chiếu bởi các bí danh của chúng, defaultsimple, tương ứng.

Tuy nhiên, nhìn vào Magento\Checkout\Block\Cart\GridBlock, được đặt tên checkout.cart.formvà là cha mẹ của các trình kết xuất, có thể lưu ý rằng có một lệnh gọi getItemHtmlphương thức trong mẫu liên quan , cart/form.phtml. Phương pháp đó sau đó gọi getItemRenderer. Cả hai phương thức này đều được định nghĩa trong Gridlớp cha của , AbstractBlock. Đây là nơi overridden_templatesdữ liệu được sử dụng:

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

Với kiến ​​thức này, việc điền vào khối dữ liệu từ bố cục XML rất đơn giản bằng argumentscú pháp của Magento2 .


1
Điều này nên được chấp nhận là giải pháp thực sự. Đơn giản và hiệu quả. Cách Magento2 đúng cách. Giải thích tuyệt vời. Cảm ơn bạn!
iva

2

Giải pháp của tôi không phải là phổ quát, nó là một "hack bẩn" nhưng nó có thể hữu ích trong một số trường hợp nhất định. Mẫu của tôi là dành cho trình kết xuất frontend, không phải cho adminhtml (tôi cho rằng nó phải giống nhau).

Thiết lập điểm dừng trong \Magento\Framework\Data\Structure::getChildIdđiều kiện " $ ParentId == 'checkout.cart.item.renderers' " (đây là tên của khối cha mẹ như bạn có thể thấy trong checkout_cart_item_renderers.xmlbố cục). Tất cả các khối con có tên riêng (được tính):

nhập mô tả hình ảnh ở đây

Sử dụng tên này trong cập nhật bố trí mô-đun của bạn:

    <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
Đối với bất cứ ai nhìn vào điều này, hãy lưu ý rằng điều này sẽ sụp đổ nếu bạn thậm chí chỉ nhìn chằm chằm vào nó. Đừng xây nhà bằng thẻ. Những con số này không được đảm bảo.
danemacmillan

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.