4

I created a boolean option (Yes / No) in Store -> Configuration, with which I can display or not the checkout sidebar.

The configuration path is: vendorname_sidebar/display/enabled.

Below is a part about sidebar from the layout XML from checkout_index_index.xml of the Checkout module.

How do I show or not show the sidebar in checkout depending on this setting in Store -> Configuration?

<item name="sidebar" xsi:type="array">
    <item name="sortOrder" xsi:type="string">50</item>
    <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item>
    <item name="displayArea" xsi:type="string">sidebar</item>
    ...
</item>
5

In the answers to this question "Remove a UI component child via Layout XML" you can see how you can disable the sidebar UI component by XML. Now you do not want to do this this way, because then it would always be removed/disabled.

If you look at the complete layout XML in checkout_index_index.xml, it looks something like this:

<page ........>
  <body>
    <referenceContainer name="content">
      <block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="onepage.phtml" cacheable="false">
        <arguments>
          <argument name="jsLayout" xsi:type="array">
            <item name="types" xsi:type="array">........</item>
            <item name="components" xsi:type="array">
              <item name="checkout" xsi:type="array">
                <item name="component" xsi:type="string">uiComponent</item>
                ........
                <item name="children" xsi:type="array">
                  ........
                  <item name="sidebar" xsi:type="array">
                    <item name="sortOrder" xsi:type="string">50</item>
                    <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item>
                    <item name="displayArea" xsi:type="string">sidebar</item>
                    <item name="config" xsi:type="array">
                      ........
                    </item>
                    ........

You see that the whole <item ...> XML is part of a bigger <arguments> structure that is a child of the <block class="Magento\Checkout\Block\Onepage" ...> definition. This whole structure is converted to a PHP associative array and passed into the $data argument of the constructor when creating this block class.

The jsLayout is a UI Components definition and you could disable the sidebar component by setting componentDisabled to true in the config.

If we look at the Magento\Checkout\Block\Onepage constructor, we can see what happens to all this data. Also we see that there is an array argument layoutProcessors.

public function __construct(
    ........
    array $layoutProcessors = [],
    array $data = []
) {
    ........
    $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : [];
    $this->layoutProcessors = $layoutProcessors;
}

Now the jsLayout is retreived from the Block by calling its getJsLayout() method which runs the layout processors first before returning the data as JSON:

public function getJsLayout()
{
    foreach ($this->layoutProcessors as $processor) {
        $this->jsLayout = $processor->process($this->jsLayout);
    }
    return \Zend_Json::encode($this->jsLayout);
}

So, you should also add a layout processor via Dependency Injection (DI) in your module's etc/frontend/di.xml:

<config ........>
    <type name="Magento\Checkout\Block\Onepage">
        <arguments>
            <argument name="layoutProcessors" xsi:type="array">
                <item name="sidebarSwitcher" xsi:type="object">Vendorname\Sidebar\Block\CheckoutOnepage\SidebarSwitcherProcessor</item>
            </argument>
        </arguments>
    </type>
</config>

This \Vendorname\Sidebar\Block\CheckoutOnepage\SidebarSwitcherProcessor class should implement \Magento\Checkout\Block\Checkout\LayoutProcessorInterface and (therefor) you should have a public method called process() where you can disable the sidebar based on the config you mention:

namespace Vendorname\Sidebar\Block\CheckoutOnepage;

use Magento\Checkout\Block\Checkout\LayoutProcessorInterface;

class SidebarSwitcherProcessor implements LayoutProcessorInterface
{
    public function process($jsLayout) {
        if (..... check config value .....) {
            $jsLayout['components']['checkout']['children']['sidebar']['config']['componentDisabled'] = true;
        }
        return $jsLayout;
    }
}
| improve this answer | |
  • Isn't works for me. – St3phan Jan 11 '18 at 18:19
  • What did you try? Did you see if it reaches the process() method? (add logging or use xdebug) – 7ochem Jan 11 '18 at 19:03
  • You inspired me with your answer and I managed to do what I wanted, see my answer. Thanks – St3phan Jan 11 '18 at 21:28
  • Your answer is very explicit. I gave you a vote. – St3phan Jan 11 '18 at 21:30
  • 1
    It works perfectly for me ! @7ochem thank you for all the details and explanation. – eInyzant Mar 30 '18 at 3:33
1

For use Scope Config Interface on the component from checkout page, you must create a Plugin see below:

Below code is must in Vendorname/SidebarActivation/etc/frontend/di.xml

<?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\Block\Checkout\LayoutProcessor">
        <plugin name="SidebarDisable" type="Vendorname\SidebarActivation\Plugin\SidebarDisable"/>
    </type>
</config>

Below code is in Vendorname/SidebarActivation/Plugin/SidebarDisable.php

<?php

namespace Vendorname\SidebarActivation\Plugin;

use Magento\Checkout\Block\Checkout\LayoutProcessor;

/**
 * Class SidebarDisable
 *
 * @package Vendorname\SidebarActivation\Plugin
 */
class SidebarDisable {

    /**
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $processor
     * @param array $jsLayout
     *
     * @return array
     */
    public function afterProcess(
        LayoutProcessor $processor,
        array $jsLayout
    ){
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $enable = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface')->getValue('sectionid/groupid/fieldid');

        if($enable){
            $jsLayout['components']['checkout']['children']['sidebar']['config']['componentDisabled'] = true;
        }

        return $jsLayout;
    }
}
| improve this answer | |
  • Nice solution. It is getting quite complex having a plugin on an object pool (layout processors) though, but still a good alternative. Also you shouldn't use the object manager, inject it in the constructor of your plugin instead. – 7ochem Jan 11 '18 at 21:34
  • I tried to put in the constructor but it does not work, it gives me the white page, I know it's good with the constructor but it does not work. – St3phan Jan 11 '18 at 21:40
  • I am a big fan and I use the constructor. – St3phan Jan 11 '18 at 21:41

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.