10

I'm trying to add custom template to product page under social sharing section. In my module I've following code in layout file default.xml

 <body>
 <referenceContainer name="product.info.social">
  <block class="Magento\Framework\View\Element\Template" name="product.info.custom" template="Lapisbard_Product::social.phtml" after="product.info.addtocart">
  </block>
 </referenceContainer>
</body>

social.phtml content

<p>Hey there !</p>
<?php //$_product = $block->getProduct();

It is working fine and showing template content on product page. When I'm using block class Magento\Catalog\Block\Product\View instead of Magento\Framework\View\Element\Template so that I can get product object in my template using $block->getProduct();, it's showing a blank page.

1. What mistake I'm doing here?
2. What is the best way to modify product page?
3. Is there a reference layout file which I can use to add new templates to any section of product page writing layout code in my module?

  • @amiteshree may be your phtml file includes functions that are defined in Magento\Catalog\Block\Product\View block file – Shaheer Ali Jan 22 '16 at 12:07
  • @ShaheerAli: In my phtml file I'm trying to get product object using $_product = $block->getProduct(); when I'm using Magento\Catalog\Block\Product\View block. – amitshree Jan 22 '16 at 12:26
  • Then why are you assign Magento\Framework\View\Element\Template block to your template. – Shaheer Ali Jan 22 '16 at 12:30
  • 1
    @amiteshree if you want to use product view functions then you need to assign Magento\Catalog\Block\Product\View to your template phtml. And your method of adding custom template to product page is correct – Shaheer Ali Jan 22 '16 at 12:52
  • 1
    Blank page usually means, some error happened. Did you look in your error.log? magento exceptions log? What mode do you use? – Anton Kril Jan 25 '16 at 22:47
23
+50

The "white page" error comes because Magento\Framework\View\Element\Template have not a getProduct() method.

So I think that the "cleanest" way to do it is create a custom module with a custom block, layout and template (don't worry this just take a few minutes and you have done some parts)

Module Files:

enter image description here

(I will skip /etc/module.xml and registration.php because are trivial, however you could find the complete example here.)

Let start with the Block php file:

Test\Catalog\Block\Product\View\Extra.php

<?php

namespace Test\Catalog\Block\Product\View;

use Magento\Catalog\Block\Product\AbstractProduct;

class Extra extends AbstractProduct
{

}

As you can see it's just a concrete class extending (IMO) the most lightweight Product Abstract Block. You can also extend Magento\Framework\View\Element\Template but in that case you'll need to implement the getProduct() method and change the context in the constructor in order to get access to the registry.

So lets move to the Layout file:

Test/Catalog/view/frontend/layout/catalog_product_view.xml

<?xml version="1.0"?>
<body>
    <referenceContainer name="product.info.social">
        <block class="Test\Catalog\Block\Product\View\Extra"
            name="product.view.extra"
            template="Test_Catalog::product/view/extra.phtml"
            after="-">
        </block>
    </referenceContainer>
</body>

And Finally the template file:

Test/Catalog/view/frontend/templates/product/view/extra.phtml

<?php /* @var $block \Test\Catalog\Block\Product\View\Extra */?>
<?php $_product = $block->getProduct() ?>
<h3><?php echo 'My Product Name Is: ' . $_product->getName(); ?></h3>

As you can see is pretty straightforward, simplest than M1-

Remember that all your custom logic should be implemented in the Extra.php block class in order to keep the view clean.

ie:

In the Extra.php class:

public function getSomething()
{
    return 'something'
}

in the extra.phtml view:

<?php echo $block->getSomething() ?>
  • 2
    So my module's catalog_product_view.xml layout loads automatically when I'm on product page? – amitshree Jan 27 '16 at 6:16
  • 2
    Absolutly! it's very similar to M1 but now every handle is in a separated file. – MauroNigrele Jan 27 '16 at 6:22
5

A Supplement for the Accepted Answer

The accepted answer is good, but the AbstractProduct is deprecated now.

/**
 * Class AbstractProduct
 * @api
 * @deprecated 101.1.0
 * @SuppressWarnings(PHPMD.NumberOfChildren)
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @since 100.0.2
 */
class AbstractProduct extends \Magento\Framework\View\Element\Template

So, we have to use the Magento\Framework\Registry to achieve the Block, the Block sample is below:

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\Registry;

class ProductView extends Template
{
    /**
     * @var Registry
     */
    protected $registry;

    /**
     * @var \Magento\Catalog\Model\Product
     */
    protected $product;

    /**
     * ProductView constructor.
     * @param Template\Context $context
     * @param array $data
     * @param Registry $registry
     */
    public function __construct(
        Template\Context $context,
        array $data = [],
        Registry $registry
    )
    {
        $this->registry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
        if (is_null($this->product)) {
            $this->product = $this->registry->registry('product');
        }

        return $this->product;
    }
}

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.