Magento2 | PWA | GraphQL

How to use Private Content or Sections in Magento 2?


Since private content is specific to individual users, it’s reasonable to handle it on the client side i.e. web browser.

A section is a piece of customer data grouped together. Each section is represented by the key that is used to access and manage data itself.

Magento loads sections by AJAX request to /customer/section/load/ and caches loaded data in the browser local storage under the key mage-cache-storage. Magento tracks when some section is changed and load updated section automatically.

We will create Magelearn_Customsection module to understand this topic.

You can find complete module on github at Magelearn_Customsection

Follow the below steps to define the custom section and use the data of the custom section in our custom phtml file.

Step 1: Define a custom section


Create folder in app/code/Magelearn/Customsection

Add registration.php file in it:
<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magelearn_Customsection', __DIR__);
Add composer.json file in it:
{
    "name": "magelearn/module-customsection",
    "description": "Magento2 display private section content using JS component",
    "type": "magento2-module",
    "license": "OSL-3.0",
    "authors": [
        {
            "email": "info@mage2gen.com",
            "name": "Mage2Gen"
        },
        {
            "email": "vijaymrami@gmail.com",
            "name": "vijay rami"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\Customsection\\": ""
        }
    }
}
Add etc/module.xml file in it:
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Magelearn_Customsection" setup_version="1.0.0">
    </module>
</config>
Add etc/frontend/di.xml file in it:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\CustomerData\SectionPoolInterface">
    	<arguments>
        	<argument name="sectionSourceMap" xsi:type="array">
            	<item name="custom_section" xsi:type="string">Magelearn\Customsection\CustomerData\CustomSection</item>
        	</argument>
    	</arguments>
    </type>
</config>
Add CustomerData/CustomSection.php file in it:
<?php
namespace Magelearn\Customsection\CustomerData;
use Magento\Customer\CustomerData\SectionSourceInterface;

class CustomSection implements SectionSourceInterface
{
    public function getSectionData()
    {
    	return [
        	'customdata' => "We are getting data from custom section",
    	];
    }
}
In getSectionData() method we will define our data that we want to store in section.

Step 2: Display custom section data in frontend


We will display our custom section data in the product view page. You can get section data in any Magento pages.

Now, Add view/frontend/layout/catalog_product_view.xml file in it:
<?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">
    <body>
    	<referenceContainer name="product.info.main">
        	<block class="Magento\Catalog\Block\Product\View" name="magelearn_custom_section" after="-" template="Magelearn_Customsection::custom_section.phtml" />
    	</referenceContainer>
    </body>
</page>
Now, Add view/frontend/templates/custom_section.phtml file in it:
<div class="magelearn-custom-section" data-bind="scope: 'section'">
    <p data-bind="text: customsection().customdata"></p>
</div>
<script type="text/x-magento-init">
    {
    	"*": {
        	"Magento_Ui/js/core/app": {
            	"components": {
                	"section": {
                    	"component": "Magelearn_Customsection/js/section"
                	}
            	}
        	}
    	}
    }
</script>
Here we write data-bind:"scope: 'section'"
So, that's why in JS we have written syntax like  
<script type="text/x-magento-init">
    {
    	"*": {
        	"Magento_Ui/js/core/app": {
            	"components": {
                	"section": {
                    	"component": "Magelearn_Customsection/js/section"
                	}
            	}
        	}
    	}
    }
</script>
To call a JS component on an HTML element without direct access to the element or with no relation to a certain element, use the
tag. Check below syntax for more details:

Now, Add view/frontend/web/js/section.js file in it:
define([
    'uiComponent',
    'Magento_Customer/js/customer-data'
], function (Component, customerData) {
    'use strict';

    return Component.extend({
    	initialize: function () {
        	this._super();
        	this.customsection = customerData.get('custom_section');
    	}
    });
});
  • The initialize() method is called during instantiation. It can be used to add custom functionality executed only once, during component instance creation.
  • The _super() method calls the parent UI component method with the same name as the _super() method’s caller. If that method does not exists in the parent UI component, then the method tries to find it higher in the inheritance chain.

Now run the below command and check on any product view page.

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush



You can see the custom section data in the product view page.

You can also verify custom section is loaded or not by running below url

{store_url}/customer/section/load/?sections=custom_section



You can see custom section data in browser local storage.

In the section.js file, we have used Magento_Customer/js/customer-data as this Magento js library file is responsible for set section data and get section data. Section data gets updated when ajax call with the post, put, delete requests are made.

Additional Information


When caching is enabled the whole page content is cached so sections help us to dynamically manage the components of the page.

For example, the complete page is cached, Now when the customer logs in or logs out only the components get updated with the value from the section as you can see the customer name, cart, wish list are all managed by section.

All sections data are fetched in one single ajax call, hence the number of ajax requests are reduced to a huge number.

Magento assumes that section data is changed when a customer sends some state modification request (POST, PUT, DELETE). To minimize the load on the server, developers should specify which action (or request) updates which customer data section in etc/frontend/sections.xml.

You can refer Magento/Catalog/etc/frontend/sections.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="catalog/product_compare/add">
    	<section name="compare-products"/>
    </action>
    <action name="catalog/product_compare/remove">
    	<section name="compare-products"/>
    </action>
    <action name="catalog/product_compare/clear">
    	<section name="compare-products"/>
    </action>
    <action name="customer/account/logout">
    	<section name="recently_viewed_product"/>
    	<section name="recently_compared_product"/>
    </action>
</config>

In the section.xml file, they have defined update the compare-products section when one of these actions catalog/product_compare/add,  catalog/product_compare/remove, catalog/product_compare/clear are requested.

If the action name is * that means that section will be updated on each POST and PUT request. If the section tag is missed then all sections will be updated.

You can refer Magento/Theme/etc/frontend/sections.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="*">
        <section name="messages"/>
    </action>
</config>

In the section.xml file, they have defined update the messages section on each POST and PUT request.

If you want to reload your custom section data when the page refreshed then you have to reload your custom section data in your js file.

define([
    'uiComponent',
    'Magento_Customer/js/customer-data'
], function (Component, customerData) {
    'use strict';

    return Component.extend({
    	initialize: function () {
        	this._super();
        	customerData.reload('custom_section');
        	this.customsection = customerData.get('custom_section');
    	}
    });
});
 

Here we have added customerData.reload('custom_section'); to reload section data whenever we refresh the page.

Tag : Magento2
0 Comments On "How to use Private Content or Sections in Magento 2?"

Back To Top