0

I want to Update XML using observer on Product Page when page load.
I want to set there condition with product Attribute there.
How can I do that?

3

What you can do is add layout via event layout_load_before, you can use this event to add your dynamic layout.

Here is sample code for you.

step: 1 create events.xml in your module

[Vendor]/[Module]/etc/events.xml

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
        <!-- for diffrentiate layout.xml on product basis -->
        <event name="layout_load_before">
            <observer name="load_custom_handler" instance="[Vendor]\[Module]\Observer\LayoutLoadBefore" />
        </event>
    </config>

Step:2 Now create observer LayoutLoadBefore.php

In your [Vendor][Module]\Observer\LayoutLoadBefore.php file write below code

    <?php

    namespace [Vendor]\[Module]\Observer;

    class LayoutLoadBefore implements \Magento\Framework\Event\ObserverInterface
    {
        /**
         * @var \Magento\Framework\Registry
         */
        protected $_registry;

        public function __construct(
           \Magento\Framework\Registry $registry,
        )
        {
            $this->_registry = $registry;
        }


        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            $product = $this->_registry->registry('current_product');

            if (!$product){
              return $this;
            }
            if($product->getSku() =='product_sku'){ // add your multiple attribute condition
               $layout = $observer->getLayout();
               $layout->getUpdate()->addHandle('catalog_product_view_customlayout'); 
// here you will have to set custom layout which is for specific layout.
            }

            return $this;
        }
    }

Step 3: Create layout file for custom layout.

Create layout file in your custom theme/ custom module.

[Theme]/frontend/Magento_catalog/layout/catalog_product_view_customlayout.xml

or

[Vendor]/[Module]/view/frontend/layout/catalog_product_view_customlayout.xml

and write your code.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        ...
            //write your custm code here.
        ...
    </body>
</page>

This file only rendered in your specific condition of products.

now in this file you can add your special requirements.

Hope this will help you !..

1

I wouldn't use an observer to be honest, but a plugin.

Wrap it around Magento\Catalog\Helper\Product\View.

Something like this:

class AroundHelperProductView
{
    public function aroundinitProductLayout(
        \Magento\Catalog\Helper\Product\View $subject, 
        callable $proceed,
        \Magento\Framework\View\Result\Page $resultPage, 
        $product, 
        $params = null
    ) {

        $result = $proceed($resultPage, $product, $params);

        $resultPage->addPageLayoutHandles(['attribute' => 'value'], 'catalog_product_view');

        return $result;
    }
}

That way you get a catalog_product_view_attribute_value.xml definition that you can fill with whatever you need. Be aware that attribute and value in the filename are dependent on what you place in the Plugin. Optionally you can loop through the different values from an attribute and add a handle for each unique value.

Update: Noticed I forgot the handle after the params in the function call.

0

Instead of Observer you can use Plugin(interceptors) concept.By using before, after and around methods you can manipulate your layout.

for example : in any block we have getChildHtml($alias = '', $useCache = true). for this one you can make

public function beforeGetChildHtml(/* your source class */ $subject,$alias = '', $useCache = true)
{
    $layout = $subject->getLayout();

    if (!$layout) {
        return '';
    }
    $childName = $layout->getChildName($subject->getNameInLayout(), $alias);
    if (!$childName) {
        return '';
    }
    if($childName=="/*your block name */")
    {
        addchild to your block
    }
}

Same way you can use after and around as per your requirement

read devdocs for more information https://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

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.