Question

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.

Was it helpful?

Solution 2

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) {
            //
        }
    }



}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top