1

We created a custom phtml template with some customer specific php, that must be loaded for each customer/pageload again. So we created the phtml template and added the following code to layout/default.xml

The problem now is that this element is cached by block cache and FPC (Varnish). We do kno that it's possible to add the cacheable="false, but this prevents the entire page from being cached. And this custom template is loaded on each page, so then we disable the entire cache. How can we exclude this template from being cached?

Found also this tutorial, but we do need to display some php code instead of just a simple text line; https://aureatelabs.com/blog/how-to-use-private-content-or-sections-in-magento-2/

Code of default.xml in Magento_Theme:

<referenceContainer name="after.body.start">
   <block class="Magento\Framework\View\Element\Template" name="country_switch_notice" template="Magento_Theme::html/switch_notice.phtml" before="-" />     
</referenceContainer>

Code of custom.phtml;

<?php
$locale = Locale::acceptFromHttp($_SERVER['HTTP_CF_IPCOUNTRY']);
?>
<?php if ($locale == "be"):?>

HTML CODE
    
<?php elseif ($locale == "uk"):?>

HTML CODE

<?php endif;?>
2
  • Can you share your PHTML file and also let me know which layout you are using? I'll check for more details.
    – Msquare
    Commented Dec 7, 2023 at 20:39
  • @Msquare See my edit
    – JGeer
    Commented Dec 8, 2023 at 7:34

2 Answers 2

3
+50

I have created a new custom section for updating content from the cache block. Please check the code below for more details.

app/code/VendorName/ModuleName

registration.php

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

app/code/VendorName/ModuleName/etc

module.xml

<?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="VendorName_ModuleName" setup_version="1.0.0">
    </module>
</config>

app/code/VendorName/ModuleName/etc/frontend

di.xml

<?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">VendorName\ModuleName\CustomerData\CustomSection</item>
            </argument>
        </arguments>
    </type>
</config>

app/code/VendorName/ModuleName/CustomerData

CustomSection.php

<?php

namespace VendorName\ModuleName\CustomerData;

use Magento\Customer\CustomerData\SectionSourceInterface;

class CustomSection implements SectionSourceInterface
{
    protected $resultPageFactory;

    public function __construct(
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        $this->resultPageFactory = $resultPageFactory;
    }

    public function getSectionData()
    {
        $resultPage = $this->resultPageFactory->create();
        $block = $resultPage->getLayout()
                ->createBlock(\Magento\Framework\View\Element\Template::class)
                ->setTemplate("VendorName_ModuleName::custom.phtml")
                ->toHtml();
        return [
            'customdata' => $block,
        ];
    }
}

app/code/VendorName/ModuleName/etc/frontend

sections.xml

<?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="custom_section"/>
    </action>
</config>

app/code/VendorName/ModuleName/view/frontend/layout

default.xml

<?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="content">
            <block class="Magento\Framework\View\Element\Template" name="custom.file.cacheable" template="VendorName_ModuleName::custom_cacheble.phtml" />
        </referenceContainer>
    </body>
</page>

app/code/VendorName/ModuleName/view/frontend/templates

custom_cacheble.phtml

<div class="custom-section-show" data-bind="scope: 'section'">
    <div data-bind="html: customsection().customdata"></div>
</div>
<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "section": {
                        "component": "VendorName_ModuleName/js/section"
                    }
                }
            }
        }
    }
</script>

app/code/VendorName/ModuleName/view/frontend/templates

custom.phtml

<?php
// $locale = Locale::acceptFromHttp($_SERVER['HTTP_CF_IPCOUNTRY']);
$locale = 'be';
?>
<?php if ($locale == "be"):?>

<h1>HTML CODE BE</h1>

<?php elseif ($locale == "uk"):?>

<h1>HTML CODE UK</h1>


<?php endif;?>

app/code/VendorName/ModuleName/view/frontend/web/js

section.js

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

    return Component.extend({
        initialize: function () {
            this._super();
            var sections = ['custom_section'];
            customerData.invalidate(sections);
            customerData.reload(sections, true);
            this.customsection = customerData.get('custom_section');
        }
    });
});

OUTPUT enter image description here

1
  • Works perfect :)
    – JGeer
    Commented Dec 8, 2023 at 15:36
1

There are 2 ways to fix this

Either use ajax to load your content for this block via controller

OR

use Private Content https://developer.adobe.com/commerce/php/development/cache/page/private-content/

1
  • Thanks! Can you provide an example to achieve this? Maybe using a custom module?
    – JGeer
    Commented Dec 5, 2023 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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