Magento 2: একটি কনফিগার সেটিংসের উপর নির্ভর করে ব্লক সরান


13

আমি একটি নির্দিষ্ট পৃষ্ঠা থেকে ব্লক সরিয়ে দেওয়ার চেষ্টা করছি (এটি সম্মুখভাগ বা ব্যাকএন্ড হোক) তবে কেবলমাত্র একটি নির্দিষ্ট কনফিগার পতাকা সেট করা থাকলে true
একটি উদাহরণ নেওয়া যাক।
আমি dashboardঅ্যাডমিন ড্যাশবোর্ড থেকে নামটি দিয়ে ব্লকটি সরাতে চাই ।

ব্লকটি মডিউল adminhtml_dashboard_index.xmlথেকে ফাইলটিতে সংজ্ঞায়িত করা হয়েছে Magento_Backend:

<referenceContainer name="content">
    <block class="Magento\Backend\Block\Dashboard" name="dashboard"/>
</referenceContainer>

অ্যাডামের উত্তরের জন্য ধন্যবাদ আমি এইটিতে এটি করতে পারিadminhtml_dashboard_index.xml

<body>
    <referenceBlock name="dashboard" remove="true"  />
</body>

তবে আমি এটি একটি খাঁজ নিতে এবং এই ব্লকটি সরাতে চাই কেবল যদি পথের সাথে কনফিগার সেটিংসের dashboard/settings/removeমান থাকে 1
একটি বিন্যাসের এক্সএমএল পদ্ধতির দুর্দান্ত হতে পারে তবে আমি একটি পর্যবেক্ষকের কাছেও যাব।


মারিয়াস, আপনি কি জানেন ইভেন্টগুলি এক্সএমএল এর জন্য একই জিনিস পাওয়া যায়? মানে আমি কনফিগারেশন সক্ষম হলে আমার পর্যবেক্ষককে মৃত্যুদণ্ড দিতে চাই
কিউর শাহ

আপনি যদি কোনও helperক্লাসে যেতে চান তবে /programming/47237179/magento-2-i-
ਵੰਤ-

উত্তর:


17

আমি লেআউট দিয়ে এটি করার কোনও উপায় খুঁজে পেলাম না তবে পর্যবেক্ষকদের (আপনি টেমপ্লেট ব্লকটি প্রসারিত করে) এর মাধ্যমে আপনি এটি করতে পারেন এমন একটি উদাহরণ এখানে ...

ইত্যাদি / ইভেন্ট.এক্সএমএল এ আপনার ইভেন্টস

<?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_before">
        <observer name="remove_block" instance="[Vendor]\[ModuleName]\Model\Observer\RemoveBlock" />
    </event>
</config>

পর্যবেক্ষক তৈরি করুন

<?php

namespace [Vendor]\[ModuleName]\Model\Observer;

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

class RemoveBlock implements ObserverInterface
{
    protected $_scopeConfig;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->_scopeConfig = $scopeConfig;
    }

    public function execute(Observer $observer)
    {
        /** @var \Magento\Framework\View\Element\Template $block */
        $block = $observer->getBlock();
        if ($block->getType() == 'Magento\Backend\Block\Dashboard') {
            $remove = $this->_scopeConfig->getValue(
                'dashboard/settings/remove',
                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
            );

            if ($remove) {
                $block->setTemplate(false);
            }
        }
    }
}

মূলত _toHtml পরীক্ষা করে দেখুন কোনও টেমপ্লেট রয়েছে কিনা। যদি তা না থাকে তবে এটি ফিরে আসে ''।

সম্পাদনা

আরও কিছু খনন করার পরে আমি এটির আরও চেইনটি করার একটি উপায় খুঁজে পেয়েছি।

<?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_block" instance="[Vendor]\[ModuleName]\Model\Observer\RemoveBlock" />
    </event>
</config>

এবং পর্যবেক্ষক ...

<?php

namespace [Vendor]\[ModuleName]\Model\Observer;

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

class RemoveBlock implements ObserverInterface
{
    protected $_scopeConfig;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->_scopeConfig = $scopeConfig;
    }

    public function execute(Observer $observer)
    {
        /** @var \Magento\Framework\View\Layout $layout */
        $layout = $observer->getLayout();
        $block = $layout->getBlock('dashboard');
        if ($block) {
            $remove = $this->_scopeConfig->getValue(
                'dashboard/settings/remove',
                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
            );

            if ($remove) {
                $layout->unsetElement('dashboard');
            }
        }
    }
}

এটি কার্যকর হতে পারে তবে কেবলমাত্র টেমপ্লেটগুলি ব্যবহার করে এমন ব্লকগুলির জন্য। এটি আমি যে উদাহরণটি দিয়েছি তা প্রযোজ্য, তবে তবুও, যদি অ্যাবস্ট্রাকব্লক প্রসারিত ব্লকগুলি থাকে এবং টেমপ্লেট ব্লকটি কাজ করে না তবে এটি কাজ করবে না। ভাল সূচনা পয়েন্টের জন্য +1।
মারিয়াস

আপনি সঠিক. আরও কিছু খোঁড়াখুঁজি করার পরে আমি খুঁজে পেয়েছি যে আপনি প্রক্রিয়াটিতে এটি আগে করতে পারেন। উত্তর আপডেট হয়েছে। রেফারেন্সের জন্য আমি আমার আসলটি সেখানে রেখেছি।
স্মার্তি

ধন্যবাদ এটি একটি দরকারী উত্তর। সমস্যাটি হ'ল এর অর্থ হ'ল যুক্তিটি প্রতিটি পৃষ্ঠা লোডের উপর নিক্ষেপ করা হবে কারণ এটি ইভেন্ট "লেআউট_জেনারেট_ব্লকস_একটি" ব্যবহার করছে। আপনি কি জানেন কীভাবে এটি নির্দিষ্ট পৃষ্ঠার লোডগুলিতে চালাতে হয় যেমন কোনও বিভাগের পৃষ্ঠা লোড করা (ইভেন্টটি "ক্যাটালগ_কন্ট্রোলার_ক্যাটরি_ইনিট_পর" তবে লেআউটটি অ্যাক্সেস করা যায় না)?
অ্যালেক্স

2
সত্যি ?! শর্তসাপেক্ষে একটি ব্লক অপসারণ করতে বা না করতে আমাদের একটি পর্যবেক্ষককে করতে হবে? এটা হাস্যকর, শুধু বলছি।
স্লেয়ারলিস্টেস্ট

1
আমার মনে হয় ডেটাগুলি পর্যবেক্ষকদের হেরফের করা উচিত নয় ...
অ্যালেক্স

5

সাধারণত এটি <action />ট্যাগ দিয়ে করা উচিত :

<referenceContainer name="content">
    <action method="unsetChild" ifconfig="dashboard/settings/remove">
        <argument xsi:type="string">dashboard</argument>
    </action>
</referenceContainer>

সম্পাদনা:

কেবল সমস্যাটি আনসেটচিল্ড কেবলমাত্র ওরফে গ্রহণ করে। আপনি ব্লকের নাম ব্যবহার করতে পারবেন না।

অন্যান্য সমাধান: অপসারণ = "সত্য" এর সাথে ifconfig ব্যবহার করতে সক্ষম হতে আবার ম্যাগন্টো ফ্রেমওয়ার্কটি পুনরায় লিখুন

1- আপনার নিজস্ব মডিউল তৈরি করুন।

2- ম্যাজেন্টো ফ্রেমওয়ার্ককে ওভাররাইড করতে একটি নতুন ফাইল যুক্ত করুন: (যেমন /Vendor/Module/Override/Magento/Framework/View/Layout/Reader/Block.php:)

namespace Vendor\Module\Override\Magento\Framework\View\Layout\Reader;

use Magento\Framework\App;
use Magento\Framework\Data\Argument\InterpreterInterface;
use Magento\Framework\View\Layout;

/**
 * Block structure reader
 */
class Block extends \Magento\Framework\View\Layout\Reader\Block
{
    /**
     * @var \Magento\Framework\App\ScopeResolverInterface
     */
    protected $scopeResolver;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * Constructor
     *
     * @param Layout\ScheduledStructure\Helper $helper
     * @param Layout\Argument\Parser $argumentParser
     * @param Layout\ReaderPool $readerPool
     * @param InterpreterInterface $argumentInterpreter
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
     * @param string|null $scopeType
     */
    public function __construct(
        Layout\ScheduledStructure\Helper $helper,
        Layout\Argument\Parser $argumentParser,
        Layout\ReaderPool $readerPool,
        InterpreterInterface $argumentInterpreter,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
        $scopeType = null
    ) {
        parent::__construct($helper,
            $argumentParser,
            $readerPool,
            $argumentInterpreter,
            $scopeType
        );
        $this->scopeConfig = $scopeConfig;
        $this->scopeResolver = $scopeResolver;
    }

    protected function scheduleReference(
        Layout\ScheduledStructure $scheduledStructure,
        Layout\Element $currentElement
    ) {
        $elementName = $currentElement->getAttribute('name');
        $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
        if ($elementRemove) {
            $configPath = (string)$currentElement->getAttribute('ifconfig');
            if (empty($configPath)
                || $this->scopeConfig->isSetFlag($configPath, $this->scopeType, $this->scopeResolver->getScope())
            ) {
                $scheduledStructure->setElementToRemoveList($elementName);
            }
        } else {
            $data = $scheduledStructure->getStructureElementData($elementName, []);
            $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
            $this->updateScheduledData($currentElement, $data);
            $this->evaluateArguments($currentElement, $data);
            $scheduledStructure->setStructureElementData($elementName, $data);
        }
    }
}

3- ম্যাজেন্টো ফাইলকে ওভাররাইড করতে 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">
    <preference for="Magento\Framework\View\Layout\Reader\Block"
       type="Vendor\Module\Override\Magento\Framework\View\Layout\Reader\Block" />    
</config>

4- এখন আপনি সরানোর সাথে মিলিত বিন্যাসে ifconfig ব্যবহার করতে পারেন:

<referenceBlock name="content" remove="true" ifconfig="path/to/myconfig" />

এই উদাহরণটি ব্লকের জন্য, তবে আপনি যদি / ম্যাজেন্টো / ফ্রেমওয়ার্ক / ভিউ / লেআউট / রিডার / কনটেইনার.পিপি এর পদ্ধতি ধারক রেফারেন্স ()টিকে ওভাররাইড করেন তবে আপনি ধারকটির জন্যও একই কাজ করতে পারেন


আমি মনে করি ফ্রেমওয়ার্কটি পুনরায় লেখাই সবচেয়ে ভাল সমাধান, কেন জানি না কেন ম্যাজেন্টো ডিফল্টরূপে এটি না করে।
স্লেয়ারলিস্ট

3

থেকে প্রযুক্তিগত নির্দেশিকা :

14.1। একটি ইভেন্টে পাস করা সমস্ত মান (অবজেক্টস সহ) ইভেন্ট পর্যবেক্ষককে সংশোধন করা উচিত নয়। পরিবর্তে, কোনও ফাংশনের ইনপুট বা আউটপুট পরিবর্তন করার জন্য প্লাগইনগুলি ব্যবহার করা উচিত।

14.3। ইভেন্টগুলি পর্যবেক্ষণযোগ্য বস্তুর একটি অবস্থার পরিবর্তন করা উচিত নয়।

সুতরাং এটির জন্য এখানে একটি প্লাগইন সমাধান রয়েছে:

প্লাগইনটি ঘোষণা করুন:

<?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\Framework\View\Element\AbstractBlock">
        <plugin name="remove_block" type="[Vendor]\[Module]\Plugin\RemoveBlock" />
    </type>
</config>

প্লাগইন সংজ্ঞায়িত করুন:

<?php

namespace Vendor\Module\Plugin;


use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\View\Element\AbstractBlock;

class RemoveBlock
{
    const BLOCK_NAME = 'block_to_be_removed';

    const CONFIG_PATH = 'your/path';

    private $_scopeConfig;

    public function __construct(ScopeConfigInterface $scopeConfig) {
        $this->_scopeConfig = $scopeConfig;
    }

    public function afterToHtml(AbstractBlock $subject, $result)
    {
        if ($subject->getNameInLayout() === self::BLOCK_NAME && $this->_scopeConfig->getValue(self::class)) {
            return '';
        }

        return $result;
    }
}

স্মার্টির উত্তরের মত আমিও \Magento\Framework\View\Layout\Builder::buildএকটি afterBuild()পদ্ধতিতে চেইনটিকে আরও প্লাগ ইন করার চেষ্টা করেছি তবে এটি একটি অন্তহীন পুনরাবৃত্তির দিকে পরিচালিত করবে কারণ \Magento\Framework\View\Layout::getBlockএবং \Magento\Framework\View\Layout::unsetElementউভয়ই \Magento\Framework\View\Layout\Builder::buildআবার কল করে।


2

বিন্যাসে "ব্লক" নোডের "ifconfig" বৈশিষ্ট্য আপনাকে স্টোর কনফিগারেশনে মানকে ব্লকের সাথে লিঙ্ক করতে দেয়।

"ifconfig" প্রসেসিং এর মধ্যে ঘটে \Magento\Framework\View\Layout\GeneratorPool::buildStructure


যদিও এটি "রেফারেন্সব্লক" দিয়ে কাজ করবে না। এটি কেবল তখনই কাজ করবে যখন আপনি একটি নতুন ব্লক যুক্ত করবেন।
নিকিতা আবরাশনেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.