J'essaie de remplacer le bloc Topmenu dans Magento 2.1 mais je ne trouve aucun guide pour le faire. Tout ce que j'ai trouvé ici et ailleurs semble ne s'appliquer qu'à la version 2.0 qui semble utiliser une structure de dossiers différente ou n'a que des exemples de code partiel qui m'attendent à connaître déjà leur contexte approprié (ce que je ne sais pas).
Ma structure de dossiers actuelle pour un thème personnalisé est app/design/frontend/Vendor/theme_name
. Dans ce document, j'ai les fichiers d'enregistrement, de thème et de compositeur ainsi que des dossiers pour les différents modules, par exemple Magento_Theme
et Magento_Search
.
D'après ce que je comprends, je dois commencer avec un etc/di.xml
fichier comme ci-dessous, édité à partir d' ici :
<?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\Theme\Block\Html\Topmenu" type="[Namespace]\[Module]\Block\Html\Topmenu" />
</config>
Je comprends également que l'étape suivante consiste à ajouter un Block/Html/Topmenu.php
fichier comme celui ci-dessous (à nouveau modifié à partir de la source ci-dessus):
namespace [Namespace]\[Module]\Block\Html;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
}
}
Cependant, il n'est pas clair pour moi à quoi je dois utiliser [Namespace]
et [Module]
, ou où placer ces fichiers. J'ai essayé d'utiliser le nom du fournisseur et du thème, et de placer les dossiers etc
et , ainsi que de les placer, en modifiant les espaces de noms , mais aucun n'a d'effet.Block
app/design/frontend/Vendor/theme_name
app/design/frontend/Vendor/theme_name/Magento_Theme
Vendor\theme_name\Magento_Theme\Block\Html
Si quelqu'un pouvait aider à expliquer exactement ce que je dois faire pour remplacer le bloc Topmenu (et par déduction tout autre bloc) dans la version 2.1, je serais très apprécié.
Addenda
J'ai essayé la réponse de Khoa TruongDinh mais cela n'a eu aucun effet. J'ai utilisé les fichiers suivants:
app/code/Vendor/MagentoTheme/Block/Html/Topmenu.php
<?php
namespace Vendor\MagentoTheme\Block\Html;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
$html = '';
if (!$child->hasChildren())
{
return $html;
}
$colStops = null;
if ($childLevel == 0 && $limit)
{
$colStops = $this->_columnBrake($child->getChildren(), $limit);
}
// Added "test" class to test
$html .= '<ul class="level' . $childLevel . ' test submenu">';
$html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
$html .= '</ul>';
return $html;
}
}
app/code/Vendor/MagentoTheme/composer.json
{
"name": "vendor/magento-theme",
"description": "",
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0",
"magento/framework": "100.0.*"
},
"type": "magento2-module",
"version": "100.0.1",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [ "registration.php" ],
"psr-4": {
"Vendor\\MagentoTheme\\": ""
}
}
}
app/code/Vendor/MagentoTheme/etc/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\Theme\Block\Html\Topmenu" type="Vendor\MagentoTheme\Block\Html\Topmenu" />
</config>
app/code/Vendor/MagentoTheme/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_MagentoTheme" setup_version="1.0.0"></module>
</config>
app/code/Vendor/MagentoTheme/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_MagentoTheme',
__DIR__
);
Je l' ai ensuite retiré le contenu pub/static/frontend
, var/generation
et var/view_preprocessed
, et rincée le cache Magento. Le sous-menu n'a pas la classe "test" prévue ajoutée:
<ul class="level0 submenu ui-menu ui-widget ui-widget-content ui-corner-all" role="menu" aria-expanded="false" style="display: none; top: 52.6719px; left: 487.5px;" aria-hidden="true">...</ul>
la source
ul
pour confirmer que j'ai réussi à remplacer la classe Topmenu.Réponses:
Remplacer le bloc:
Créez votre propre module sous
app/code
dossier.Nous pouvons utiliser
preference
pour remplacer la classe dans Magento 2.app / code / Vendor / Module / etc / di.xml
app / code / Vendor / Module / Block / Html / Topmenu.php
Solution temporaire:
actuellement, il semble que les étapes ci-dessus ne peuvent pas remplacer complètement le bloc. Nous devons créer un nouveau thème personnalisé. Et puis, créez le
default.xml
fichier:app / design / frontend / Vendor / Theme / Magento_Theme / layout / default.xml
Il s'agit peut-être d'un bogue de Magento: sommes-nous obligés de réécrire un modèle dans Magento2 lors de la réécriture d'un bloc?
[ÉDITER]
1) Nous pouvons définir le modèle:
app / code / Vendor / Module / Block / Html / Topmenu.php
2) Définissez le modèle via Xml:
Par exemple:
app / code / Vendor / Module / view / frontend / layout / checkout_cart_index.xml
N'oubliez pas de créer
registration.php
etmodule.xml
.Nous créons le nouveau module parce que nous remplaçons la classe de Magento. Lorsque nous voulons remplacer une classe, nous devons créer un nouveau module .
Le thème personnalisé sous
app/design/frontend
contient:--layout
--templates
--js
--html templates (Knockout templates)
--less, css
--etc ...
En savoir plus ici et ici .
Norme de chargement automatique et convention de dénomination:
Pour
[Namespace]
et[Module]
, nous devrions en savoir plus ici:http://www.php-fig.org/psr/psr-0/
http://www.php-fig.org/psr/psr-4/
http://alanstorm.com/magento_2_autoloader_and_class_generation
la source
Pour remplacer le produit ListProduct du catalogue.
1) Créez un fichier di.xml dans le dossier
Vendor/Module/etc
2) Créer un fichier bloc ListProduct.php dans un dossier
Vendor/Module/Block/Rewrite/Product
Pour remplacer le modèle de produit du catalogue.
1) Ajoutez une préférence dans di.xml avant
2) Créer un fichier modèle Product.php dans un dossier
Vendor/Module/Model/Rewrite/Catalog
Pour remplacer le contrôleur
1) Ajouter une préférence en di.xml
2) Créez le fichier du contrôleur View.php à
Vendor/Module/Controller/Rewrite/Product
Vous pouvez remplacer d'autres blocs, modèles et contrôleurs en utilisant cette même approche.
la source
Pour remplacer la classe, vous devez créer un module où vous pouvez ajouter le fichier
etc/di.xml
etBlock/Html/Topmenu.php
(ci-dessus le code que vous avez publié)où Namespace est le nom de votre fournisseur et Module est le nom de votre module. Par exemple: Magento est l'espace de noms et le thème est le nom du module.
Pour plus d'informations sur la création d'un module, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure
la source
À cause de ce bogue: https://github.com/magento/magento2/issues/3724, vous ne pouvez pas simplement préférer les classes de blocs.
1) (De préférence) Ce qui fonctionne à la place est d'utiliser un plugin pour cette classe et de changer ce dont vous avez besoin. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html
2) Ou si vous voulez vraiment faire la préférence, vous devez également copier le modèle du noyau vers votre module / thème et mettre à jour avec xml afin qu'il utilise ce modèle à la place, alors cela commencera comme par magie.
la source