How to add custom layout handles programatically for Category View in Magento 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.
magento2 layout layout-update update-handle
add a comment |
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
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
add a comment |
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
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
magento2 layout layout-update update-handle
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
add a comment |
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
add a comment |
4 Answers
4
active
oldest
votes
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.
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
add a comment |
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).
Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin onMagentoCmsControllerPageView::execute()
andMagentoFrameworkViewResultPage::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
add a comment |
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
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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).
Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin onMagentoCmsControllerPageView::execute()
andMagentoFrameworkViewResultPage::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
add a comment |
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).
Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin onMagentoCmsControllerPageView::execute()
andMagentoFrameworkViewResultPage::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
add a comment |
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).
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).
answered Jul 30 '16 at 0:51
alternizealternize
465211
465211
Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin onMagentoCmsControllerPageView::execute()
andMagentoFrameworkViewResultPage::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
add a comment |
Thanks! I had a similar problem (magento.stackexchange.com/questions/156231/…) and a plugin onMagentoCmsControllerPageView::execute()
andMagentoFrameworkViewResultPage::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
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Aug 25 '17 at 13:02
Hồ Trung NghĩaHồ Trung Nghĩa
111
111
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 7 mins ago
Vasilii BurlacuVasilii Burlacu
18826
18826
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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