Magento 2 - Add CMS Static Block to Checkout Address Form
You'll have to do this with a module, it can't be done from within the theme.
The idea is to get the CMS block's html and put it into the checkoutConfig
JS object. We do this by adding a config provider to Magento\Checkout\Model\CompositeConfigProvider
Here is {module_dir}/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_provider" xsi:type="object">Vendor\Module\Model\CheckoutConfigProvider</item>
</argument>
</arguments>
</type>
<type name="Vendor\Module\Model\CheckoutConfigProvider">
<arguments>
<!--ID OF THE CMS BLOCK-->
<argument name="blockId" xsi:type="string">16</argument>
</arguments>
</type>
</config>
This will add our config provider and is also where we pass in the ID of the CMS block you want to display.
Now for the config provider {module_dir}/Model/CheckoutConfigProvider.php:
<?php
namespace Vendor\Module\Model;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Cms\Block\Widget\Block;
class CheckoutConfigProvider 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 [
'cmsBlockHtml' => $this->cmsBlockWidget->toHtml()
];
}
}
This renders the block's html and will make it available to javascript in window.checkoutConfig.cmsBlockHtml
.
Now we need to add a uiComponent
to the address form. We do this in {module_dir}/view/frontend/layout/checkout_index_index.xml`
<?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">Vendor_Module/cms-block</item>
</item>
<item name="sortOrder" xsi:type="string">125</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Finally we just need to create the knockout template file for this uiComponent
.
It will be {module_dir}/view/frontend/web/template/cms-block.html:
<div data-bind="html: window.checkoutConfig.cmsBlockHtml"></div>
This is what I did to display a CMS block on checkout page under sidebar. 1. In the templates/onepage.phtml I created a js variable to hold the cms block content like this:
<?php $myCmsBlock = $block->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('my_cms_block')->toHtml() ?>
<script type="text/javascript">
var my_cms_block = <?php echo json_encode($myCmsBlock)?>;
</script>
2. In the knockout template file (in my case it was web/js/template/sidebar.html), displayed the cms block content from the above js variable like this:
<div class="opc-help-cms" data-bind="html:my_cms_block">
</div>
Hope this helps someone! Thanks!