बिना नाम के लेआउट से ब्लॉक निकालें


12

मैं Magento 2 में लेआउट से एक ब्लॉक को निकालना चाहता हूं जिसे तीसरे पक्ष के विस्तार में घोषित किया गया है, लेकिन ब्लॉक का कोई नाम नहीं है।
क्या मै वह कर सकता हूं?

ब्लॉक को इस तरह घोषित किया जाता है

<referenceContainer name="before.body.end">
    <block class="Magento\Backend\Block\Template" template="[Vendor_Module]::template.phtml"/>
</referenceContainer>

मैं उपयोग नहीं कर सकता

<referenceBlock name="..." remove="true" /> 

क्योंकि, जैसा कि आप देख सकते हैं कि इस पर कोई नाम नहीं है।


Marius, मैं IDEA.IF हम मैच टेम्पलेट नाम से घटना और निकालने के ब्लॉक का उपयोग किया है [Vendor_Module]::template.phtml
अमित बेरा

मेरे पास एक ही विचार है (उत्तर पर टिप्पणी देखें) लेकिन मैं इसे केवल एक हताश उपाय के रूप में उपयोग करूंगा। मैं एक सरल समाधान की उम्मीद कर रहा था। यदि आपके पास कुछ कोड है, तो उसे उत्तर के रूप में पोस्ट करें।
मेरियस

हा हा हम donot सरल solution.let है कि मुझे यू घटना का उपयोग कर उत्तर देने की कोशिश
अमित बेरा

जवाबों:


5

मुझे यह मुद्दा कक्षा में मिला Magento\Framework\View\Layout\ScheduledStructure\Helper

समारोह है _generateAnonymousName:

protected function _generateAnonymousName($class)
{
    $position = strpos($class, '\\Block\\');
    $key = $position !== false ? substr($class, $position + 7) : $class;
    $key = strtolower(trim($key, '_'));
    return $key . $this->counter++;
}

यह scheduleStructureफ़ंक्शन से कॉल करता है:

    public function scheduleStructure(
    Layout\ScheduledStructure $scheduledStructure,
    Layout\Element $currentNode,
    Layout\Element $parentNode
) {
    // if it hasn't a name it must be generated
    if (!(string)$currentNode->getAttribute('name')) {
        $name = $this->_generateAnonymousName($parentNode->getElementName() . '_schedule_block'); // CALL HERE
        $currentNode->setAttribute('name', $name);
    }
    $path = $name = (string)$currentNode->getAttribute('name');

    // Prepare scheduled element with default parameters [type, alias, parentName, siblingName, isAfter]
    $row = [
        self::SCHEDULED_STRUCTURE_INDEX_TYPE           => $currentNode->getName(),
        self::SCHEDULED_STRUCTURE_INDEX_ALIAS          => '',
        self::SCHEDULED_STRUCTURE_INDEX_PARENT_NAME    => '',
        self::SCHEDULED_STRUCTURE_INDEX_SIBLING_NAME   => null,
        self::SCHEDULED_STRUCTURE_INDEX_IS_AFTER       => true,
    ];

    $parentName = $parentNode->getElementName();
    //if this element has a parent element, there must be reset [alias, parentName, siblingName, isAfter]
    if ($parentName) {
        $row[self::SCHEDULED_STRUCTURE_INDEX_ALIAS] = (string)$currentNode->getAttribute('as');
        $row[self::SCHEDULED_STRUCTURE_INDEX_PARENT_NAME] = $parentName;

        list($row[self::SCHEDULED_STRUCTURE_INDEX_SIBLING_NAME],
            $row[self::SCHEDULED_STRUCTURE_INDEX_IS_AFTER]) = $this->_beforeAfterToSibling($currentNode);

        // materialized path for referencing nodes in the plain array of _scheduledStructure
        if ($scheduledStructure->hasPath($parentName)) {
            $path = $scheduledStructure->getPath($parentName) . '/' . $path;
        }
    }

    $this->_overrideElementWorkaround($scheduledStructure, $name, $path);
    $scheduledStructure->setPathElement($name, $path);
    $scheduledStructure->setStructureElement($name, $row);
    return $name;
}

इस मामले के साथ, ब्लॉक का नाम हो सकता है:

  • before.body.end_schedule_block1
  • before.body.end_schedule_block2
  • ...

मुझे लगता है कि आपको कंटेनर पर नाम के बिना योग ब्लॉक को परिभाषित करना चाहिए और कंटेनर पर ऑर्डर ब्लॉक नाम को हटाने की आवश्यकता है।


मुझे नहीं लगता कि यह काम करेगा। जेनरेट किए गए नाम का अनुमान लगाने का कोई तरीका नहीं है क्योंकि विभिन्न पृष्ठों पर body.before.endकंटेनर में अलग-अलग क्रम में कई ब्लॉक जोड़े जा सकते हैं ।
मेरियस

यह मामला केवल एक नाम के बिना ब्लॉक / कंटेनर पर लागू होता है। यदि नाम के बिना उनमें से सभी, तो कुछ ब्लॉक / कंटेनर को हटाने की आवश्यकता को परिभाषित करना मुश्किल है।
थाओ फाम

हां ... मेरी समस्या बिल्कुल
मेरियस

हमें फिर से लिखना चाहिए $name = $this->_generateAnonymousName($parentNode->getElementName() . '_schedule_block');, पैरामीटर के लिए कक्षा और टेम्पलेट पास करना चाहिए?
थाओ फाम

2
ऐसा लगता है जैसे कुछ लिखने के लिए एक ओवरहेड। मैं एक सरल समाधान (यदि कोई हो) या 'बहुत आसानी से संभव नहीं' जैसे उत्तर की तलाश में हूं। मुझे लगता है कि मैं लेआउट को ब्लॉक घटना या इसे हटाने के लिए कुछ का निरीक्षण कर सकता हूं, लेकिन फिर से बहुत अधिक लगता है। मैं एक बैकअप समाधान के रूप में रख रहा हूँ।
मेरियस

3

मैं वास्तव में यू बुरा विचार दे रहा हूं।

यहां यह विचार आपके ब्लॉक का आउटपुट बंद नहीं करता है

घटना का उपयोग करना view_block_abstract_to_html_after

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="view_block_abstract_to_html_after">
        <observer name="myObserverName" instance="Stack\Work\Observer\MyObserver" />
    </event>
</config>

और इस पर्यवेक्षक का उपयोग करके अपने ब्लॉक का आउटपुट अक्षम करें

<?php
namespace Stack\Work\Observer;
use Magento\Framework\Event\ObserverInterface;

class MyObserver implements ObserverInterface
{
  public function __construct()
  {
    //Observer initialization code...
    //You can use dependency injection to get any class this observer may need.
  }

  public function execute(\Magento\Framework\Event\Observer $observer)
  {
    $block = $observer->getData('block');

    if('[Vendor_Module]::template.phtml' == $block->getTemplate()){
        $transport = $observer->getData('transport');
        $transport->setHtml('');

    }
  }
}

यह वास्तव में इतना बुरा विचार नहीं है। वास्तव में सभी ब्लॉकों का अवलोकन करने वाला एक ओवरकिल है, लेकिन मैं इसे अन्य विकल्पों पर उपयोग करने के लिए तैयार हूं। मैं कोशिश करूंगा और आपको बताऊंगा।
मेरियस

coool। आदमी .... देखो क्या होता है
अमित बेरा

1
यह काम करता है, लेकिन मैंने इसे थोड़ा अनुकूलित करने की कोशिश की, न कि हर ब्लॉक के कोड को निष्पादित करने के लिए। तो मैं अपने जवाब के साथ समाप्त हुआ । विचार के लिए धन्यवाद।
मेरियस

मैं जवाब है कि वास्तव में अच्छा आदमी :) देखते हैं,
अमित बेरा

3

मुझे अमित के जवाब से एक विचार आया और एक काम करने वाले समाधान के साथ समाप्त हुआ जो बहुत दखल नहीं देता है और यह एक ओवरकिल नहीं है क्योंकि मेरे कोड को केवल एक बार निष्पादित किया गया है।

मैंने उस घटना पर एक पर्यवेक्षक बनाया layout_generate_blocks_afterहै जिसे लेआउट लोड होने के बाद निष्पादित किया जाता है और ब्लॉक उत्पन्न होते हैं।

इसकी एक खामी हो सकती है क्योंकि मैं जिस ब्लॉक को हटाने की कोशिश कर रहा हूं वह तुरंत हो जाता है, लेकिन मेरे मामले में मुझे इसे पेज से हटाने की जरूरत थी।

तो मेरे पास फाइल है etc/adminhtml/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">
    <event name="layout_generate_blocks_after">
        <observer name="remove-the-block" instance="[MyVendor]\[MyModule]\Observer\RemoveBlock" />
    </event>
</config>

और मेरा पर्यवेक्षक वर्ग:

<?php
namespace [MyVendor]\[MyModule]\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class RemoveBlock implements ObserverInterface
{
    const TEMPLATE_TO_REMOVE = '[OtherVendor]_[OtherModule]::template.phtml';
    public function execute(Observer $observer)
    {
        /** @var \Magento\Framework\View\Layout $layout */
        $layout = $observer->getLayout();
        $blocks = $layout->getAllBlocks();
        foreach ($blocks as $key => $block) {
            /** @var \Magento\Framework\View\Element\Template $block */
            if ($block->getTemplate() == self::TEMPLATE_TO_REMOVE) {
                $layout->unsetElement($key);
            }
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.