Jak zastąpić bloki w wersji 2.1


14

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_Themei Magento_Search.

Z tego, co rozumiem, muszę zacząć od etc/di.xmlpliku 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.phppliku 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 etci , a także umieszczenia ich , zmiany przestrzeni nazw na , ale żadne z nich nie ma żadnego efektu.Blockapp/design/frontend/Vendor/theme_nameapp/design/frontend/Vendor/theme_name/Magento_ThemeVendor\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/generationi 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>

Próbowałeś utworzyć wiele podkategorii?
Khoa TruongDinh

Nie jestem pewny co masz na myśli. W tej chwili próbuję tylko dodać klasę „testową” do podmenu, ulaby potwierdzić, że udało mi się zastąpić klasę Topmenu.
MichaelRushton,

Jak możesz to zrobić? Mój przewodnik może ci pomóc?
Khoa TruongDinh

Postępowałem zgodnie z twoimi instrukcjami, jak najlepiej rozumiałem, ale to nie działało. Mój niestandardowy moduł Topmenu jest ignorowany i używane jest domyślne zachowanie.
MichaelRushton,

W weekend sprawdzę ponownie i dam ci moje rozwiązanie.
Khoa TruongDinh

Odpowiedzi:


20

Zastąp blok:

Utwórz własny moduł w app/codefolderze.
Możemy użyć preferencedo zastąpienia klasy w Magento 2.

app / code / Vendor / Module / 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\Module\Block\Html\Topmenu" />
</config>

app / code / Vendor / Module / Block / Html / Topmenu.php

<?php

namespace Vendor\Module\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{

    protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
    {

    }

}

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.xmlplik:

app / design / frontend / Vendor / Theme / Magento_Theme / layout / default.xml

<?xml version="1.0"?>

<page layout="3columns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="default_head_blocks"/>
    <referenceBlock name="catalog.topnav" class="Vendor\Module\Block\Html\Topmenu" template="Magento_Theme::html/topmenu.phtml"/>
</page>

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

public function setTemplate($template)
{
    return parent::setTemplate('Vendor_Module::custom-menu.phtml');
}

2) Ustaw szablon za pomocą Xml:

Na przykład:

app / code / Vendor / Module / view / frontend / layout / checkout_cart_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.cart">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Magento_Checkout::cart.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

Pamiętaj, aby utworzyć registration.phpi module.xml.

Tworzymy nowy moduł, ponieważ zastępujemy klasę Magento. Kiedy chcemy przesłonić dowolną klasę, musimy utworzyć nowy moduł .

Under niestandardowy motyw app/design/frontendzawiera:
--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


Dzięki, ale nie udało mi się tego uruchomić. Zmodyfikowałem moją próbę w moim pytaniu, abyś mógł zobaczyć, gdzie nieuchronnie popełniłem błąd.
MichaelRushton,

Jaki jest szablon
MichaelRushton,

Zaktualizowałem swoją odpowiedź. Wygląda na to, że występuje błąd Magento. Musimy utworzyć nowy niestandardowy motyw. Następnie utwórz układ, aby ustawić klasę ponownie.
Khoa TruongDinh,

Tak, zadziałało. Dziękuję Ci bardzo. Dzień stracony na robale ...
MichaelRushton

muszę zastąpić plik bloku w custom_account_create.xml znajdującym się w moim niestandardowym pliku theme.xml znajduje się w folderze Magento_Customer. który jest domyślny. xml muszę zmienić magento_theme lub magento_customer? nie mogę zastąpić bloku. używam Magento2.1 jest lepiej przenieść Magento 2.1.3?
vijay b

3

W przypadku zastąpienia katalogu katalog ListProduct.

1) Utwórz plik di.xml w folderzeVendor/Module/etc

<?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\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config>

2) Utwórz plik bloku ListProduct.php w folderzeVendor/Module/Block/Rewrite/Product

<?php
namespace Vendor\Module\Block\Rewrite\Product;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    public function _getProductCollection()
    {
        // Do your code here
    }
}

Do zastąpienia modelu produktu z katalogu.

1) Dodaj preferencje w pliku di.xml wcześniej

<?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\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config> 

2) Utwórz plik modelu Product.php w folderzeVendor/Module/Model/Rewrite/Catalog

<?php
namespace Vendor\Module\Model\Rewrite\Catalog;

class Product extends \Magento\Catalog\Model\Product
{
    public function isSalable()
    {
        // Do your code here

        return parent::isSalable();
    }

}

Dla nadrzędnego kontrolera

1) Dodaj preferencje w di.xml

2) Utwórz plik kontrolera View.php pod adresemVendor/Module/Controller/Rewrite/Product

class View extends \Magento\Catalog\Controller\Product\View
{
    public function execute()
    {
        // Do your stuff here
        return parent::execute();
    }
}

Możesz zastąpić inne bloki, modele i kontrolery, stosując to samo podejście.


Wygląda na to, że zastąpienie klasy \ Magento \ Katalog \ Blok \ Produkt \ Lista Produkt nie działa (w Magento 2.2 Może?), Odsyłacz - github.com/magento/magento2/issues/13152
Aniruddha A Deshpande

0

Aby zastąpić klasę, musisz utworzyć moduł, w którym możesz dodać plik etc/di.xmli Block/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


0

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ć.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.