নাম ছাড়াই বিন্যাস থেকে একটি ব্লক সরান


12

আমি তৃতীয় পক্ষের এক্সটেনশনে ঘোষিত ম্যাজেন্টো 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
অমিত বেড়া

আমারও একই ধারণা আছে (উত্তরের মন্তব্য দেখুন) তবে আমি এটি কেবলমাত্র মরিয়া হিসাবে ব্যবহার করব। আমি একটি সহজ সমাধানের জন্য আশা ছিল। আপনার যদি কিছু কোড থাকে তবে উত্তর হিসাবে পোস্ট করুন।
Marius

হা হা আমাদের কাছে সহজ সমাধান নেই 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);
            }
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.