0

I need to remove a block named "header_top_content" by using a layout xml file, but only on CMS sites with page layout set to "empty".

Is this possible via layout or not?

I tried it like this:

THEME\Magento_Cms\layout\cms_page_view.xml

<?xml version="1.0" ?>
<page layout="empty" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="header_top_content" remove="true"/>
    </body>
</page>

but it removes the block on ALL cms pages.

2 Answers 2

1

You could use an observer and a custom layout handle.

  • Rename the layout file you posted 'cms_page_view_empty.xml'
  • Add an observer for the event 'layout_load_before'
  • Inside the observer class, add something like this:
    /**
     * @var \Magento\Cms\Api\GetPageByIdentifierInterface
     */
    private $page;
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    public function __construct(
        \Magento\Cms\Api\GetPageByIdentifierInterface $page,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    )
    {
        $this->page = $page;
        $this->storeManager = $storeManager;
    }

    public function execute(Observer $observer)
    {
        $layout = $observer->getLayout()->getUpdate()->getHandles();
        $identifier = str_replace('cms_page_view_id_', '', end($layout));
        $page = $this->page->execute($identifier, $this->storeManager->getStore()->getId());

        if ($page->getPageLayout() == 'empty') {
            $layout->getUpdate()->addHandle('cms_page_view_empty');
        }
    }

That should work.

HTH, Tom


NOTE by Black (OP): The answer does not work, but the basic logic of the code pointed me to the right direction to solve the problem. I posted my working code as an answer.

5
  • On second thought, use the event cms_page_render. It will only fire on cms pages. Test for page layout and add a layout update handle if page layout is empty. Jan 30, 2021 at 13:24
  • Unfortunatelly I get Call to a member function getUpdate() on null
    – Black
    Feb 1, 2021 at 11:45
  • If I try the event layout_load_before, then I get Magento \ Framework \ Exception \ NoSuchEntityException): The CMS page with the ID "am_mega_menu_layout" does not exist.
    – Black
    Feb 1, 2021 at 11:50
  • I added a try catch, now the site loads again, but your solution is not working.
    – Black
    Feb 1, 2021 at 12:04
  • I made some modifications, now it is working! I will post my answer
    – Black
    Feb 1, 2021 at 15:11
1

I created an observer for the event layout_load_before like @Tom van den Heuvel explained.

But I had to make some fixes and modifications:

<?php

namespace Company\Base\Observer;

use \Magento\Framework\Event\ObserverInterface;

/**
 *  Event: layout_load_before
 *  Target: Add handle for CMS sites with page layout "empty".
 *
 *  Check if we are on a CMS site by running through all layout handles
 *  of the site and checking for a layout starting with `cms_page_view_id_` 
 *  and load the page by that handle.
 *  Then check the page layout of the site, and if it is "empty",
 *  then add a new layout handle cms_page_view_empty, so we can change
 *  the layout with the layout file cms_page_view_empty.xml
 */
class CmsPageViewEmpty implements ObserverInterface
{
    /**
     * @var \Magento\Cms\Api\GetPageByIdentifierInterface
     */
    private $page;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    public function __construct(
        \Magento\Cms\Api\GetPageByIdentifierInterface $page,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->page = $page;
        $this->storeManager = $storeManager;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $layout = $observer->getLayout();
        if ($layout == null) { return false; }

        $handles = $layout->getUpdate()->getHandles();

        $handle = array_filter($handles, function($value, $key) {
            return strpos($value, 'cms_page_view_id_') !== false;
        }, ARRAY_FILTER_USE_BOTH);
        
        if (empty($handle)) { return false; }

        $identifier = str_replace('cms_page_view_id_', '', end($handle));
        
        try {
            $page = $this->page->execute($identifier, $this->storeManager->getStore()->getId());
            if ($page->getPageLayout() == 'empty') {
                $layout->getUpdate()->addHandle('cms_page_view_empty');
            }
        } catch (\Magento\Framework\Exception\NoSuchEntityException $ex) {
            //
        }
    }



}

Your Answer

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

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