Adı olmayan bir bloğu mizanpajdan kaldırma


12

Üçüncü taraf bir uzantıda bildirilen magento 2 düzeninden bir blok kaldırmak istiyorum, ancak blok bir adı yok.
Bunu yapabilir miyim?

Blok şöyle ilan edilir

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

Kullanamam

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

çünkü gördüğünüz gibi üzerinde isim yok.


marius i idea.if biz maç şablon adıyla olayı ve kaldır bloğunu kullanan var [Vendor_Module]::template.phtml
Amit Bera

Aynı fikrim var (cevabın yorumlarına bakın) ama bunu sadece umutsuz bir önlem olarak kullanacağım. Basit bir çözüm umuyordum. Kodunuz varsa, yanıt olarak gönderin.
Marius

ha basit bir çözümümüz yok. olayı kullanarak u cevap vereyim
Amit Bera

Yanıtlar:


5

Bu sorunu sınıfta buldum Magento\Framework\View\Layout\ScheduledStructure\Helper

Fonksiyon var _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++;
}

Bu scheduleStructurefonksiyondan çağrı :

    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;
}

Bu durumda, Blok adı şunlar olabilir:

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

Kapsayıcı üzerinde ad olmadan toplam bloğu tanımlamanız gerektiğini ve sipariş bloğu adının kapsayıcıda kaldırılması gerektiğini düşünüyorum.


Bunun işe yarayacağını sanmıyorum. Oluşturulan adı tahmin etmenin bir yolu yoktur, çünkü farklı sayfalarda body.before.endkapsayıcıya farklı sırayla birden fazla blok eklenebilir .
Marius

Bu durum yalnızca adı olmayan blok / kapsayıcı için geçerlidir. Hepsi adı olmadan, bazı blok / konteyner tanımlamak çok zor kaldırılması gerekir.
Thao Pham

evet ... benim sorunum tam olarak
Marius

Yeniden yazmalıyız $name = $this->_generateAnonymousName($parentNode->getElementName() . '_schedule_block');, parametreye pass class & template olmalı mı?
Thao Pham

2
böyle bir şeyi yeniden yazmak için ek yük gibi görünüyor. Basit bir çözüm (varsa) ya da 'çok kolay mümkün değil' gibi bir cevap arıyorum. Ben düzeni oluşturmak blok olay ya da orada kaldırmak için bir şey gözlemlemek düşünüyorum, ama yine çok fazla yük görünüyor. Bunu bir yedek çözüm olarak saklıyorum.
Marius

3

Sana gerçekten kötü bir fikir veriyorum.

Burada fikir bloğunuzun çıktısını durdurmak değil

Etkinliği kullanma 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>

Ve bu gözlemciyi kullanarak bloğunuzun çıktısını devre dışı bırakın

<?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('');

    }
  }
}

bu aslında o kadar da kötü bir fikir değil. Gerçekten de, tüm blokları gözlemleyen bir aşırı yüklenme var, ancak diğer seçenekler üzerinde kullanmaya hazırım. Size söyleyeceğim.
Marius

coool. adamım .... ne olduğunu görün
Amit Bera

1
Çalışıyor, ancak her blok için kodu yürütmemek için biraz optimize etmeye çalıştım. Sonunda cevabımı buldum . Fikir için teşekkürler.
Marius

Cevabı görüyorum, gerçekten iyi bir adam :)
Amit Bera

3

Amit'in cevabından bir fikir aldım ve çok müdahaleci görünmeyen bir çalışma çözümü ile sonuçlandım ve kodum sadece bir kez yürütüldüğünden bu bir abartı değil.

layout_generate_blocks_afterDüzenleri yüklendikten ve bloklar oluşturulduktan sonra yürütülen olayda bir gözlemci oluşturdum.

Kaldırmaya çalıştığım blok hala somutlaştığı için bu bir dezavantaj olabilir, ancak benim durumumda sadece sayfadan kaldırmam gerekiyordu.

Yani dosyam var 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>

ve gözlemci sınıfım:

<?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);
            }
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.