5

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.

10

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

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!

  • Doesn't seem as clean as Aaron's approach, but probably still working well :-) – Alex May 23 at 10:06
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, privacy policy and cookie policy

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