Magento 2 - remove block if page layout is XY
-
15-04-2021 - |
Вопрос
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
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) {
//
}
}
}
Другие советы
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.
Не связан с magento.stackexchange