Somos forçados a reescrever um modelo no Magento2 ao reescrever um bloco?

8

Esta pergunta é sobre seguir as melhores práticas do Magento2.

Eu tive que reescrever o método \ Magento \ Theme \ Block \ Html \ Topmenu :: _ addSubMenu () para adicionar alguns wrappers ao redor dos elementos. Agora, por ser um método protegido, meu entendimento é que eu tenho que usar o recurso de preferência:

<preference for="Magento\Theme\Block\Html\Topmenu" type="MyCompany\Theme\Block\Html\Topmenu" />

e adicione uma classe com minhas reescritas:

<?php

namespace MyCompany\Theme\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
    protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
    {
        // my stuff
    }
}

Embora a classe padrão tenha sido reescrita, na próxima página recarreguei o seguinte erro:

main.CRITICAL: arquivo de modelo inválido: 'html / topmenu.phtml' no módulo: 'MyCompany_Theme' nome do bloco: 'catalog.topnav' [] []

O Magento está tentando encontrar html / topmenu.phtml na minha extensão e não no Magento_Theme. Entendo que esse é um comportamento correto, mas estava pensando em aspectos práticos disso. Isso significa que sempre que reescrevemos um bloco, precisamos reescrever seu modelo também, mesmo que não precisemos necessariamente tocar em algo relacionado a HTML?

Uma maneira de contornar isso seria reescrever o método _toHtml () também, assim:

protected function _toHtml()
{
    $this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Topmenu'));
    return parent::_toHtml();
}

Agora, o Magento está procurando no módulo Magento_Theme o arquivo de modelo novamente. Mas, isso parece um hack para mim.

Então, minha pergunta é: o que é uma recomendação nessas situações? Devemos sempre copiar o modelo relevante ao reescrever a classe de bloco ou a solução alternativa está correta? Existe uma abordagem melhor para isso?

mstojanov
fonte
Não tem tempo para responder agora, mas eu sugiro que você dê uma olhada a esta pergunta e as respostas que podem ajudar você a entender o conceito: magento.stackexchange.com/q/112749/2380
Raphael em Digital pianismo
11
interessante. O modelo ainda poderia ser carregado a partir do módulo original se tivesse sido prefixado Magento_Theme::, mas eles não github.com/magento/magento2/blob/develop/app/code/Magento/Theme/… Gostaria realmente de saber agora se isso foi de propósito
David Verholen
@RaphaelatDigitalPianism Thanks. O tópico que você vinculou é sobre plug-ins. Meu cenário é diferente.
Mstojanov 18/05/19
Sim, foi o que acabei encontrando quando entendi qual era o seu problema. Sons Definitivamente não é direito, como um bug para mim
Raphael em Digital pianismo
Eu criei um problema no GitHub resolvendo esse problema: github.com/magento/magento2/issues/4564 aguardando uma resposta da equipe de desenvolvimento e fará um PR se acabar sendo um bug.
Raphael no Pianism Digital

Respostas:

4

Como existem discussões em torno da solução proposta na solicitação pull ( https://github.com/magento/magento2/pull/1895 ), enquanto isso, você só precisa "fixar" o modelo original ao alterar o nome da classe de bloco original:

<referenceBlock name="catalog.topnav" class="***" template="Magento_Theme::html/topmenu.phtml"/>
Vitalii K
fonte
Essa é uma boa sugestão, embora para certos blocos seja impraticável, na melhor das hipóteses, pois é usado em muitos layouts ( Catalog\Block\Product\View). Acho que a sugestão do OP ainda é a melhor solução para esse exemplo.
Erfan
3

você só precisa adicionar um código nesse arquivo

app/design/frontend/chop/misty/Magento_Theme/layout/default.xml

com:

<referenceBlock name="catalog.topnav" class="Company_name\Override\Block\Html\Topmenu" template="Magento_Theme::html/topmenu.phtml"/>

e adicione o código abaixo no nome do arquivo do módulo de substituição:

app/code/Aims/Override/etc/di.xml

código:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Theme\Block\Html\Topmenu" type="Company_name\Override\Block\Html\Topmenu" />
    <preference for="Magento\Paypal\Model\Config" type="Company_name\Override\Model\Paypal\Config" />
</config>

Adicionar Topmenu.phparquivo no arquivo: app/code/Company_name/Override/Block/Html/Topmenu.php você pode adicionar qualquer função que queira substituir.

obrigado

anant prajapati
fonte