7

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.

3 Answers 3

13

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>
13
  • Ah Excellent, That worked a treat!
    – Baber
    May 7, 2017 at 5:01
  • i did the same but not working for me. Dec 21, 2017 at 10:43
  • 1
    Thank you so much! I put it into a module (see below)
    – Alex
    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
    – Prits
    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
    – Chrysippus
    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!

2
  • Doesn't seem as clean as Aaron's approach, but probably still working well :-)
    – Alex
    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.
    – Sumit
    Dec 12, 2019 at 9:11
0

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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.