Как переопределить блоки в v2.1

14

Я пытаюсь переопределить блок Topmenu в Magento 2.1, но не могу найти руководство для этого. Все, что я нашел здесь и где-либо еще, кажется, применимо только к версии 2.0, которая, похоже, использует другую структуру папок, или имеет только частичные примеры кода, которые ожидают, что я уже знаю их правильный контекст (чего я не знаю).

Моя текущая структура папок для пользовательской темы app/design/frontend/Vendor/theme_name. В рамках этого у меня есть файлы регистрации, темы и композитора, а также папки для различных модулей, например, Magento_Themeи Magento_Search.

Из того, что я понимаю, мне нужно начать с 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="[Namespace]\[Module]\Block\Html\Topmenu" />
</config>

Я также понимаю, что следующим шагом является добавление Block/Html/Topmenu.phpфайла, подобного приведенному ниже (снова отредактированный из приведенного выше источника):

namespace [Namespace]\[Module]\Block\Html;

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

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

  }

}

Тем не менее, мне не ясно, для чего я должен использовать [Namespace]и [Module]где разместить эти файлы. Я пытался использовать имя поставщика и темы, а также размещении etcи Blockпапки app/design/frontend/Vendor/theme_name, а также размещение их в app/design/frontend/Vendor/theme_name/Magento_Theme, о внесении изменений в пространстве имен Vendor\theme_name\Magento_Theme\Block\Html, но и не имеют никакого эффекта.

Если бы кто-нибудь мог помочь объяснить, что именно мне нужно сделать, чтобы переопределить блок Topmenu (и путем вывода любого другого блока) в версии 2.1, я был бы очень признателен.

добавление

Я попытался ответить Кхоа ТруонгДинь , но это никак не повлияло. Я использовал следующие файлы:

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__
);

Я затем удаляют содержимое pub/static/frontend, var/generationи var/view_preprocessed, и очистили кэш Magento. В подменю не добавлен предполагаемый «тестовый» класс:

<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>
MichaelRushton
источник
Вы пытались создать несколько подкатегорий?
Khoa TruongDinh
Я не уверен, что вы имеете в виду. В данный момент я просто пытаюсь добавить класс «test» в подменю, ulчтобы подтвердить, что я успешно переопределил класс Topmenu.
Майкл Раштон
Как вы можете это сделать? Мой гид может вам помочь?
Khoa TruongDinh
Я следовал твоим инструкциям, насколько я понял, но это не сработало. Мой пользовательский модуль Topmenu игнорируется и используется поведение по умолчанию.
Майкл Раштон
В выходные я еще раз проверю и предоставлю свое решение.
Khoa TruongDinh

Ответы:

20

Блок переопределения:

Создайте свой собственный модуль в app/codeпапке.
Мы можем использовать preferenceдля переопределения класса в Magento 2.

Приложение / код / ​​Vendor / модуль / и т.д. / 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>

Приложение / код / ​​Vendor / модуль / блок / Html / Topmenu.php

<?php

namespace Vendor\Module\Block\Html;

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

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

    }

}

Временное решение: в
настоящее время кажется, что описанные выше шаги не могут полностью переопределить блок. Нам нужно создать новую пользовательскую тему. А затем создайте default.xmlфайл:

приложение / дизайн / интерфейс / Vendor / Тема / Magento_Theme / макет / 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>

Это может быть ошибка в Magento: мы вынуждены переписывать шаблон в Magento2 при переписывании блока?

[РЕДАКТИРОВАТЬ]

1) Мы можем установить шаблон:

Приложение / код / ​​Vendor / модуль / блок / Html / Topmenu.php

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

2) Установите шаблон через Xml:

Например:

Приложение / код / ​​Vendor / модуль / вид / интерфейс / расположение / 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>

Не забудьте создать registration.phpи module.xml.

Мы создаем новый модуль, потому что переопределяем класс Magento. Когда мы хотим переопределить любой класс, мы должны создать новый модуль .

Пользовательская тема app/design/frontendсодержит:
--layout
--templates
--js
--html шаблоны (шаблоны нокаута)
--less, css
--etc ...

Узнайте больше здесь и здесь .

Стандарт автозагрузки и соглашение об именах:

Для [Namespace]и [Module]мы должны читать больше здесь:

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

Хоа ТруонгДинь
источник
Спасибо, но я не смог заставить это работать. Я отредактировал свою попытку в своем вопросе, чтобы вы могли видеть, где я неизбежно ошибся.
Майкл Раштон
Что за шаблон?
Майкл Раштон
Я обновил свой ответ. Кажется, что есть ошибка Magento. Нам нужно создать новую пользовательскую тему. А затем создайте макет, чтобы снова установить класс.
Khoa TruongDinh
Да, это сработало. Большое спасибо. День, потраченный на ошибку ...
MichaelRushton
мне нужно переопределить файл блока в файле custom_account_create.xml, расположенном в моем пользовательском файле theme.xml, в папке Magento_Customer. который по умолчанию. xml, мне нужно изменить magento_theme или magento_customer ?? Я не могу переопределить block.i я использую Magento2.1 лучше переместить Magento 2.1.3 ??
Виджай б
3

Для переопределения каталога товаров ListProduct block.

1) Создайте файл di.xml в папкеVendor/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) Создать файл блокировки ListProduct.php в папкеVendor/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
    }
}

Для переопределения каталога модели продукта.

1) Добавить предпочтение в 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\Catalog\Model\Product" type="Vendor\Module\Model\Rewrite\Catalog\Product" />
</config> 

2) Создать файл модели Product.php в папкеVendor/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();
    }

}

Для переопределения контроллера

1) Добавить предпочтение в di.xml

2) Создайте файл View.php Controller вVendor/Module/Controller/Rewrite/Product

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

Вы можете переопределить другие блоки, модели и контроллеры, используя тот же подход.

Принц Патель
источник
Похоже, переопределение класса \ Magento \ Catalog \ Block \ Product \ ListProduct не работает (в Magento 2.2 Может быть?), См. Ссылку - github.com/magento/magento2/issues/13152
Aniruddha A Deshpande
0

Чтобы переопределить класс , вы должны создать модуль , где вы можете добавить etc/di.xmlи Block/Html/Topmenu.phpфайл (выше кода , публикуемый Вами)

где Namespace - это имя вашего поставщика, а Module - имя вашего модуля. Например: Magento - это пространство имен, а тема - имя модуля.

Для получения дополнительной информации о том, как создать модуль, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure

Майк
источник
0

Из-за этой ошибки: https://github.com/magento/magento2/issues/3724 вы не можете просто настроить классы блоков.

1) (предпочтительно) Вместо этого нужно использовать плагин для этого класса и изменить то, что вам нужно. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

2) Или, если вы действительно хотите сделать предпочтительный способ, вам нужно также скопировать шаблон из ядра в ваш модуль / тему и обновить его с помощью XML, чтобы вместо этого использовать этот шаблон, тогда он волшебным образом начнет работать.

Ozzie
источник