Sommes-nous obligés de réécrire un modèle dans Magento2 lors de la réécriture d'un bloc?

8

Cette question concerne le respect des meilleures pratiques Magento2.

J'ai dû réécrire la méthode \ Magento \ Theme \ Block \ Html \ Topmenu :: _ addSubMenu () afin d'ajouter des wrappers autour des éléments. Maintenant, parce que c'est une méthode protégée, je comprends que je dois utiliser la fonction de préférence:

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

et ajouter une classe avec mes réécritures:

<?php

namespace MyCompany\Theme\Block\Html;

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

Bien que la classe par défaut ait été réécrite, à la page suivante, j'ai rechargé l'erreur suivante:

main.CRITICAL: Fichier de modèle non valide: 'html / topmenu.phtml' dans le module: nom du bloc 'MyCompany_Theme': 'catalog.topnav' [] []

Magento essaie de trouver html / topmenu.phtml sous mon extension et non sous Magento_Theme. Je comprends que c'est un comportement correct, mais je pensais aux aspects pratiques de cela. Est-ce à dire que chaque fois que nous réécrivons un bloc, nous devons également réécrire son modèle, même si nous n'avons pas nécessairement besoin de toucher à quelque chose de HTML?

Une façon de contourner cela serait de réécrire la méthode _toHtml () aussi, comme ceci:

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

Maintenant, Magento examine à nouveau le module Magento_Theme pour le fichier de modèle. Mais cela ressemble à un hack pour moi.

Donc, ma question est: quelle est la recommandation dans ces situations? Devrions-nous toujours copier le modèle pertinent lors de la réécriture de la classe de bloc, ou la solution de contournement est-elle correcte? Y a-t-il une meilleure approche pour cela?

mstojanov
la source
Je n'ai pas le temps de répondre pour le moment, mais je vous suggère de jeter un œil à cette question et aux réponses qui pourraient vous aider à comprendre le concept: magento.stackexchange.com/q/112749/2380
Raphael au
1
intéressant. Le modèle pourrait toujours être chargé à partir du module d'origine s'il Magento_Theme::n'avait pas été préfixé , mais ils n'ont pas github.com/magento/magento2/blob/develop/app/code/Magento/Theme/… Je me demande vraiment maintenant si c'était exprès
David Verholen
@RaphaelatDigitalPianism Merci. Le fil que vous avez lié concerne les plugins. Mon scénario est différent.
mstojanov
Oui, c'est ce que j'ai fini par trouver une fois que j'ai compris quel était votre problème. Certainement pas bien me semble être un bug
Raphael au Digital Pianism
J'ai créé un problème sur GitHub pour résoudre ce problème: github.com/magento/magento2/issues/4564 en attente d'une réponse de l'équipe de développement et fera un PR si cela finit par être un bug.
Raphael au Digital Pianism

Réponses:

4

Puisqu'il y a des discussions autour de la solution proposée dans la demande de tirage ( https://github.com/magento/magento2/pull/1895 ), en attendant, vous avez juste besoin de "pin" le modèle d'origine lorsque vous changez le nom de la classe de bloc d'origine:

<referenceBlock name="catalog.topnav" class="***" template="Magento_Theme::html/topmenu.phtml"/>
Vitalii K
la source
C'est une bonne suggestion, bien que pour certains blocs, ce serait au mieux impossible car il est utilisé dans de nombreuses mises en page ( Catalog\Block\Product\View). Je pense que la suggestion du PO est toujours la meilleure solution pour ce cas.
Erfan
3

il vous suffit d'ajouter un code dans ce fichier

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

avec:

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

et ajoutez le code ci-dessous dans le nom de fichier de votre module de remplacement:

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

code:

<?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>

Ajouter un Topmenu.phpfichier dans un fichier: app/code/Company_name/Override/Block/Html/Topmenu.php vous pouvez ajouter la fonction que vous souhaitez remplacer.

Merci

anant prajapati
la source