How To Add CMS Block In Checkout Page Magento 2
CMS blocks were one of the reasons which made Magento was and is that popular. Site administrators can easily manipulate the content of the store using CMS blocks.
However, adding a CMS block to the Checkout page in Magento 2 is a bit more complicated than usual. This is because the whole checkout process is dynamically loaded and we cannot put anything static
inside it. Therefore, in today’s post, I will guide you on how to add CMS block to Magento 2 Checkout.
How to add CMS Block in checkout page in 3 steps
- Step 1: Create a module
- Step 2: Add CMS block in Checkout sidebar
- Step 3: Add CMS block to address form
Step 1: Create a module
In case you have not known the way to create a Magento 2 module, you can follow the steps the post How to Create Module in Magento 2
You can set the name of the module as you want. In this article, I will use Mageplaza for vendor and ModuleName for the module name.
After the module has been created with all the necessary files, you will need to add or edit some details of it.
But before doing that, please make sure that you have done setup:upgrade
after creating the module.
Step 2: Add CMS block in Checkout sidebar
In this step, you will edit the Mageplaza/ModuleName/etc/frontend/di.xml file:
<?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">Mageplaza\ModuleName\Model\ConfigProvider</item>
</argument>
</arguments>
</type>
<type name="Mageplaza\ModuleName\Model\ConfigProvider">
<arguments>
<argument name="blockId" xsi:type="string">checkout_cms_block</argument>
</arguments>
</type>
</config>
Using this code, a new entry to ConfigProvider is added as well as CMS block which will be used to parse data from is declared.
In the example above, the name of the block is checkout_cms_block. This would work with the block’s ID or identifier.
Remember that the path Mageplaza\ModuleName\Model\ConfigProvider
need to be matched with the name of your block.
Then, by creating or editing Mageplaza/ModuleName/Model/ConfigProvider.php
, you will create a new entry for Config Provider:
<?php namespace Mageplaza\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
];
}
}
Because the variable has been added to the global window.checkoutConfig variable, now you can use window.checkoutConfig.cms_block variable to call that content.
Next, bind that variable to some HTML element. The rest will be in charge of Knockout.JS.
Following is the file app/design/frontend/Mageplaza/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>
After following all the steps correctly, you will see your CMS block being displayed in the sidebar.
Step 3: Add CMS block to address form
Instead of using a similar approach, in this step, we will change the content of app/code/Mageplaza/ModuleName/Model/ConfigProvider.php
. The content will be changed into this:
<?php
namespace Mageplaza\ModuleName\Model;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Cms\Block\Widget\Block;
class ConfigProvider implements ConfigProviderInterface
{
protected $cmsBlockWidget;
public function __construct(Block $block, $blockId)
{
$this->cmsBlockWidget = $block;
$block->setData('block_id', $blockId);
$block->setTemplate('Magento_Cms::widget/static_block/default.phtml');
}
public function getConfig()
{
return [
'cms_block' => $this->cmsBlockWidget->toHtml()
];
}
}
Next, you create app/code/Mageplaza/ModuleName/view/frontend/layout/checkout_index_index.xml
with the following content:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-address-fieldset" xsi:type="array">
<item name="children" xsi:type="array">
<item name="cms-block" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Mageplaza_ModuleName/cms-block</item>
</item>
<item name="sortOrder" xsi:type="string">1</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Now, the new UI component has been added to the address form. The content of your CMS block will be held in that component. The components load order would be managed inside XML files. You might see that the sortOrder has been set as 1, which means that your component will be loaded first inside the address form.
Pay attention to the line Mageplaza_ModuleName/cms-block and then change it.
Now, the only thing you need is a knockout template to output the CMS block data.
Use this content to create app/code/Mageplaza/ModuleName/view/frontend/web/template/cms-block.html
:
<div data-bind="html: window.checkoutConfig.cms_block"></div>
Following all the steps above, you will see your CMS block being displayed in address form and rendered first. This guide will work with clean Magento 2.2 installation. If for testing purposes, the Luma theme can be used.
Conclusion
Above is the instruction on how to add Magento 2 CMS Block in checkout page. Hope it will be helpful for you. In case something went wrong, please ensure:
- Your module is created properly and all config files with proper values have consisted inside.
- The
php bin/magento setup:upgrade
need to be run after the module is created. - The code
Mageplaza/ModuleName
from this post need to be replaced with the proper vendor and name of your module.
- How to create a simple Hello World module for Magento 2
- Magento 2 Block Template Ultimate Guides
- How to Create Module in Magento 2
- How to Create Controller in Magento 2
- How to create CRUD Models in Magento 2
- How to Create Magento 2 Block, Layout and Templates
- Configuration - System.xml
- How To Create Admin Menu In Magento 2
- Admin ACL
- Admin Grid