8

Evening All,

I am looking to add a static CMS block to the Magento 2 Checkout delivery address form. I would like display the CMS block under the phone number field. The old method would have been to pull the template into my new theme and update it but in Magento 2 the Checkout is being rendered by knockoutjs and I am a bit lost.

Any help with what knockout templates or XML layout I need to update to do this would be very helpful.

asked May 6, 2017 at 20:46

3 Answers 3

14

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>
Saphal Jha
1,89315 silver badges26 bronze badges
answered May 7, 2017 at 0:40
13
  • Ah Excellent, That worked a treat! Commented May 7, 2017 at 5:01
  • i did the same but not working for me. Commented Dec 21, 2017 at 10:43
  • 1
    Thank you so much! I put it into a module (see below) Commented May 23, 2019 at 10:35
  • I have added it in my checkout_index_index.xml` where i have created some tabs for checkout but it doesn't show there. Will you Please Help @Aaron Commented Jul 29, 2020 at 5:57
  • @Prits Did you get it to work? I followed these steps as well and I am seeing the div appear on the checkout page but it is not populated with the block content. Checking console log, there is no cmsBlockHtml in window.checkoutConfig Commented Jul 30, 2020 at 4:41
10

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!

answered Sep 20, 2017 at 18:06
2
  • Doesn't seem as clean as Aaron's approach, but probably still working well :-) Commented May 23, 2019 at 10:06
  • Perfect. This code is working fine when we add a CMS block in a section where you can not add it by XML file. Commented Dec 12, 2019 at 9:11
1

Based on Aarons answer I put that in our Mestrona_CommonBlocks Magento 2 Module on GitHub.

answered May 23, 2019 at 10:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.