Итак, я хочу добавить собственный дескриптор макета для всех страниц просмотра категорий ... дескриптор, который должен быть загружен, зависит от определенных параметров категории, поэтому дескриптор необходимо добавлять программно с помощью $page->addPageLayoutHandles()
Кажется легким ..? Очевидно нет
Magento 2 предоставляет замечательную систему плагинов, которую я собирался использовать естественным образом, просто определите afterExecute()
плагин, который будет запускаться после исходной категории, execute()
и вставляйте любые обновления в объект Page оттуда.
К сожалению, это не совсем так работает .. причина в том, что оригинальный execute()
метод (в самом конце) будет выполнен $page->getConfig()->addBodyClass()
- вызов этого метода автоматически заставит макет быть полностью загруженным и сгенерированным, поэтому любые последующие попытки добавить новый Дескрипторы макета для Page совершенно бесполезны. Я посмотрел вокруг, чтобы найти какие-то не очень элегантные способы достижения того же самого (все еще используя плагины) .. не нашел ни одного.
В итоге я запустил свой собственный контроллер для просмотра категорий, однако я бы не хотел оставлять его таким.
Итак, мой вопрос ... как я могу добавить новые маркеры макета страницы (программно) для просмотра по категориям? и сделать это элегантно.
источник
$page->getConfig()->addBodyClass()
загружает и генерирует ваш макет? У меня сейчас аналогичная задача, только со страницами CMS.Ответы:
Способ XML
Самый простой способ - создать следующий файл в папке вашего модуля:
view/frontend/layout/catalog_category_view.xml
со следующим содержимым:Он не более или менее элегантен, чем способ PHP, и в соответствии с тем, что вы нашли, безопаснее.
PHP путь
К сожалению, в вашем случае кажется, что PHP - единственный способ динамически создавать дескрипторы, основанные на параметрах, которые имеет категория.
Через плагины
Вместо создания плагина для
execute()
метода вашего класса действий, вы можете напрямую создать плагин дляaddPageLayoutHandles()
методаMagento\Framework\View\Result\Page
Основная проблема заключается в том, что он будет вызываться каждый раз, когда вызывается этот метод, и вам придется добавить некоторые условия в код вашего плагина, чтобы убедиться, что вы находитесь на странице просмотра категории.
Через настройки
Еще один способ сделать это - использовать настройки для класса действий представления категории:
Затем в своем пользовательском классе контроллера вы просто переопределяете
execute()
метод, копируя / вставляя оригинальный метод и добавляя свои изменения непосредственно в этот метод.Основная проблема заключается в том, что при обновлении установки Magento, если изменения будут добавлены в исходный собственный класс действий Magento, он не будет отражаться в вашем классе пользовательских действий.
источник
У меня была аналогичная проблема. для категорий, которые не показывают списки продуктов, мне нужна дополнительная ручка. после того, как не удалось добавить дескриптор через XML пользовательского макета категории, я добавил его в качестве наблюдателя на
layout_load_before
событие:Это связано с небольшим падением производительности, поскольку для каждого просмотра страницы вызывается наблюдатель. к сожалению, все события, связанные с 'category_view', кажутся либо слишком ранними (категория еще не загружена), либо слишком поздними (макет уже обработан).
источник
\Magento\Cms\Controller\Page\View::execute()
и я\Magento\Framework\View\Result\Page::addPageLayoutHandles() or render()
не справился. Это последнее средство было единственным решением, которое сработало для меня.Давайте попробуем наблюдать за событием layout_load_before. Выполнить функцию будет так же, как это:
Надеюсь, это поможет
источник