How to use a custom price template in Magento 2?

If you’re familiar with the Magento basic fundamentals then you certainly know Magento has been developed to show a variety of prices to your buyers. And below is the bunch of all prices that have their own explanation:

  1. Special Price.
  2. Tier Price.
  3. Grouped Price.
  4. The minimum price of composite products
  5. The price range of composite products
  6. Manufacturer price (MSRP)

Magento represents these prices as price types (e.g. final price, minimum price, maximum price, regular price) and is separate from the actual price in the code. For example, Special Price is represented by the final price type in the code and use a separate template for each price(e.g. final_price.phtml, tier_price.phtml, default.phtml).

Hence We at Aureate Labs wrote a custom module which will show you how to use custom price templates for related product list. For that, you need to override module-catalog/view/base/templates/product/price/final_price.phtml

Step 1: Create a sample module

Create a new module named as PriceTemplate under app/code/Aureatelabs/. Then include the needed registration.php and module.xml files.

File:  app/code/Aureatelabs/PriceTemplate/registration.php

 
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
   \Magento\Framework\Component\ComponentRegistrar::MODULE,
   'Aureatelabs_PriceTemplate',
   __DIR__
);

File: app/code/Aureatelabs/PriceTemplate/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
   <module name="Aureatelabs_PriceTemplate" setup_version="1.0.0"/>
</config>

Run below command to enable the created module.

php bin/magento module:enable Aureatelabs_PriceTemplate
php bin/magento setup:upgrade

Step 2: Create a block

Create a new Aureatelabs\PriceTemplate\Pricing\Render block in our modules layout file catalog_product_view.xml.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/layout/catalog_product_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
       <block class="Aureatelabs\PriceTemplate\Pricing\Render" name="product.price.render.custom">
           <arguments>
               <argument name="price_render_handle" xsi:type="string">custom_catalog_product_prices</argument>
               <argument name="use_link_for_as_low_as" xsi:type="boolean">true</argument>
               <!-- set "override" configuration settings here -->
           </arguments>
       </block>
   </body>
</page>

Step 3: Add new price render handle

As we define custom price render handle custom_catalog_product_prices in step 2, now we need to create that handle as below.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/layout/custom_catalog_product_prices.xml

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
   <block class="Magento\Framework\Pricing\Render\RendererPool" name="render.product.prices.custom">
       <arguments>
           <argument name="default" xsi:type="array">
               <item name="default_render_class" xsi:type="string">Magento\Catalog\Pricing\Render\PriceBox</item>
               <item name="default_render_template" xsi:type="string">Magento_Catalog::product/price/default.phtml</item>
               <item name="default_amount_render_class" xsi:type="string">Magento\Framework\Pricing\Render\Amount</item>
               <item name="default_amount_render_template" xsi:type="string">Magento_Catalog::product/price/amount/default.phtml</item>
               <item name="prices" xsi:type="array">
                   <item name="final_price" xsi:type="array">
                       <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\FinalPriceBox</item>
                       <item name="render_template" xsi:type="string">Aureatelabs_PriceTemplate::product/price/final_price_related_product.phtml</item>
                   </item>
               </item>
           </argument>
       </arguments>
   </block>
</layout>

Step 4: Create Price Render class

As mentioned in step 2, Block type of product.price.render.custom is Aureatelabs\PriceTemplate\Pricing\Render

Hence create the same class and extend Magento\Framework\Pricing\Render

File: app/code/Aureatelabs/PriceTemplate/Pricing/Render.php

<?php

namespace Aureatelabs\PriceTemplate\Pricing;

use Magento\Framework\Pricing\SaleableInterface;

/**
* Base price render
*
* @api
* @method string getPriceRenderHandle()
*
* @api
*/
class Render extends \Magento\Framework\Pricing\Render
{
   /**
    * Render price
    *
    * @param string $priceCode
    * @param SaleableInterface $saleableItem
    * @param array $arguments
    * @return string
    * @throws \InvalidArgumentException
    * @throws \RuntimeException
    */
   public function render($priceCode, SaleableInterface $saleableItem, array $arguments = [])
   {
       $useArguments = array_replace($this->_data, $arguments);

       /** @var \Magento\Framework\Pricing\Render\RendererPool $rendererPool */
       $rendererPool = $this->priceLayout->getBlock('render.product.prices.custom');
       if (!$rendererPool) {
           throw new \RuntimeException('Wrong Price Rendering layout configuration. Factory block is missed');
       }

       // obtain concrete Price Render
       $priceRender = $rendererPool->createPriceRender($priceCode, $saleableItem, $useArguments);
       return $priceRender->toHtml();
   }
}

Here we’ve layout render.product.prices.custom block which was defined previously in catalog_product_view.xml file of our module.

Step 5: Override related product list block

As we want to change the price template for only related product only, now we need to override \Magento\Catalog\Block\Product\ProductList\Related, so first create a preference in di.xml file.

File: app/code/Aureatelabs/PriceTemplate/etc/frontend/di.xml

<?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\ProductList\Related" type="Aureatelabs\PriceTemplate\Block\Product\ProductList\Related"/>
</config>

Here we’ve told Magento whenever someone requests that the object manager instantiate an Aureatelabs\PriceTemplate\Block\Product\ProductList\Related object instead of Magento\Catalog\Block\Product\ProductList\Related object.

So, create a block class in our module.

File: app/code/Aureatelabs/PriceTemplate/Block/Product/ProductList/Related.php

<?php
namespace Aureatelabs\PriceTemplate\Block\Product\ProductList;

class Related extends \Magento\Catalog\Block\Product\ProductList\Related
{
   /**
    * Return HTML block
    *
    * @param \Magento\Catalog\Model\Product $product
    * @param string $priceType
    * @param string $renderZone
    * @param array $arguments
    * @return string
    * @throws \Magento\Framework\Exception\LocalizedException
    */
   public function getProductPriceHtml(
       \Magento\Catalog\Model\Product $product,
       $priceType,
       $renderZone = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST,
       array $arguments = []
   ) {
       if (!isset($arguments['zone'])) {
           $arguments['zone'] = $renderZone;
       }

       /** @var \Magento\Framework\Pricing\Render $priceRender */
       $priceRender = $this->getLayout()->getBlock('product.price.render.custom');
       $price = '';

       if ($priceRender) {
           $price = $priceRender->render($priceType, $product, $arguments);
       }
       return $price;
   }
}

Step 6: Create a custom template file

Now, the final step is to create a custom template for the final price and do changes as per your requirement.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/templates/product/price/final_price_related_product.phtml

<?php
// @codingStandardsIgnoreFile
?>

<?php
/** @var \Magento\Catalog\Pricing\Render\FinalPriceBox $block */

$productId = $block->getSaleableItem()->getId();
//$currentProductId = $block->getRequest()->getParam('id');

/** ex: \Magento\Catalog\Pricing\Price\RegularPrice */
/** @var \Magento\Framework\Pricing\Price\PriceInterface $priceModel */
$priceModel = $block->getPriceType('regular_price');

/** ex: \Magento\Catalog\Pricing\Price\FinalPrice */
/** @var \Magento\Framework\Pricing\Price\PriceInterface $finalPriceModel */
$finalPriceModel = $block->getPriceType('final_price');
$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : '';
$schema = ($block->getZone() == 'item_view') ? true : false;
?>
<?php if ($block->hasSpecialPrice()): ?>
   <span class="special-price">
       <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
           'display_label'     => __('Special Price'),
           'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
           'price_type'        => 'finalPrice',
           'include_container' => true,
           'schema' => $schema
       ]); ?>
   </span>
<?php else: ?>
   <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
       'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
       'price_type'        => 'finalPrice',
       'include_container' => true,
       'schema' => $schema
   ]); ?>
<?php endif; ?>

<?php if ($block->showMinimalPrice()): ?>
   <?php if ($block->getUseLinkForAsLowAs()):?>
       <a href="<?= /* @escapeNotVerified */ $block->getSaleableItem()->getProductUrl() ?>" class="minimal-price-link">
           <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
       </a>
   <?php else:?>
       <span class="minimal-price-link">
           <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
       </span>
   <?php endif?>
<?php endif; ?>

Conclusion

In this way, you’re done with the successful module building to change price templates for related products only. In case you’re stuck in between and need any help in this regards, we’re all glad to help you. Feel free to contact us.

In this article, I’ve shown you how to change price templates for related products step by step. If you still need any help regarding the price template or Magento, we are happy to help you. Feel free to get in touch!

  • Share :