Magento 2 – How to view CMS block in checkout page

By | August 25, 2018
Spread the love

Using CMS blocks, admin can easily change content of the store. CMS blocks can be used to display banners, sale blocks, return policies, important information message on some sections of the store etc. CMS blocks can carry plain text or HTML/JS/CSS code which means they can be used for even more complex content delivery like sliders, product carousels etc.

CMS blocks at checkout can have many usages like displaying some information for specific shipping method of some static content in order to convince the user to spend more before he checks out.

Adding CMS block to some specific position/page is not such a hassle, we just need to “register” our CMS block in layouts and define order/position of our CMS block. We then need to call it in templates and that’s it. CMS block is now part of the content and will be rendered/delivered when needed.

Adding CMS block to Magento 2 Checkout is a bit more complex task since the whole checkout is built up from a series of KnockoutJS components which are then rendered using the knockout.js templating system. Magento 2 defines these components and their mutual relationship in a large XML file. To pull the data from the server, Magento uses global Javascript variable window.checkoutConfig which is then used by Knockout.js to compute and display information on the frontend.

In short, the whole checkout is dynamically loaded and we can’t put anything “static” inside.

Hopefully, there is a way to insert CMS block inside checkout flow.

Since the whole checkout is bundled from various JS components, approaches on this task will vary depending on the CMS block position. However, each approach has the same initial step.

Idea is to take content from CMS block and put it in JS object which will then be outputted to frontend via Knockout Bindings. That way, our CMS content becomes part of the checkout flow and it is loaded alongside with other components. If you want to hang out with components, act as a component!

Adding CMS block in Checkout sidebar

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Checkout\Model\CompositeConfigProvider">
       <arguments>
           <argument name="configProviders" xsi:type="array">
               <item name="cms_block_config_provider" xsi:type="object">Vendor\ModuleName\Model\ConfigProvider</item>
           </argument>
       </arguments>
   </type>
   <type name="Vendor\ModuleName\Model\ConfigProvider">
       <arguments>
           <argument name="blockId" xsi:type="string">checkout_cms_block</argument>
       </arguments>
   </type>
</config>

With this code, we are adding new entry to ConfigProvider and we are also declaring CMS block which will be used to parse data from.
In the above example, a block is named “checkout_cms_block” (it works with id or identifier of the block).

Please make sure that and paths match the name of your block. In above example, path is Vendor\ModuleName\Model\ConfigProvider.

Next, we will create new entry for Config Provider by creating or editing Vendor/ModuleName/Model/ConfigProvider.php:

<?php namespace Vendor\ModuleName\Model;
 
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Framework\View\LayoutInterface;
 
class ConfigProvider implements ConfigProviderInterface
{
   /** @var LayoutInterface  */
   protected $_layout;
   protected $cmsBlock;
 
   public function __construct(LayoutInterface $layout, $blockId)
   {
       $this->_layout = $layout;
       $this->cmsBlock = $this->constructBlock($blockId);
   }
 
   public function constructBlock($blockId){
       $block = $this->_layout->createBlock('Magento\Cms\Block\Block')
           ->setBlockId($blockId)->toHtml();
       return $block;
   }
 
   public function getConfig()
   {
       return [
           'cms_block' => $this->cmsBlock
       ];
   }
}

Since we have added our own variable to global window.checkoutConfig variable, we can now call that content using window.checkoutConfig.cms_block variable.

Now we just need to bind that variable to some HTML element and Knockout.JS will do the rest.

Here is app/design/frontend/Vendor/ThemeName/Magento_Checkout/web/template/sidebar.html

<div id="opc-sidebar"
    data-bind="afterRender:setModalElement, mageInit: {
   'Magento_Ui/js/modal/modal':{
       'type': 'custom',
       'modalClass': 'opc-sidebar opc-summary-wrapper',
       'wrapperClass': 'checkout-container',
       'parentModalClass': '_has-modal-custom',
       'responsive': true,
       'responsiveClass': 'custom-slide',
       'overlayClass': 'modal-custom-overlay',
       'buttons': []
   }}">
 
   <!-- ko foreach: getRegion('summary') -->
       <!-- ko template: getTemplate() --><!-- /ko -->
   <!--/ko-->
 
   <div data-bind="html: window.checkoutConfig.cms_block"></div>
 
   <div class="opc-block-shipping-information">
       <!-- ko foreach: getRegion('shipping-information') -->
       <!-- ko template: getTemplate() --><!-- /ko -->
       <!--/ko-->
   </div>
</div>

And that’s it.

If you did everything right, you should see your CMS block displayed in the sidebar.

Please, note that I’ve created sidebar.html template in my package/theme. Never edit files directly in vendor/magento/* folder.

Leave a Reply

Your email address will not be published. Required fields are marked *

one × 2 =