11

I want to add my custom block on listing page[Magento-2] but without any modification on list.phtml or any .phtml file. Is there any possibility by using xml file ?

enter image description here

Any help will be appreciated.

Amit Bera
  • 77,456
  • 20
  • 123
  • 237
Keyur Shah
  • 18,046
  • 6
  • 66
  • 80
  • Great article. Would you expand more detail on test.phtml to override the orginal listing page? As I'm a new comer on Magento 2. –  Jan 19 '16 at 03:48
  • How can I get use the function getProductDetailsHtml() for add block 'label' NEW on grid in test.phtml? – user35225 Jan 21 '16 at 02:36

3 Answers3

11

You can do that if you create new module to override this block: vendor\magento\module-catalog\Block\Product\ListProduct.php

to override this block, you need to create di.xml at app\code\Vendor\Module_Name\etc

di.xml content:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\Module_Name\Block\Product\ListProduct" />
</config>

Create new file name ListProduct.php at app\code\Vendor\Module_Name\Block\Product

ListProduct.php content:

namespace Vendor\Module_Name\Block\Product;
class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    public function getProductDetailsHtml(\Magento\Catalog\Model\Product $product)
    {
        $html = $this->getLayout()->createBlock('Magento\Framework\View\Element\Template')->setProduct($product)->setTemplate('Vendor_ModuleName::test.phtml')->toHtml();
        $renderer = $this->getDetailsRenderer($product->getTypeId());
        if ($renderer) {
            $renderer->setProduct($product);
            return $html.$renderer->toHtml();
        }
        return '';
    }
}

You can change block Magento\Framework\View\Element\Template to your block

create test.phtml file at app\code\Vendor\Module_Name\view\frontend\templates

Harry Nguyen
  • 2,815
  • 17
  • 13
  • Thanks for the information +1 from me... But can we achieve without override ? – Keyur Shah Jan 11 '16 at 10:06
  • @KeyurShah, is above the best method so far in Mage 2.0 to add your custom block on listing page ? I also agree with Kandy as product output is hardcoded in list.phtml. – Slimshadddyyy Feb 08 '16 at 13:08
  • @Vikram till now, I think this is the best method so far and is also working fine for me.. – Keyur Shah Feb 08 '16 at 13:38
  • @KeyurShah, I have already overriddien that with di.xml using above method. Now how to display my custom attribute value in listing page ? – Slimshadddyyy Feb 09 '16 at 08:08
  • @Vikram you can use Mageev2 code to display your custom attribute. I mean in test.phtml you can get $product object and from $product object you can get easily its attribute value. – Keyur Shah Feb 09 '16 at 08:39
  • I have written in my phtml like getProduct(); ?> getMycustomValue();?>, Rest Magev2 code do the magic – Keyur Shah Feb 09 '16 at 08:41
  • This seems to work great, but only on actual catalog pages, if I have products listed on other pages (like front page), it does not work. Any advice how to apply it to product listings everywhere? – Tero Lahtinen Sep 29 '16 at 14:22
  • not working for me! – Chirag Prajapati Dec 06 '16 at 09:35
  • Genius i really like this no functions however i can use to pull this further up the product listing however. – harri Aug 17 '17 at 17:15
  • @magev2 can you please explain when module disable from Disable Modules Output what happen?. its break my category page because in solution template are added in block and Disable Modules Output not disable module its just disable module output content. – Ajay Patel Sep 07 '17 at 11:45
  • so how can i stop the block override when module output are disable – Ajay Patel Sep 07 '17 at 11:46
  • my test.phtml is not shwoing ,but ListProduct.php is called, is there any thing that i am missing? – inrsaurabh Jun 16 '18 at 18:33
4

Currently you cannot do this because all logic of product output is hardcoded in list.phtml template.

KAndy
  • 20,811
  • 3
  • 49
  • 59
2

Here is my take on the solution - but you must modify the list.phtml template:

catalog_category_view.xml

<referenceBlock name="category.products.list">
    <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="custom.block.container" as="custom-block-container">
        <block class="Magento\Catalog\Block\Product\ProductList\Item\Block" name="custom.block" as="custom-block"
           template="Magento_Catalog::product/view/custom-block.phtml" />
    </block>
</referenceBlock>

In custom-block.phtml you can get the product like this:

$_product = $block->getProduct();

You will need to overwrite the list.phtml template though... Just add this where you want your custom block to show:

<?php if ($customBlock = $block->getChildBlock('custom-block-container')): ?>
    <?= $customBlock->setProduct($_product)->getChildHtml() ?>
<?php endif; ?>

If you really want to avoid modifying the list.phtml template, then you might be able to do a similar thing but in a different template.

Zankar
  • 554
  • 3
  • 9