5

How can do you change the class type and template of a block set by LayoutXML?

For instance I would like to change the class used below from Magento\Wishlist\Block\Customer\Wishlist to Holy\Wishlist\Block\Customer\Wishlist and the template to a template from my module.

<block class="Magento\Wishlist\Block\Customer\Wishlist" name="customer.wishlist" template="view.phtml" cacheable="false">

So far I've tried

<referenceBlock name="customer.wishlist">
    <!--<block class="Holy\Wishlist\Block\Customer\Wishlist" template="Holy_Wishlist::view.phtml"/>-->
    <arguments>
        <argument name="class" xsi:type="string">Holy\Wishlist\Block\Customer\Wishlist</argument>
        <argument name="template" xsi:type="string">Holy_Wishlist::view.phtml</argument>
    </arguments>
</referenceBlock>
3

I found I had to remove the block defined in the core in my modules layout XML, and then add it again with the new class type and template.

<referenceBlock name="customer.wishlist" remove="true" />

 <referenceContainer name="content">
     <block class="Holy\Wishlist\Block\Customer\Wishlist" name="customer.wishlist.categorized" template="Holy_Wishlist::view.phtml" cacheable="false">
         <block class="Magento\Wishlist\Block\Rss\Link" name="wishlist.rss.link" template="rss/wishlist.phtml"/>
         <block class="Magento\Wishlist\Block\Customer\Wishlist\Items" name="customer.wishlist.items" as="items" template="item/list.phtml" cacheable="false">
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image" name="customer.wishlist.item.image" template="item/column/image.phtml" cacheable="false"/>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info" name="customer.wishlist.item.name" template="item/column/name.phtml" cacheable="false"/>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart" name="customer.wishlist.item.price" template="item/column/price.phtml" cacheable="false">
                 <block class="Magento\Catalog\Pricing\Render" name="product.price.render.wishlist">
                     <arguments>
                         <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                         <argument name="price_type_code" xsi:type="string">wishlist_configured_price</argument>
                         <argument name="price_label" xsi:type="boolean">false</argument>
                         <argument name="zone" xsi:type="string">item_list</argument>
                     </arguments>
                 </block>
                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Options" name="customer.wishlist.item.options" cacheable="false"/>
             </block>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.inner" template="item/column/actions.phtml" cacheable="false">
                 <arguments>
                     <argument name="css_class" xsi:type="string">product-item-inner</argument>
                 </arguments>
                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment" name="customer.wishlist.item.comment" template="item/column/comment.phtml" cacheable="false">
                     <arguments>
                         <argument name="title" translate="true" xsi:type="string">Product Details and Comment</argument>
                     </arguments>
                 </block>
                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart" name="customer.wishlist.item.cart" template="item/column/cart.phtml" cacheable="false">
                     <arguments>
                         <argument name="title" translate="true" xsi:type="string">Add to Cart</argument>
                     </arguments>
                 </block>

                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.actions" template="item/column/actions.phtml" cacheable="false">
                     <arguments>
                         <argument name="css_class" xsi:type="string">product-item-actions</argument>
                     </arguments>
                     <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit" name="customer.wishlist.item.edit" template="item/column/edit.phtml" before="-" cacheable="false"/>
                     <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove" name="customer.wishlist.item.remove" template="item/column/remove.phtml" cacheable="false"/>
                 </block>
             </block>
         </block>
         <container name="customer.wishlist.buttons" as="control_buttons" label="Wishlist Control Buttons">
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Button" name="customer.wishlist.button.update" template="button/update.phtml" cacheable="false"/>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Button" name="customer.wishlist.button.share" template="button/share.phtml" cacheable="false"/>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Button" name="customer.wishlist.button.toCart" template="button/tocart.phtml" cacheable="false"/>
         </container>
     </block>
 </referenceContainer>
| improve this answer | |
3

Quite old question, but might be useful for someone else, so you can use preference in module di.xml like

<preference for="Magento\Catalog\Block\Product\View\Description" type="Vendor\Module\Block\ProductDescription" />

After this template can be change easily in layout xml without removing core block.

| improve this answer | |
  • This is a bad practice actually. And does not answer the question. – vitoriodachef Jun 21 '19 at 10:51
  • Not a good solution. Because it will override with your code in all module which shouldn't happen. If you want to make changes in Description class on some layout eq product page. Overriding any function will make changes every where that even in description page which we don't want. If you are adding a new function then its fine. – Avesh Naik Aug 21 '19 at 7:36
  • Yes, <preference> will allow Magento to use your module class instead default class. Better you can extend class & use it. – Sourav Apr 2 at 9:27
0

In case you'd like to keep the same block name in the layout as well as the same alias to avoid modifying of the core files (and to manipulate only with layouts) you could utilise "insert" directive. The only thing it doesn't change the name of the block. It changes only an alias. To change the name of the block in the layout one would need to use "setNameInLayout". See example below

<referenceBlock name="customer.wishlist" remove="true" />
<referenceBlock name="content">
    <block class="Holy\Wishlist\Block\Customer\Wishlist" name="customer.wishlist.tmp" after="customer.wishlist">
        <!-- Copy-paste here all related blocks and actions from the original "customer.wishlist" block -->
    </block>
    <action method="insert">
        <argument name="name" xsi:type="string">customer.wishlist.tmp</argument>
        <argument name="siblingName" xsi:type="number">0</argument><!-- May be string with the name of the sibling block -->
        <!-- <argument name="siblingName" xsi:type="string">sibling_name_in_layout</argument> -->
        <argument name="after" xsi:type="boolean">true</argument><!-- Toggle false - before; true - after -->
        <argument name="alias" xsi:type="string">customer.wishlist</argument>
    </action>
</referenceBlock>
<referenceBlock name="customer.wishlist.tmp">
    <action method="setNameInLayout">
        <argument name="name" xsi:type="string">customer.wishlist</argument>
    </action>
</referenceBlock>

After such manipulations core code, which calls

$block->getChildHtml('customer.wishlist');
//or
$block->getChildBlock('customer.wishlist');

would work just fine as well as

$layout->getBlock('customer.wishlist');

Then no need to adjust core blocks and templates to the new block name.

| improve this answer | |
0

Just keep the same name of the block in the name argument and change class and template.

<block class="Vendor\Module\Block\Customer\Wishlist" name="customer.wishlist" template="Vendor_Module::view.phtml" cacheable="false">
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.