Magento2: Add custom template to product details page below add to cart section
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:
(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() ?>
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,
Registry $registry,
array $data = []
)
{
$this->registry = $registry;
parent::__construct($context, $data);
}
/**
* @return \Magento\Catalog\Model\Product
*/
public function getProduct()
{
if ($this->product === null) {
$this->product = $this->registry->registry('product');
}
return $this->product;
}
}