How to add custom layout handles programatically for Category View in Magento 2












8















So, I want to add a custom layout handle for all category view pages.. the handle that is supposed to be loaded depends on certain category parameters, so the handle needs to be added programatically with $page->addPageLayoutHandles()



Seems easy..? Apparently not



Magento 2 provides a nice Plugin system that I was naturally going to use, just define a afterExecute() plugin to be run after original category execute() and push any updates into Page object from there.



Unfortunately it does not quite work that way.. reason being that the original execute() method (at the very end) will execute $page->getConfig()->addBodyClass() -- a call to this method will automatically force the layout to be completely loaded and generated, so any subsequent attempts to add new layout handles to Page are completely useless.
I looked around to find any not-so-elegant-ways to achieve the same thing (still using plugins).. did not find any.



I ended up running my own controller for category view, however I would not prefer to leave it that way.



So my question is.. how can I add new page layout handles (programatically) for category view? and do it elegantly.










share|improve this question

























  • What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

    – Giel Berkers
    Jan 25 '17 at 10:00











  • I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

    – Perry Holden
    Feb 7 '18 at 18:25
















8















So, I want to add a custom layout handle for all category view pages.. the handle that is supposed to be loaded depends on certain category parameters, so the handle needs to be added programatically with $page->addPageLayoutHandles()



Seems easy..? Apparently not



Magento 2 provides a nice Plugin system that I was naturally going to use, just define a afterExecute() plugin to be run after original category execute() and push any updates into Page object from there.



Unfortunately it does not quite work that way.. reason being that the original execute() method (at the very end) will execute $page->getConfig()->addBodyClass() -- a call to this method will automatically force the layout to be completely loaded and generated, so any subsequent attempts to add new layout handles to Page are completely useless.
I looked around to find any not-so-elegant-ways to achieve the same thing (still using plugins).. did not find any.



I ended up running my own controller for category view, however I would not prefer to leave it that way.



So my question is.. how can I add new page layout handles (programatically) for category view? and do it elegantly.










share|improve this question

























  • What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

    – Giel Berkers
    Jan 25 '17 at 10:00











  • I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

    – Perry Holden
    Feb 7 '18 at 18:25














8












8








8


2






So, I want to add a custom layout handle for all category view pages.. the handle that is supposed to be loaded depends on certain category parameters, so the handle needs to be added programatically with $page->addPageLayoutHandles()



Seems easy..? Apparently not



Magento 2 provides a nice Plugin system that I was naturally going to use, just define a afterExecute() plugin to be run after original category execute() and push any updates into Page object from there.



Unfortunately it does not quite work that way.. reason being that the original execute() method (at the very end) will execute $page->getConfig()->addBodyClass() -- a call to this method will automatically force the layout to be completely loaded and generated, so any subsequent attempts to add new layout handles to Page are completely useless.
I looked around to find any not-so-elegant-ways to achieve the same thing (still using plugins).. did not find any.



I ended up running my own controller for category view, however I would not prefer to leave it that way.



So my question is.. how can I add new page layout handles (programatically) for category view? and do it elegantly.










share|improve this question
















So, I want to add a custom layout handle for all category view pages.. the handle that is supposed to be loaded depends on certain category parameters, so the handle needs to be added programatically with $page->addPageLayoutHandles()



Seems easy..? Apparently not



Magento 2 provides a nice Plugin system that I was naturally going to use, just define a afterExecute() plugin to be run after original category execute() and push any updates into Page object from there.



Unfortunately it does not quite work that way.. reason being that the original execute() method (at the very end) will execute $page->getConfig()->addBodyClass() -- a call to this method will automatically force the layout to be completely loaded and generated, so any subsequent attempts to add new layout handles to Page are completely useless.
I looked around to find any not-so-elegant-ways to achieve the same thing (still using plugins).. did not find any.



I ended up running my own controller for category view, however I would not prefer to leave it that way.



So my question is.. how can I add new page layout handles (programatically) for category view? and do it elegantly.







magento2 layout layout-update update-handle






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 27 '16 at 9:59









Raphael at Digital Pianism

53.5k19112270




53.5k19112270










asked Jun 27 '16 at 9:49









Kristjan H.Kristjan H.

14112




14112













  • What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

    – Giel Berkers
    Jan 25 '17 at 10:00











  • I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

    – Perry Holden
    Feb 7 '18 at 18:25



















  • What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

    – Giel Berkers
    Jan 25 '17 at 10:00











  • I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

    – Perry Holden
    Feb 7 '18 at 18:25

















What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

– Giel Berkers
Jan 25 '17 at 10:00





What Magento version are you using? Because where can you see that $page->getConfig()->addBodyClass() loads and generates your layout? I'm having a similar task at the moment, only with CMS pages.

– Giel Berkers
Jan 25 '17 at 10:00













I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

– Perry Holden
Feb 7 '18 at 18:25





I am so glad you noted this, as you saved me a bunch of grief. Just FYI: the category view controller also calls the $page->getConfig()->addBodyClass() which makes a plugin useless for accomplishing this.

– Perry Holden
Feb 7 '18 at 18:25










4 Answers
4






active

oldest

votes


















14














The XML way



Well an easy way is to create the following file in your module folder: view/frontend/layout/catalog_category_view.xml with the following content:



<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="your_custom_handle"/>
</page>


It is not more or less elegant than the PHP way and according to what you found it is safer.



The PHP way



Unfortunately in your case, it seems like PHP is the only way to achieve dynamically create handles based on the parameters the category has.



Via plugins



Instead of creating a plugin on the execute() method of your action class, you could directly create a plugin on the addPageLayoutHandles() method of MagentoFrameworkViewResultPage



Main problem is that it will be called every time this method is called and you will have to add some conditions in your plugin code to ensure you're on a category view page.



Via preferences



Another way of doing it would be to use preferences for the category view action class:



<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="MagentoCatalogControllerCategoryView"
type="VendorModuleControllerCategoryView"/>
</config>


Then in your custom controller class you simply override the execute() method by copying/pasting the original method and add your modifications directly in this method.



Main problem is that when you will upgrade your Magento install, if changes are added to the original native Magento action class, it won't reflect in your custom action class.






share|improve this answer


























  • The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

    – Kristjan H.
    Jun 27 '16 at 10:07











  • @KristjanH. hmmm I see it's embarassing, let me dig further

    – Raphael at Digital Pianism
    Jun 27 '16 at 10:13











  • @KristjanH. see my update

    – Raphael at Digital Pianism
    Jun 27 '16 at 10:26






  • 1





    Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

    – Kristjan H.
    Jun 27 '16 at 10:40













  • Did you try any other way after this?

    – LM_Fielding
    Dec 12 '16 at 10:53



















6














I had a similar problem. for categories that do not show product listings I needed an extra handle. after failing to add the handle through the category's Custom Layout XML, I ended up adding it in an observer on the layout_load_before event:



class LayoutLoadBefore implements MagentoFrameworkEventObserverInterface
{
/**
* @var MagentoFrameworkRegistry
*/
protected $_registry;

public function __construct(
MagentoFrameworkRegistry $registry
)
{
$this->_registry = $registry;
}

/**
* add a custom handle to categories of page type 'PAGE'
*
* @param MagentoFrameworkEventObserver $observer
* @return $this
*/
public function execute(MagentoFrameworkEventObserver $observer)
{
$action = $observer->getData('full_action_name');
if ($action != 'catalog_category_view')
return $this;

$category = $this->_registry->registry('current_category');
if (!$category)
return $this;

if ($category->getDisplayMode() == $category::DM_PAGE) {
$layout = $observer->getData('layout');
$layout->getUpdate()->addHandle('catalog_category_view_cms');
}

return $this;
}
}


there is a small performance hit involved as the observer is called for every pageview. unfortunately, all 'category_view' related events seem either too early (category not yet loaded) or too late (layout already processed).






share|improve this answer
























  • Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

    – Giel Berkers
    Jan 25 '17 at 10:07



















1














Let's try observing event layout_load_before. Execute function will be as same as this:



public function execute(MagentoFrameworkEventObserver $observer)
{
if($observer->getFullActionName() == 'catalog_category_view'){
$observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
}
}


Hope this will help






share|improve this answer































    0














    If you still wondering how to do it and what's the best practices and wonder about the store performance, check out this article. Hope it helps you.





    share























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "479"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f122913%2fhow-to-add-custom-layout-handles-programatically-for-category-view-in-magento-2%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      14














      The XML way



      Well an easy way is to create the following file in your module folder: view/frontend/layout/catalog_category_view.xml with the following content:



      <?xml version="1.0"?>
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <update handle="your_custom_handle"/>
      </page>


      It is not more or less elegant than the PHP way and according to what you found it is safer.



      The PHP way



      Unfortunately in your case, it seems like PHP is the only way to achieve dynamically create handles based on the parameters the category has.



      Via plugins



      Instead of creating a plugin on the execute() method of your action class, you could directly create a plugin on the addPageLayoutHandles() method of MagentoFrameworkViewResultPage



      Main problem is that it will be called every time this method is called and you will have to add some conditions in your plugin code to ensure you're on a category view page.



      Via preferences



      Another way of doing it would be to use preferences for the category view action class:



      <?xml version="1.0"?>
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="MagentoCatalogControllerCategoryView"
      type="VendorModuleControllerCategoryView"/>
      </config>


      Then in your custom controller class you simply override the execute() method by copying/pasting the original method and add your modifications directly in this method.



      Main problem is that when you will upgrade your Magento install, if changes are added to the original native Magento action class, it won't reflect in your custom action class.






      share|improve this answer


























      • The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

        – Kristjan H.
        Jun 27 '16 at 10:07











      • @KristjanH. hmmm I see it's embarassing, let me dig further

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:13











      • @KristjanH. see my update

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:26






      • 1





        Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

        – Kristjan H.
        Jun 27 '16 at 10:40













      • Did you try any other way after this?

        – LM_Fielding
        Dec 12 '16 at 10:53
















      14














      The XML way



      Well an easy way is to create the following file in your module folder: view/frontend/layout/catalog_category_view.xml with the following content:



      <?xml version="1.0"?>
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <update handle="your_custom_handle"/>
      </page>


      It is not more or less elegant than the PHP way and according to what you found it is safer.



      The PHP way



      Unfortunately in your case, it seems like PHP is the only way to achieve dynamically create handles based on the parameters the category has.



      Via plugins



      Instead of creating a plugin on the execute() method of your action class, you could directly create a plugin on the addPageLayoutHandles() method of MagentoFrameworkViewResultPage



      Main problem is that it will be called every time this method is called and you will have to add some conditions in your plugin code to ensure you're on a category view page.



      Via preferences



      Another way of doing it would be to use preferences for the category view action class:



      <?xml version="1.0"?>
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="MagentoCatalogControllerCategoryView"
      type="VendorModuleControllerCategoryView"/>
      </config>


      Then in your custom controller class you simply override the execute() method by copying/pasting the original method and add your modifications directly in this method.



      Main problem is that when you will upgrade your Magento install, if changes are added to the original native Magento action class, it won't reflect in your custom action class.






      share|improve this answer


























      • The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

        – Kristjan H.
        Jun 27 '16 at 10:07











      • @KristjanH. hmmm I see it's embarassing, let me dig further

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:13











      • @KristjanH. see my update

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:26






      • 1





        Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

        – Kristjan H.
        Jun 27 '16 at 10:40













      • Did you try any other way after this?

        – LM_Fielding
        Dec 12 '16 at 10:53














      14












      14








      14







      The XML way



      Well an easy way is to create the following file in your module folder: view/frontend/layout/catalog_category_view.xml with the following content:



      <?xml version="1.0"?>
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <update handle="your_custom_handle"/>
      </page>


      It is not more or less elegant than the PHP way and according to what you found it is safer.



      The PHP way



      Unfortunately in your case, it seems like PHP is the only way to achieve dynamically create handles based on the parameters the category has.



      Via plugins



      Instead of creating a plugin on the execute() method of your action class, you could directly create a plugin on the addPageLayoutHandles() method of MagentoFrameworkViewResultPage



      Main problem is that it will be called every time this method is called and you will have to add some conditions in your plugin code to ensure you're on a category view page.



      Via preferences



      Another way of doing it would be to use preferences for the category view action class:



      <?xml version="1.0"?>
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="MagentoCatalogControllerCategoryView"
      type="VendorModuleControllerCategoryView"/>
      </config>


      Then in your custom controller class you simply override the execute() method by copying/pasting the original method and add your modifications directly in this method.



      Main problem is that when you will upgrade your Magento install, if changes are added to the original native Magento action class, it won't reflect in your custom action class.






      share|improve this answer















      The XML way



      Well an easy way is to create the following file in your module folder: view/frontend/layout/catalog_category_view.xml with the following content:



      <?xml version="1.0"?>
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <update handle="your_custom_handle"/>
      </page>


      It is not more or less elegant than the PHP way and according to what you found it is safer.



      The PHP way



      Unfortunately in your case, it seems like PHP is the only way to achieve dynamically create handles based on the parameters the category has.



      Via plugins



      Instead of creating a plugin on the execute() method of your action class, you could directly create a plugin on the addPageLayoutHandles() method of MagentoFrameworkViewResultPage



      Main problem is that it will be called every time this method is called and you will have to add some conditions in your plugin code to ensure you're on a category view page.



      Via preferences



      Another way of doing it would be to use preferences for the category view action class:



      <?xml version="1.0"?>
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="MagentoCatalogControllerCategoryView"
      type="VendorModuleControllerCategoryView"/>
      </config>


      Then in your custom controller class you simply override the execute() method by copying/pasting the original method and add your modifications directly in this method.



      Main problem is that when you will upgrade your Magento install, if changes are added to the original native Magento action class, it won't reflect in your custom action class.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jun 27 '16 at 10:26

























      answered Jun 27 '16 at 9:58









      Raphael at Digital PianismRaphael at Digital Pianism

      53.5k19112270




      53.5k19112270













      • The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

        – Kristjan H.
        Jun 27 '16 at 10:07











      • @KristjanH. hmmm I see it's embarassing, let me dig further

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:13











      • @KristjanH. see my update

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:26






      • 1





        Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

        – Kristjan H.
        Jun 27 '16 at 10:40













      • Did you try any other way after this?

        – LM_Fielding
        Dec 12 '16 at 10:53



















      • The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

        – Kristjan H.
        Jun 27 '16 at 10:07











      • @KristjanH. hmmm I see it's embarassing, let me dig further

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:13











      • @KristjanH. see my update

        – Raphael at Digital Pianism
        Jun 27 '16 at 10:26






      • 1





        Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

        – Kristjan H.
        Jun 27 '16 at 10:40













      • Did you try any other way after this?

        – LM_Fielding
        Dec 12 '16 at 10:53

















      The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

      – Kristjan H.
      Jun 27 '16 at 10:07





      The issue is.. it needs to be programatically added. Simply because the handle being loaded depends on the parameters that the category has.

      – Kristjan H.
      Jun 27 '16 at 10:07













      @KristjanH. hmmm I see it's embarassing, let me dig further

      – Raphael at Digital Pianism
      Jun 27 '16 at 10:13





      @KristjanH. hmmm I see it's embarassing, let me dig further

      – Raphael at Digital Pianism
      Jun 27 '16 at 10:13













      @KristjanH. see my update

      – Raphael at Digital Pianism
      Jun 27 '16 at 10:26





      @KristjanH. see my update

      – Raphael at Digital Pianism
      Jun 27 '16 at 10:26




      1




      1





      Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

      – Kristjan H.
      Jun 27 '16 at 10:40







      Using <preference>.. that is, what I did just before I wrote the question here, however, I'm not happy with that. Same with using a plugin on addPageLayoutHandles, I don't want to call a plugin all the time, even if the performance penalty is non-existent, it's just not right. Let's see if any other solutions appear here.

      – Kristjan H.
      Jun 27 '16 at 10:40















      Did you try any other way after this?

      – LM_Fielding
      Dec 12 '16 at 10:53





      Did you try any other way after this?

      – LM_Fielding
      Dec 12 '16 at 10:53













      6














      I had a similar problem. for categories that do not show product listings I needed an extra handle. after failing to add the handle through the category's Custom Layout XML, I ended up adding it in an observer on the layout_load_before event:



      class LayoutLoadBefore implements MagentoFrameworkEventObserverInterface
      {
      /**
      * @var MagentoFrameworkRegistry
      */
      protected $_registry;

      public function __construct(
      MagentoFrameworkRegistry $registry
      )
      {
      $this->_registry = $registry;
      }

      /**
      * add a custom handle to categories of page type 'PAGE'
      *
      * @param MagentoFrameworkEventObserver $observer
      * @return $this
      */
      public function execute(MagentoFrameworkEventObserver $observer)
      {
      $action = $observer->getData('full_action_name');
      if ($action != 'catalog_category_view')
      return $this;

      $category = $this->_registry->registry('current_category');
      if (!$category)
      return $this;

      if ($category->getDisplayMode() == $category::DM_PAGE) {
      $layout = $observer->getData('layout');
      $layout->getUpdate()->addHandle('catalog_category_view_cms');
      }

      return $this;
      }
      }


      there is a small performance hit involved as the observer is called for every pageview. unfortunately, all 'category_view' related events seem either too early (category not yet loaded) or too late (layout already processed).






      share|improve this answer
























      • Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

        – Giel Berkers
        Jan 25 '17 at 10:07
















      6














      I had a similar problem. for categories that do not show product listings I needed an extra handle. after failing to add the handle through the category's Custom Layout XML, I ended up adding it in an observer on the layout_load_before event:



      class LayoutLoadBefore implements MagentoFrameworkEventObserverInterface
      {
      /**
      * @var MagentoFrameworkRegistry
      */
      protected $_registry;

      public function __construct(
      MagentoFrameworkRegistry $registry
      )
      {
      $this->_registry = $registry;
      }

      /**
      * add a custom handle to categories of page type 'PAGE'
      *
      * @param MagentoFrameworkEventObserver $observer
      * @return $this
      */
      public function execute(MagentoFrameworkEventObserver $observer)
      {
      $action = $observer->getData('full_action_name');
      if ($action != 'catalog_category_view')
      return $this;

      $category = $this->_registry->registry('current_category');
      if (!$category)
      return $this;

      if ($category->getDisplayMode() == $category::DM_PAGE) {
      $layout = $observer->getData('layout');
      $layout->getUpdate()->addHandle('catalog_category_view_cms');
      }

      return $this;
      }
      }


      there is a small performance hit involved as the observer is called for every pageview. unfortunately, all 'category_view' related events seem either too early (category not yet loaded) or too late (layout already processed).






      share|improve this answer
























      • Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

        – Giel Berkers
        Jan 25 '17 at 10:07














      6












      6








      6







      I had a similar problem. for categories that do not show product listings I needed an extra handle. after failing to add the handle through the category's Custom Layout XML, I ended up adding it in an observer on the layout_load_before event:



      class LayoutLoadBefore implements MagentoFrameworkEventObserverInterface
      {
      /**
      * @var MagentoFrameworkRegistry
      */
      protected $_registry;

      public function __construct(
      MagentoFrameworkRegistry $registry
      )
      {
      $this->_registry = $registry;
      }

      /**
      * add a custom handle to categories of page type 'PAGE'
      *
      * @param MagentoFrameworkEventObserver $observer
      * @return $this
      */
      public function execute(MagentoFrameworkEventObserver $observer)
      {
      $action = $observer->getData('full_action_name');
      if ($action != 'catalog_category_view')
      return $this;

      $category = $this->_registry->registry('current_category');
      if (!$category)
      return $this;

      if ($category->getDisplayMode() == $category::DM_PAGE) {
      $layout = $observer->getData('layout');
      $layout->getUpdate()->addHandle('catalog_category_view_cms');
      }

      return $this;
      }
      }


      there is a small performance hit involved as the observer is called for every pageview. unfortunately, all 'category_view' related events seem either too early (category not yet loaded) or too late (layout already processed).






      share|improve this answer













      I had a similar problem. for categories that do not show product listings I needed an extra handle. after failing to add the handle through the category's Custom Layout XML, I ended up adding it in an observer on the layout_load_before event:



      class LayoutLoadBefore implements MagentoFrameworkEventObserverInterface
      {
      /**
      * @var MagentoFrameworkRegistry
      */
      protected $_registry;

      public function __construct(
      MagentoFrameworkRegistry $registry
      )
      {
      $this->_registry = $registry;
      }

      /**
      * add a custom handle to categories of page type 'PAGE'
      *
      * @param MagentoFrameworkEventObserver $observer
      * @return $this
      */
      public function execute(MagentoFrameworkEventObserver $observer)
      {
      $action = $observer->getData('full_action_name');
      if ($action != 'catalog_category_view')
      return $this;

      $category = $this->_registry->registry('current_category');
      if (!$category)
      return $this;

      if ($category->getDisplayMode() == $category::DM_PAGE) {
      $layout = $observer->getData('layout');
      $layout->getUpdate()->addHandle('catalog_category_view_cms');
      }

      return $this;
      }
      }


      there is a small performance hit involved as the observer is called for every pageview. unfortunately, all 'category_view' related events seem either too early (category not yet loaded) or too late (layout already processed).







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jul 30 '16 at 0:51









      alternizealternize

      465211




      465211













      • Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

        – Giel Berkers
        Jan 25 '17 at 10:07



















      • Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

        – Giel Berkers
        Jan 25 '17 at 10:07

















      Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

      – Giel Berkers
      Jan 25 '17 at 10:07





      Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin on MagentoCmsControllerPageView::execute() and MagentoFrameworkViewResultPage::addPageLayoutHandles() or render() didn't do the trick. This last-resort solution was the only solution that worked for me.

      – Giel Berkers
      Jan 25 '17 at 10:07











      1














      Let's try observing event layout_load_before. Execute function will be as same as this:



      public function execute(MagentoFrameworkEventObserver $observer)
      {
      if($observer->getFullActionName() == 'catalog_category_view'){
      $observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
      }
      }


      Hope this will help






      share|improve this answer




























        1














        Let's try observing event layout_load_before. Execute function will be as same as this:



        public function execute(MagentoFrameworkEventObserver $observer)
        {
        if($observer->getFullActionName() == 'catalog_category_view'){
        $observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
        }
        }


        Hope this will help






        share|improve this answer


























          1












          1








          1







          Let's try observing event layout_load_before. Execute function will be as same as this:



          public function execute(MagentoFrameworkEventObserver $observer)
          {
          if($observer->getFullActionName() == 'catalog_category_view'){
          $observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
          }
          }


          Hope this will help






          share|improve this answer













          Let's try observing event layout_load_before. Execute function will be as same as this:



          public function execute(MagentoFrameworkEventObserver $observer)
          {
          if($observer->getFullActionName() == 'catalog_category_view'){
          $observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
          }
          }


          Hope this will help







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 25 '17 at 13:02









          Hồ Trung NghĩaHồ Trung Nghĩa

          111




          111























              0














              If you still wondering how to do it and what's the best practices and wonder about the store performance, check out this article. Hope it helps you.





              share




























                0














                If you still wondering how to do it and what's the best practices and wonder about the store performance, check out this article. Hope it helps you.





                share


























                  0












                  0








                  0







                  If you still wondering how to do it and what's the best practices and wonder about the store performance, check out this article. Hope it helps you.





                  share













                  If you still wondering how to do it and what's the best practices and wonder about the store performance, check out this article. Hope it helps you.






                  share











                  share


                  share










                  answered 7 mins ago









                  Vasilii BurlacuVasilii Burlacu

                  18826




                  18826






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Magento Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f122913%2fhow-to-add-custom-layout-handles-programatically-for-category-view-in-magento-2%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Polycentropodidae

                      Magento 2 Error message: Invalid state change requested

                      Paulmy