Estoy tratando de anular el bloque Topmenu en Magento 2.1 pero no puedo encontrar ninguna guía para hacerlo. Todo lo que he encontrado aquí y en otros lugares parece aplicarse solo a la versión 2.0 que parece usar una estructura de carpetas diferente o solo tiene ejemplos de código parcial que espera que ya conozca su contexto adecuado (lo cual no sé).
Mi estructura de carpetas actual para un tema personalizado es app/design/frontend/Vendor/theme_name
. Dentro de esto tengo los archivos de registro, tema y compositor, así como carpetas para los diversos módulos, por ejemplo, Magento_Theme
y Magento_Search
.
Por lo que entiendo, necesito comenzar con un etc/di.xml
archivo como el siguiente, editado desde aquí :
<?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>
También entiendo que el siguiente paso es agregar un Block/Html/Topmenu.php
archivo como el siguiente (nuevamente editado de la fuente anterior):
namespace [Namespace]\[Module]\Block\Html;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
}
}
Sin embargo, no me queda claro para qué debo usar [Namespace]
y [Module]
dónde colocar estos archivos. Intenté usar el nombre del proveedor y el tema, y colocar las carpetas etc
y , así como colocarlas , modificando los espacios de nombres , pero ninguno tiene ningún efecto.Block
app/design/frontend/Vendor/theme_name
app/design/frontend/Vendor/theme_name/Magento_Theme
Vendor\theme_name\Magento_Theme\Block\Html
Si alguien pudiera ayudarme a explicar exactamente lo que necesito hacer para anular el bloque Topmenu (y por inferencia cualquier otro bloque) en la versión 2.1, sería muy apreciado.
Apéndice
He intentado la respuesta de Khoa TruongDinh pero no ha tenido ningún efecto. He usado los siguientes archivos:
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__
);
Entonces me he quitado el contenido de pub/static/frontend
, var/generation
y var/view_preprocessed
, y tiraba el caché de Magento. El submenú no tiene la clase de "prueba" prevista agregada:
<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>
fuente
ul
para confirmar que he anulado con éxito la clase Topmenu.Respuestas:
Anular bloque:
Crea tu propio módulo en la
app/code
carpeta.Podemos usar
preference
para anular la clase en Magento 2.app / code / Vendor / Module / etc / di.xml
app / code / Vendor / Module / Block / Html / Topmenu.php
Solución temporal:
actualmente, parece que los pasos anteriores no pueden anular el bloque por completo. Necesitamos crear un nuevo tema personalizado. Y luego, crea el
default.xml
archivo:app / design / frontend / Vendor / Theme / Magento_Theme / layout / default.xml
Puede ser un error de Magento: ¿estamos obligados a reescribir una plantilla en Magento2 cuando reescribimos un bloque?
[EDITAR]
1) Podemos configurar la plantilla:
app / code / Vendor / Module / Block / Html / Topmenu.php
2) Establecer plantilla a través de Xml:
Por ejemplo:
app / code / Vendor / Module / view / frontend / layout / checkout_cart_index.xml
Recuerda crear
registration.php
ymodule.xml
.Creamos el nuevo módulo porque estamos anulando la clase de Magento. Cuando queremos anular cualquier clase, tenemos que crear un nuevo módulo .
El tema personalizado debajo
app/design/frontend
contiene:--layout
--templates
--js
--html templates (Knockout templates)
--less, css
--etc ...
Lea más aquí y aquí .
Estándar de carga automática y convención de nombres:
Para
[Namespace]
y[Module]
, deberíamos leer más aquí: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
fuente
Para anular el catálogo del producto ListProduct block.
1) Crear un archivo di.xml en la carpeta
Vendor/Module/etc
2) Crear el archivo de bloque ListProduct.php en la carpeta
Vendor/Module/Block/Rewrite/Product
Para anular el modelo de catálogo del producto.
1) Agregue preferencia en di.xml antes
2) Crear archivo de modelo Product.php en la carpeta
Vendor/Module/Model/Rewrite/Catalog
Para anular el controlador
1) Añadir preferencia en di.xml
2) Crear el archivo View.php Controller en
Vendor/Module/Controller/Rewrite/Product
Puede anular otros bloques, modelos y controladores utilizando este mismo enfoque.
fuente
Para anular la clase, debe crear un módulo donde pueda agregar el archivo
etc/di.xml
yBlock/Html/Topmenu.php
(el código anterior publicado por usted)donde Namespace es su nombre de proveedor y Module es su nombre de módulo. Por ejemplo: Magento es el espacio de nombres y el tema es el nombre del módulo.
Para obtener más información sobre cómo crear un módulo, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure
fuente
Debido a este error: https://github.com/magento/magento2/issues/3724 no puedes simplemente preferir las clases de bloque.
1) (Preferible) Lo que funciona es utilizar un complemento para esa clase y cambiar lo que necesita. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html
2) O si realmente desea hacer la forma de preferencia, entonces también necesita copiar la plantilla desde el núcleo a su módulo / tema y actualizar con xml para que use esa plantilla, entonces mágicamente comenzará a funcionar ...
fuente