3

I create custom page layout. In admin area select this layout:

Amin -> Products -> Categories -> MyCategory -> Design -> Layout

Q: How add css class to body tag?

My file:

app/design/frontend/{Vendor}/{theme}/Magento_Theme/page_layout/custom.xml

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
    <update handle="1column"/>
    <!-- my references -->
</layout>

Tried, but not work:

<body>
    <attribute name="class" value="my-class" />
</body>
----------------------
<referenceContainer name="root" htmlClass="my-class" />
----------------------
<referenceContainer name="root">
    <argument name="css_class" xsi:type="string">my-class</argument>
</referenceContainer>

Update. PY Yick answer not work too (for me):

<referenceContainer name="root">
    <arguments>
        <argument name="css_class" xsi:type="string">my-class</argument>
    </arguments>
</referenceContainer>
8

 Page Layout XML

As far as I'm aware this isn't possible out of the box via page layout XML, the existing implementation is done via PHP (checkout the addDefaultBodyClasses() function here);

/**
 * Add default body classes for current page layout
 *
 * @return $this
 */
protected function addDefaultBodyClasses()
{
    $this->pageConfig->addBodyClass($this->request->getFullActionName('-'));
    $pageLayout = $this->getPageLayout();
    if ($pageLayout) {
        $this->pageConfig->addBodyClass('page-layout-' . $pageLayout);
    }
    return $this;
}

Layout XML

Just in case anyone ends up on this question for standard layout XML it can be done this way:

Add the following attribute inside the <body> tags.

<body>
    <attribute name="class" value="your-class"/>
</body>

If this doesn't work you may need to clear your caches?

  • Thank you for trying help. But i wrote that it not work. It work only for "<page "urn:magento:framework:View/Layout/etc/page_configuration.xsd">" – orthener Jun 30 '17 at 12:16
  • I didn't notice it was a page layout sorry, I don't think it's possible out the box. I've updated my answer with my findings. – Ben Crook Jun 30 '17 at 12:51
1

You're almost there. Change <referenceContainer name="root"> to the following code:

<referenceContainer name="root">
    <arguments>
        <argument name="css_class" xsi:type="string">my-class</argument>
    </arguments>
</referenceContainer>

Ref: http://devdocs.magento.com/guides/v2.1/frontend-dev-guide/layouts/xml-instructions.html#fedg_layout_xml-instruc_ex_ref

1

The only solution i've found is to add a class to the root container. This element will be displayed immediately after the body tag.

I've used this code:

<referenceContainer name="root" htmlTag="div" htmlClass="custom-class">
</referenceContainer>

For me worked in the Layout Update XML for CMS pages and categories.

Unfortunately is the only solution iv'e found similar to the old "addBodyClass".

0

My own workaround: use autogenerated class. Magento 2 add class to <body> that based on layout name:

page-layout-{layout-id}

Example. My page-layout file name "category-blog.xml". Body will have class "page-layout-category-blog".

0

You can do this using a plugin:

Create the file app/code/Myvendor/Mymodule/etc/frontend/di.xml with the following content:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">


<type name="Magento\Framework\View\Result\Page">
<plugin name="myModuleResultPage" type="Myvendor\Mymodule\Plugin\Result\Page"/>
</type>

</config>

Create the file app/code/Myvendor/Mymodule/Plugin/Result/Page.php with the following content:

<?php
namespace Myvendor\Mymodule\Plugin\Result;

use Magento\Framework\App\ResponseInterface;

class Page
{
private $context;
private $registry;

public function __construct(
\Magento\Framework\View\Element\Context $context,
\Magento\Framework\Registry $registry
) {
$this->context = $context;
$this->registry = $registry;
}

public function beforeRenderResult(
\Magento\Framework\View\Result\Page $subject,
ResponseInterface $response
){

$category = $this->registry->registry('current_category');

if($this->context->getRequest()->getFullActionName() == 'catalog_category_view'
  && $category 
  && $category->getId() == <some_category_id>){
   $subject->getConfig()->addBodyClass('my_custom_class');
}

return [$response];
}
}

Replace the "some_category_id" with the category id that you want to add the custom body class in.

Note: In order to this solution to work, you need a working plugin "Myvendor_Mymodule", if you don't have the plugin, just do the following to create it:

Create the following file -

app/code/Myvendor/Mymodule/etc/module.xml

With the following content

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Myvendor_Mymodule" setup_version="1.0.0" />
</config>

And the following file - app/code/Myvendor/Mymodule/registration.php

with the following content -

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Myvendor_Mymodule',
__DIR__
);

Reference: https://www.mexbs.com/magento-blog/adding-custom-body-class-magento2/

0

You can do this using a Observer:

=> Create the file :

app/code/Myvendor/Mymodule/etc/frontend/event.xml with the following content:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <event name="layout_generate_blocks_after">
        <observer name="samgranger_storecodebodyclass" instance="Myvendor\Mymodule\Observer\AddBodyClass" shared="false" />
    </event>
</config>

=> Create the file :

app/code/Myvendor/Mymodule/Observer/AddBodyClass.php with the following content:

<?php
namespace Myvendor\Mymodule\Observer;

use Magento\Framework\View\Page\Config;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer as EventObserver;

class AddBodyClass implements ObserverInterface
{
    public function __construct(
        Config $config
    ){
        $this->config = $config;
    }

    public function execute(EventObserver $observer){
        $name = $observer->getFullActionName();
        $layout = $observer->getLayout();
        if($name == "amblog_index_category") {
            $this->config->addBodyClass("events-page");
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.