3

I want to render specific product price render in my custom page in block file.

I get reference from here . But, It returns error :

main.CRITICAL: Wrong Price Rendering layout configuration. Factory block is missed [] []

How to render price box ?

Please help me.

Block File :

<?php
namespace Vendor\Helloworld\Block;

class Helloworld extends \Magento\Framework\View\Element\Template {
    /** @var  \Magento\Framework\View\Result\Page */
    protected $_product;
    protected $_layout;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Product $product,
        \Magento\Framework\View\LayoutInterface $layout
    ) {
        $this->_product = $product;
        $this->_layout = $layout;
        parent::__construct($context);
    }

    public function getPrice($productID) {
        $product = $this->_product->load($productID);
        $price = '';
        $arguments = [];
        $priceType = \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE;
        $priceRender = $this->getLayout()->getBlock('Magento\Framework\Pricing\Render', 'product.price.render.default');
        $arguments['zone'] = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST;
        if ($priceRender) {
            $price = $priceRender->render($priceType, $product, $arguments);
        }
        return $price;
    }
}

Controller File :

<?php
namespace Vendor\Helloworld\Controller\Index;

class Custom extends \Magento\Framework\App\Action\Action {

    protected $_customBlock;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Vendor\Helloworld\Block\Helloworld $customBlock
    ) {
        $this->_customBlock = $customBlock;
        parent::__construct($context);
    }

    public function execute() {
        return $this->_customBlock->getPrice(1);
    }
}

layout xml : (helloworld_index_index.xml)

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
  <referenceContainer name="content">
   <block class="Vendor\Helloworld\Block\Helloworld" name="formbuilder" template="Vendor_Helloworld::helloworld.phtml"/>
  </referenceContainer>
</body>
</page>

I take reference from this both answer :

1) Click here 2) Click here

Thanks.

7
  • Can you please share some code
    – Amit Bera
    Commented Oct 12, 2018 at 11:13
  • Please check it @AmitBera. Commented Oct 12, 2018 at 11:19
  • I added this code in my block file. I call one controller using ajax. And this block function call in controller. But, it return system.log. If I add this in one file which is display on page load then it will display pricebox. Commented Oct 12, 2018 at 11:21
  • You have to load render layout
    – Amit Bera
    Commented Oct 12, 2018 at 13:59
  • okay. can you please tell me how ? I mean which layout should i render? Commented Oct 12, 2018 at 14:17

3 Answers 3

13

For render price template in the specific block, you need to call function like below,

public function getPrice(\Magento\Catalog\Model\Product $product)
{
    $priceRender = $this->getLayout()->getBlock('product.price.render.default');
    if (!$priceRender) {
        $priceRender = $this->getLayout()->createBlock(
            \Magento\Framework\Pricing\Render::class,
            'product.price.render.default',
            ['data' => ['price_render_handle' => 'catalog_product_prices']]
        );
    }

    $price = '';
    if ($priceRender) {
        $price = $priceRender->render(
            \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
            $product,
            [
                'display_minimal_price'  => true,
                'use_link_for_as_low_as' => true,
                'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST
            ]
        );
    }

    return $price;
}
5
  • Thanks sir @RakeshJesadiya. I got solution by Amit Bera's hint about render layout. I find that way and get result. But, your answer is better :) Commented Oct 13, 2018 at 5:32
  • 3
    You can check core code from module-catalog/Block/Rss/Product/NewProducts.php to render price. Commented Oct 13, 2018 at 5:37
  • Oh...!! Yes. I didn't see in that file. I just look over on swatches and ListProduct.php file. Thanks for guiding me :) Commented Oct 13, 2018 at 5:40
  • Great. It worked Commented Dec 3, 2020 at 14:40
  • Great. It is working. Commented Jul 22, 2021 at 9:32
1

You can try below solution:

   $arguments = [];
$priceType = \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE;
$priceRender = $this->getLayout()->getBlock('product.price.render.default');
$arguments['zone'] = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST;
$price = ''
if ($priceRender) {
    $price = $priceRender->render($priceType, $product, $arguments);
}

echo $price;

If layout still not render, then you need to inject \Magento\Framework\App\ViewInterface in your construct :

   /**
     * @var  \Magento\Framework\App\ViewInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $_view;

    public function __construct(
        ..........
        \Magento\Framework\App\ViewInterface $view,
        ..........
    ) {
        ..........
        $this->_view = $view;
        ..........
    }

And need to inject Magento\Framework\View\Result\PageFactory in your controller

   /**
     * @var \Magento\Framework\View\Result\PageFactory
     */
    protected $_resultPageFactory;
    public function __construct(
        ..........
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        ..........      
    ) {
        ..........
        $this->_resultPageFactory = $resultPageFactory;
        ..........
    }
    public function execute() {
          ........
          $resultPage = $this->_resultPageFactory->create();
          ........
    }

Then, you can use this below line for successfully price render layout.

$priceRender = $this->getLayout()->getBlock('product.price.render.default');
9
  • Same system.log return. Commented Oct 12, 2018 at 11:58
  • I use like this : $this->_layout->getBlock('product.price.render.default'); Commented Oct 12, 2018 at 12:00
  • construct : \Magento\Framework\View\LayoutInterface $layout, Commented Oct 12, 2018 at 12:00
  • You have tried at block then you have to change $block->getLayout() to $this->getLayout()
    – Amit Bera
    Commented Oct 12, 2018 at 12:01
  • It returns blank. I think block not render. So, It's not enter in if condition. Commented Oct 12, 2018 at 12:05
0

Try This Code

protected $resultLayout;

public function __construct(
    \Magento\Framework\View\Result\Layout $resultLayout
) {
    $this->resultLayout = $resultLayout;
}

public function getProductPriceHtml(\Magento\Catalog\Model\Product $product)
{
    /** @var \Magento\Framework\Pricing\Render $priceRender */
    $priceRender = $this->resultLayout->getLayout()->getBlock(\Magento\Framework\Pricing\Render::class);
    if (!$priceRender) {
        $priceRender = $this->resultLayout->getLayout()->createBlock(
            \Magento\Framework\Pricing\Render::class,
            \Magento\Framework\Pricing\Render::class,
            ['data' => ['price_render_handle' => 'catalog_product_prices']]
        );
    }
    $price = '';
    if ($priceRender) {
        $price = $priceRender->render(
            \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
            $product,
            [
                'display_minimal_price' => true,
                'use_link_for_as_low_as' => true,
                'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST,
            ]
        );
    }

    return $price;
}

I Hope This Helps You.

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.