Magento 2 – Add CMS Static Block to Checkout Address Form

knockoutjsmagento2shipping-address

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.

Best Answer

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>
Related Topic