So überschreiben Sie Blöcke in v2.1


14

Ich versuche, den Topmenu-Block in Magento 2.1 zu überschreiben, finde aber keine Anleitung dazu. Alles, was ich hier und anderswo gefunden habe, scheint entweder nur auf Version 2.0 zuzutreffen, die anscheinend eine andere Ordnerstruktur verwendet, oder es gibt nur teilweise Codebeispiele, von denen ich erwartet habe, dass ich den richtigen Kontext bereits kenne (was ich nicht tue).

Meine aktuelle Ordnerstruktur für ein benutzerdefiniertes Thema ist app/design/frontend/Vendor/theme_name. Darin befinden sich die Registrierungs-, Themen- und Komponistendateien sowie Ordner für die verschiedenen Module, z . B. Magento_Themeund Magento_Search.

Soweit ich weiß, muss ich mit einer etc/di.xmlDatei wie der folgenden beginnen, die von hier aus bearbeitet wurde :

<?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>

Ich verstehe auch, dass der nächste Schritt darin besteht, eine Block/Html/Topmenu.phpDatei wie die folgende hinzuzufügen (erneut bearbeitet aus der obigen Quelle):

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

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

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

  }

}

Mir ist jedoch nicht klar, wofür [Namespace]und [Module]wo ich diese Dateien ablegen soll. Ich habe versucht , den Hersteller und Themennamen und die Platzierung etcund Blockin Ordnern app/design/frontend/Vendor/theme_name, sowie sie bei der Platzierung app/design/frontend/Vendor/theme_name/Magento_Theme, zur Änderung der Namensräume Vendor\theme_name\Magento_Theme\Block\Html, aber weder irgendeine Wirkung hat.

Wenn jemand helfen könnte, genau zu erklären, was ich tun muss, um den Topmenu-Block (und durch Rückschluss auf einen anderen Block) in Version 2.1 zu überschreiben, wäre ich sehr dankbar.

Nachtrag

Ich habe versucht, Khoa TruongDinhs Antwort zu geben, aber sie hatte keine Auswirkungen. Ich habe die folgenden Dateien verwendet:

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

Ich habe dann den Inhalt entfernt pub/static/frontend, var/generationund var/view_preprocessed, und die Magento Cache geleert. Dem Untermenü wurde nicht die beabsichtigte "Test" -Klasse hinzugefügt:

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

Sie haben versucht, mehrere Unterkategorien zu erstellen?
Khoa TruongDinh

Ich bin mir nicht sicher was du meinst. Im Moment versuche ich nur, dem Untermenü eine "Test" -Klasse hinzuzufügen, um ulzu bestätigen, dass ich die Klasse "Topmenu" erfolgreich überschrieben habe.
MichaelRushton

Wie kannst du das machen? Mein Führer kann Ihnen helfen?
Khoa TruongDinh

Ich habe Ihre Anweisungen befolgt, so gut ich verstanden habe, aber es hat nicht funktioniert. Mein benutzerdefiniertes Topmenü-Modul wird ignoriert und das Standardverhalten wird verwendet.
MichaelRushton

Am Wochenende werde ich nochmal nachsehen und dir meine Lösung geben.
Khoa TruongDinh

Antworten:


20

Block überschreiben:

Erstellen Sie Ihr eigenes Modul unter app/codeOrdner.
Mit können wir preferencedie Klasse in Magento 2 überschreiben.

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)
    {

    }

}

Temporäre Lösung:
Momentan scheinen die obigen Schritte den Block nicht vollständig überschreiben zu können. Wir müssen ein neues benutzerdefiniertes Thema erstellen. Und dann erstelle die default.xmlDatei:

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>

Es könnte ein Magento-Fehler sein: Müssen wir eine Vorlage in Magento2 neu schreiben, wenn wir einen Block neu schreiben?

[BEARBEITEN]

1) Wir können die Vorlage einstellen:

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

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

2) Vorlage über XML setzen:

Beispielsweise:

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>

Denken Sie daran, registration.phpund zu erstellenmodule.xml .

Wir erstellen das neue Modul, weil wir die Klasse von Magento überschreiben. Wenn wir eine Klasse überschreiben wollen, müssen wir ein neues Modul erstellen .

Das benutzerdefinierte Thema unter app/design/frontendenthält:
--layout
--templates
--js
--html templates (Knockout templates)
--less, css
--etc ...

Lesen Sie hier und hier mehr .

Autoloading-Standard und Namenskonvention:

Für [Namespace]und [Module]sollten wir hier mehr lesen:

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


Danke, aber ich konnte das nicht zum Laufen bringen. Ich habe meinen Versuch in meine Frage geändert, damit Sie sehen können, wo ich unweigerlich einen Fehler gemacht habe.
MichaelRushton

Was ist die Vorlage?
MichaelRushton

Ich habe meine Antwort aktualisiert. Es scheint, dass es einen Magento-Fehler gibt. Wir müssen ein neues benutzerdefiniertes Thema erstellen. Erstellen Sie dann das Layout, um die Klasse erneut festzulegen.
Khoa TruongDinh

Ja, das hat funktioniert. Vielen Dank. Ein Tag, der durch einen Bug verschwendet wurde ...
MichaelRushton

Ich muss die Blockdatei in "custom_account_create.xml" überschreiben. Die Datei "custom theme.xml" befindet sich im Ordner "Magento_Customer". Die Datei "default.xml" muss "magento_theme" oder "magento_customer" geändert werden. Ich kann "block.i" nicht überschreiben. Ich verwende "Magento2.1" ist es besser, Magento 2.1.3 zu verschieben ??
vijay b

3

Zum Überschreiben des Katalogprodukts ListProduct-Block.

1) Erstellen Sie die Datei di.xml im OrdnerVendor/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) Erstellen Sie eine ListProduct.php-Blockdatei im OrdnerVendor/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
    }
}

Zum Überschreiben des Katalogproduktmodells.

1) Fügen Sie vorher Präferenz in di.xml hinzu

<?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) Erstellen Sie die Model-Datei Product.php im OrdnerVendor/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();
    }

}

Für übergeordnete Steuerung

1) Präferenz in di.xml hinzufügen

2) Erstellen Sie die View.php Controller-Datei unterVendor/Module/Controller/Rewrite/Product

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

Sie können andere Bausteine, Modelle und Steuerungen auf dieselbe Weise überschreiben.


Sieht aus wie Überschreibung der Klasse \ Magento \ Catalog \ blockieren \ Produkt \ ListProduct Arbeit nicht (? In Magento 2.2 Vielleicht) siehe Link - github.com/magento/magento2/issues/13152
Aniruddha A Deshpande

0

Um die Klasse zu überschreiben, müssen Sie ein Modul erstellen, in dem Sie die etc/di.xmlund Block/Html/Topmenu.php-Datei (über dem von Ihnen geposteten Code) hinzufügen können.

Dabei ist Namespace der Name Ihres Herstellers und Module der Name Ihres Moduls. Zum Beispiel: Magento ist Namespace und Theme ist Modulname.

Weitere Informationen zum Erstellen eines Moduls finden Sie unter http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-file-structure.html#module-file-structure


0

Aufgrund dieses Fehlers: https://github.com/magento/magento2/issues/3724 können Sie nicht nur Blockklassen bevorzugen.

1) (Bevorzugt) Stattdessen können Sie ein Plugin für diese Klasse verwenden und die erforderlichen Änderungen vornehmen. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

2) Oder wenn Sie wirklich die bevorzugte Methode verwenden möchten, müssen Sie die Vorlage auch vom Kern in Ihr Modul / Thema kopieren und mit XML aktualisieren, damit stattdessen diese Vorlage verwendet wird. Dann funktioniert sie auf magische Weise.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.