5

I'm trying to hide prices and "add to shopping cart" for guests.

To do that I need to check whether the customer is logged in or not. There are no predefined methods in the Catalog Widget block so I need to extend the class via preference.

I've successfully extended the block Magento\Catalog\Block\Product\ListProduct but Magento\CatalogWidget\Block\Product\ProductsList is trickier.

When I try it, I get main.CRITICAL: Invalid template file: 'product/widget/content/grid.phtml' in module: 'Vendor_Namespace' block's name: 'product\productslist_0' in system.log.

Any solutions to this?

Edit

This is the contents of the di.xml file:

<?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\CatalogWidget\Block\Product\ProductsList" type="Vendor\Namespace\Block\Product\ProductsList" />
</config>

This is the contents of the ProductsList.php file:

<?php
namespace Vendor\Namespace\Block\Product;

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{
    protected $_httpContext;

    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder,
        \Magento\CatalogWidget\Model\Rule $rule,
        \Magento\Widget\Helper\Conditions $conditionsHelper,
        array $data = []
    ) {
        $this->_httpContext = $httpContext;
        parent::__construct(
            $context,
            $productCollectionFactory,
            $catalogProductVisibility,
            $httpContext,
            $sqlBuilder,
            $rule,
            $conditionsHelper,
            $data
        );
    }

    protected function _construct()
    {
        parent::_construct();
        // Tested, but does not work
        // $this->setTemplate('Vendor_Namespace::product/widget/content/grid.phtml');
    }

    public function isCustomerLoggedIn()
    {
        return $this->_httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
    }
}
3
  • please show your file Commented Aug 8, 2016 at 12:10
  • There is a phtml file: Vendor/Namespace/view/frontend/templates/product/widget/content/grid.phtml? Commented Aug 8, 2016 at 16:10
  • Yes, I've tried adding to both template location and to the custom module, nothing works. Commented Aug 9, 2016 at 5:14

3 Answers 3

2

When we override the widget block class, then due to some reason, we need to put related template file into the override block with the same directory path as original.

That's why to override the catalogwidget, we need to follow given below steps:

1- Create di.xml file into your custom module.

<?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\CatalogWidget\Block\Product\ProductsList" type="Vendor\Namespace\Block\Product\ProductsList" />
</config>

2- Create a block file to extend the widget class:

<?php

namespace YOUR_NAMESPACE\CatalogWidget\Block\Product;

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{
  public function customMethod()
  {
    //do your action here
   }
}

?>

3- Copy the related template file and put into your custom module with related directory Path:

For this example, copy the file by going into given below path.

 vendor/magento/module-catalog-widget/view/frontend/templates/product/widget/content/grid.phtml

And put into your custom module's view ditectory into given below path:

app/code/YOUR_NAMESPACE/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml

Hope, by this way your problem got fixed.

1

Magento includes a specific template for you for you when you add the widget on a CMS page.

{{ ... template="catalog/product/list.phtml" ... }}

You do not need to copy the entire template file to your module. You can specify in your module to use the default Magento_CatalogWidget like so:


In your Block class declaration:

namespace <vendor>\CatalogWidget\Block\Product;

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{

    protected $_template = 'Magento_CatalogWidget::product/widget/content/grid.phtml';

...

In your Block class constructor:

public function __construct(<args>)
{
    ...
    $this->setTemplate('Magento_CatalogWidget::product/widget/content/grid.phtml');
    ...
}

You would think it would be possible to do so in the CMS declaration, but this did not work for me:

{{ ... template="Magento_CatalogWidget::catalog/product/list.phtml" ... }}

Hope this helps, Cheers!

0

For some reason, you actually need to add the phtml file to your custom module.

Here is how I fixed this problem.

My custom module tree is as follow:

├── Block
│   └── Product
│       └── ProductsList.php
├── etc
│   ├── di.xml
│   └── module.xml
├── registration.php
└── view
    └── frontend
        └── templates
            └── product
                └── widget
                    └── content
                        └── grid.phtml

The content of di.xml is:

<?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\CatalogWidget\Block\Product\ProductsList" type="YOUR_NAMESPACE\CatalogWidget\Block\Product\ProductsList" />
</config>

The content of ProductsList.php is:

<?php

namespace YOUR_NAMESPACE\CatalogWidget\Block\Product;

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{
    public function myTest()
    {
        die('Hello World !');
    }
}

?>

The file grid.phtml comes from Magento_CatalogWidget module:

vendor/magento/module-catalog-widget/view/frontend/templates/product/widget/content/grid.phtml

To test it, you can add the line below to the custom module's grid.phtml in order to list the methods of the block:

print_r(get_class_methods($block));

You should see the method myTest() in the list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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