Як перекрити блоки в 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>

Ви намагалися створити кілька підкатегорій?
Khoa TruongDinh

Я не впевнений, що ти маєш на увазі. На даний момент я просто намагаюся додати "тестовий" клас до підменю, ulщоб підтвердити, що я успішно перемінив клас Topmenu.
MichaelRushton

Як ви можете це зробити? Мій путівник може вам допомогти?
Khoa TruongDinh

Я дотримувався ваших інструкцій, як я краще зрозумів, але це не спрацювало. Мій спеціальний модуль Topmenu ігнорується та використовується поведінка за замовчуванням.
MichaelRushton

У вихідні я ще раз перевірю і дам вам своє рішення.
Khoa TruongDinh

Відповіді:


20

Блок перевизначення:

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

додаток / код / ​​Постачальник / Модуль / тощо / 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>

додаток / код / ​​Постачальник / Модуль / Блок / 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файл:

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>

Це може бути помилка Magento: чи ми змушені переписати шаблон у Magento2 під час перезапису блоку?

[EDIT]

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

додаток / код / ​​Постачальник / Модуль / Блок / Html / Topmenu.php

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

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

Наприклад:

app / code / Постачальник / Модуль / 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>

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

Ми створюємо новий модуль, оскільки переосмислюємо клас Magento. Коли ми хочемо перекрити будь-який клас, ми повинні створити новий модуль .

Спеціальна тема під app/design/frontend: містить:
--layout
--templates
--js
--html шаблони (Knockout templates)
--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


Дякую, але мені не вдалося змусити це працювати. Я відредагував свою спробу свого запитання, щоб ви могли бачити, де я неминуче пішов не так.
MichaelRushton

Який шаблон?
MichaelRushton

Я оновив свою відповідь. Здається, є помилка 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 ??
vijay b

3

Для блоку переліку продуктового каталогу СписокПродукт.

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) Створіть файл Block 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) Створіть файл Model.php Model у папці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 за адресоюVendor/Module/Controller/Rewrite/Product

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

Ви можете замінити інші блоки, моделі та контролери, використовуючи цей самий підхід.


Схоже, перекриття класу \ Magento \ Каталог \ Блок \ Продукт \ СписокПродукт не працює (в Magento 2.2 Можливо?), Перейдіть за
A

0

Для зміни класу потрібно створити модуль, куди ви можете додати файл etc/di.xmlта Block/Html/Topmenu.phpфайл (вище розміщений вами код)

де простір імен - ваше ім’я постачальника, а модуль - ваше ім'я. Наприклад: 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/isissue/3724 ви не можете просто надавати перевагу блоковим класам.

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.