Próbuję zastąpić blok Topmenu w Magento 2.1, ale nie mogę znaleźć żadnego przewodnika. Wszystko, co znalazłem tutaj i gdzie indziej albo wydaje się dotyczyć tylko wersji 2.0, która wydaje się używać innej struktury folderów lub zawiera tylko częściowe przykłady kodu, które oczekują, że już znam ich właściwy kontekst (czego nie znam).
Moja bieżąca struktura folderów dla niestandardowego motywu to app/design/frontend/Vendor/theme_name
. W ramach tego mam pliki rejestracji, temat, i kompozytor, a także foldery dla poszczególnych modułów, np Magento_Theme
i Magento_Search
.
Z tego, co rozumiem, muszę zacząć od etc/di.xml
pliku takiego jak poniżej, edytowanego stąd :
<?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>
Rozumiem również, że następnym krokiem jest dodanie Block/Html/Topmenu.php
pliku podobnego do poniższego (ponownie edytowanego z powyższego źródła):
namespace [Namespace]\[Module]\Block\Html;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
}
}
Jednak nie jest dla mnie jasne, do czego powinienem użyć [Namespace]
i [Module]
gdzie umieścić te pliki. Próbowałem użyć nazwy dostawcy i motywu oraz umieszczenia folderów etc
i , a także umieszczenia ich , zmiany przestrzeni nazw na , ale żadne z nich nie ma żadnego efektu.Block
app/design/frontend/Vendor/theme_name
app/design/frontend/Vendor/theme_name/Magento_Theme
Vendor\theme_name\Magento_Theme\Block\Html
Gdyby ktoś mógł wyjaśnić dokładnie, co muszę zrobić, aby zastąpić blok Topmenu (i wywnioskować dowolny inny blok) w wersji 2.1, byłbym bardzo wdzięczny.
Uzupełnienie
Próbowałem odpowiedzi Khoa TruongDinh , ale nie miało to wpływu. Użyłem następujących plików:
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__
);
Mam następnie usunięto zawartość pub/static/frontend
, var/generation
i var/view_preprocessed
, i spłukuje cache Magento. W podmenu nie ma dodanej zamierzonej klasy „test”:
<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>
źródło
ul
aby potwierdzić, że udało mi się zastąpić klasę Topmenu.Odpowiedzi:
Zastąp blok:
Utwórz własny moduł w
app/code
folderze.Możemy użyć
preference
do zastąpienia klasy w Magento 2.app / code / Vendor / Module / etc / di.xml
app / code / Vendor / Module / Block / Html / Topmenu.php
Rozwiązanie tymczasowe:
obecnie wydaje się, że powyższe kroki nie mogą całkowicie zastąpić bloku. Musimy utworzyć nowy niestandardowy motyw. A następnie utwórz
default.xml
plik:app / design / frontend / Vendor / Theme / Magento_Theme / layout / default.xml
Może to być błąd Magento: Czy podczas przepisywania bloku jesteśmy zmuszeni przepisać szablon w Magento2?
[EDYTOWAĆ]
1) Możemy ustawić szablon:
app / code / Vendor / Module / Block / Html / Topmenu.php
2) Ustaw szablon za pomocą Xml:
Na przykład:
app / code / Vendor / Module / view / frontend / layout / checkout_cart_index.xml
Pamiętaj, aby utworzyć
registration.php
imodule.xml
.Tworzymy nowy moduł, ponieważ zastępujemy klasę Magento. Kiedy chcemy przesłonić dowolną klasę, musimy utworzyć nowy moduł .
Under niestandardowy motyw
app/design/frontend
zawiera:--layout
--templates
--js
--html szablony (szablony Knockout)
--less, css
--etc ...
Czytaj więcej tutaj i tutaj .
Standard ładowania automatycznego i konwencja nazewnictwa:
Dla
[Namespace]
i[Module]
powinniśmy przeczytać więcej tutaj: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
źródło
W przypadku zastąpienia katalogu katalog ListProduct.
1) Utwórz plik di.xml w folderze
Vendor/Module/etc
2) Utwórz plik bloku ListProduct.php w folderze
Vendor/Module/Block/Rewrite/Product
Do zastąpienia modelu produktu z katalogu.
1) Dodaj preferencje w pliku di.xml wcześniej
2) Utwórz plik modelu Product.php w folderze
Vendor/Module/Model/Rewrite/Catalog
Dla nadrzędnego kontrolera
1) Dodaj preferencje w di.xml
2) Utwórz plik kontrolera View.php pod adresem
Vendor/Module/Controller/Rewrite/Product
Możesz zastąpić inne bloki, modele i kontrolery, stosując to samo podejście.
źródło
Aby zastąpić klasę, musisz utworzyć moduł, w którym możesz dodać plik
etc/di.xml
iBlock/Html/Topmenu.php
(powyższy kod przesłany przez Ciebie)gdzie Przestrzeń nazw to nazwa twojego dostawcy, a moduł to nazwa twojego modułu. Na przykład: Magento to Przestrzeń nazw, a Motyw to Nazwa modułu.
Aby uzyskać więcej informacji na temat tworzenia modułu, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure
źródło
Z powodu tego błędu: https://github.com/magento/magento2/issues/3724 nie można po prostu preferować klas bloków.
1) (Preferowane) Zamiast tego należy użyć wtyczki dla tej klasy i zmienić to, czego potrzebujesz. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html
2) Lub jeśli naprawdę chcesz zrobić preferencje, musisz również skopiować szablon z rdzenia do modułu / motywu i zaktualizować za pomocą xml, aby używał tego szablonu, wtedy magicznie zacznie działać.
źródło