Estou tentando substituir o bloco Topmenu no Magento 2.1, mas não consigo encontrar nenhum guia para fazer isso. Tudo o que encontrei aqui e em outros lugares parece se aplicar apenas à versão 2.0, que parece usar uma estrutura de pastas diferente ou possui apenas exemplos de códigos parciais que esperam que eu já conheça o contexto adequado (o que não sei).
Minha estrutura de pastas atual para um tema personalizado é app/design/frontend/Vendor/theme_name
. Dentro disso, tenho os arquivos de registro, tema e compositor, além de pastas para os vários módulos, por exemplo, Magento_Theme
e Magento_Search
.
Pelo que entendi, preciso começar com um etc/di.xml
arquivo como o abaixo, editado a partir daqui :
<?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>
Também entendo que o próximo passo é adicionar um Block/Html/Topmenu.php
arquivo como o abaixo (novamente editado a partir da fonte acima):
namespace [Namespace]\[Module]\Block\Html;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
}
}
No entanto, não está claro para mim o que devo usar [Namespace]
e [Module]
nem onde colocar esses arquivos. Tentei usar o nome do fornecedor e do tema, colocar as pastas etc
e , além de colocá-las , alterar os espaços para nome , mas nenhum deles tem efeito.Block
app/design/frontend/Vendor/theme_name
app/design/frontend/Vendor/theme_name/Magento_Theme
Vendor\theme_name\Magento_Theme\Block\Html
Se alguém puder ajudar a explicar exatamente o que preciso fazer para substituir o bloco Topmenu (e por inferência de qualquer outro bloco) na versão 2.1, eu ficaria muito agradecido.
Termo aditivo
Eu tentei a resposta de Khoa TruongDinh , mas ela não teve efeito. Eu usei os seguintes arquivos:
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__
);
Eu, em seguida, removido o conteúdo pub/static/frontend
, var/generation
e var/view_preprocessed
, e corou o cache Magento. O submenu não possui a classe "teste" pretendida adicionada:
<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>
fonte
ul
para confirmar que substitui com êxito a classe Topmenu.Respostas:
Substituir bloco:
Crie seu próprio módulo na
app/code
pastaPodemos
preference
substituir a classe no Magento 2.aplicativo / código / fornecedor / módulo / etc / di.xml
app / code / Vendor / Module / Block / Html / Topmenu.php
Solução temporária:
atualmente, parece que as etapas acima não podem substituir completamente o bloco. Precisamos criar um novo tema personalizado. E então, crie o
default.xml
arquivo:app / design / front-end / fornecedor / tema / tema-magento / layout / default.xml
Pode ser um bug do Magento: somos forçados a reescrever um modelo no Magento2 ao reescrever um bloco?
[EDITAR]
1) Podemos definir o modelo:
app / code / Vendor / Module / Block / Html / Topmenu.php
2) Defina o modelo via Xml:
Por exemplo:
app / code / Vendor / Module / view / frontend / layout / checkout_cart_index.xml
Lembre-se de criar
registration.php
emodule.xml
.Criamos o novo módulo porque estamos substituindo a classe Magento. Quando queremos substituir qualquer classe, precisamos criar um novo módulo .
O tema personalizado em
app/design/frontend
contém:--layout
--templates
--js
--html templates (modelos de Knockout)
--less, css -
etc ...
Leia mais aqui e aqui .
Padrão de carregamento automático e convenção de nomenclatura:
Para
[Namespace]
e[Module]
, devemos ler mais aqui: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
fonte
Para substituir o bloco ListProduct do produto do catálogo.
1) Crie um arquivo di.xml na pasta
Vendor/Module/etc
2) Crie o arquivo ListProduct.php Block na pasta
Vendor/Module/Block/Rewrite/Product
Para substituir o modelo de produto do catálogo.
1) Adicione preferência em di.xml antes
2) Crie o arquivo Product.php Model na pasta
Vendor/Module/Model/Rewrite/Catalog
Para substituir o controlador
1) Adicione preferência em di.xml
2) Crie o arquivo View.php Controller em
Vendor/Module/Controller/Rewrite/Product
Você pode substituir outro bloco, modelo e controladores usando essa mesma abordagem.
fonte
Para substituir a classe, é necessário criar um módulo no qual você pode adicionar o arquivo
etc/di.xml
eBlock/Html/Topmenu.php
(código acima postado por você)onde Namespace é o nome do seu fornecedor e Module é o nome do seu módulo. Por exemplo: Magento é Namespace e Theme é Module name.
Para obter mais informações sobre como criar um módulo, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure
fonte
Devido a esse bug: https://github.com/magento/magento2/issues/3724, você não pode apenas preferir classes de bloco.
1) (Preferível) O que funciona é usar um plug - in para essa classe e alterar o que você precisa. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html
2) Ou se você realmente deseja fazer a preferência, também precisa copiar o modelo do núcleo para o seu módulo / tema e atualizar com xml, para que ele use esse modelo, então ele começará a funcionar magicamente.
fonte