Come sovrascrivere i blocchi in v2.1


14

Sto cercando di ignorare il blocco Topmenu in Magento 2.1 ma non riesco a trovare alcuna guida per farlo. Tutto ciò che ho trovato qui e altrove sembra applicarsi solo alla versione 2.0 che sembra utilizzare una diversa struttura di cartelle o ha solo esempi di codice parziale che mi aspettano di conoscere già il loro contesto (cosa che non faccio).

La mia attuale struttura di cartelle per un tema personalizzato è app/design/frontend/Vendor/theme_name. All'interno di questo ho i file di registrazione, tema e compositore, nonché le cartelle per i vari moduli, ad esempio Magento_Themee Magento_Search.

Da quello che ho capito devo iniziare con un etc/di.xmlfile come di seguito, modificato da qui :

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

Capisco anche che il prossimo passo è aggiungere un Block/Html/Topmenu.phpfile come il seguente (di nuovo modificato dalla fonte sopra):

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

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

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

  }

}

Tuttavia, non mi è chiaro cosa dovrei usare per [Namespace]e [Module], o dove posizionare questi file. Ho provato a utilizzare il nome del fornitore e del tema, a posizionare le cartelle etce , nonché a inserirle , modificando gli spazi dei nomi in , ma nessuno dei due ha alcun effetto.Blockapp/design/frontend/Vendor/theme_nameapp/design/frontend/Vendor/theme_name/Magento_ThemeVendor\theme_name\Magento_Theme\Block\Html

Se qualcuno potesse aiutare a spiegare esattamente cosa devo fare per sovrascrivere il blocco Topmenu (e di conseguenza qualsiasi altro blocco) nella versione 2.1, sarei molto apprezzato.

appendice

Ho tentato la risposta di Khoa TruongDinh ma non ha avuto alcun effetto. Ho usato i seguenti file:

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

Ho quindi rimosso il contenuto di pub/static/frontend, var/generatione var/view_preprocessed, e arrossata la cache di Magento. Nel sottomenu non è stata aggiunta la classe "test" prevista:

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

Hai provato a creare più sottocategorie?
Khoa TruongDinh

Non sono sicuro di cosa intendi. Al momento sto solo cercando di aggiungere una classe "test" al sottomenu ulper confermare che ho superato con successo la classe Topmenu.
MichaelRushton,

Come puoi farlo? La mia guida può aiutarti?
Khoa TruongDinh,

Ho seguito le tue istruzioni come ho capito ma non ha funzionato. Il mio modulo Topmenu personalizzato viene ignorato e viene utilizzato il comportamento predefinito.
MichaelRushton,

Nel fine settimana, controllerò di nuovo e ti darò la mia soluzione.
Khoa TruongDinh,

Risposte:


20

Sostituisci blocco:

Crea il tuo modulo sotto la app/codecartella.
Possiamo usare preferenceper sovrascrivere la classe in Magento 2.

app / code / Venditore / modulo / 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 / Venditore / modulo / blocco / Html / Topmenu.php

<?php

namespace Vendor\Module\Block\Html;

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

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

    }

}

Soluzione temporanea:
attualmente, sembra che i passaggi precedenti non possano annullare completamente il blocco. Dobbiamo creare un nuovo tema personalizzato. E quindi, crea il default.xmlfile:

app / design / frontend / Venditore / a tema / 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>

Potrebbe essere un bug di Magento: siamo costretti a riscrivere un modello in Magento2 quando riscriviamo un blocco?

[MODIFICARE]

1) Possiamo impostare il modello:

app / code / Venditore / modulo / blocco / Html / Topmenu.php

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

2) Imposta modello tramite Xml:

Per esempio:

app / code / Venditore / modulo / 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>

Ricorda di creare registration.phpe module.xml.

Creiamo il nuovo modulo perché stiamo scavalcando la classe di Magento. Quando vogliamo sovrascrivere qualsiasi classe, dobbiamo creare un nuovo modulo .

Il tema personalizzato sotto app/design/frontendcontiene:
--layout
--templates
--js
--html modelli (modelli knockout)
--less, css
--etc ...

Leggi di più qui e qui .

Standard di caricamento automatico e convenzione di denominazione:

Per [Namespace]e [Module], dovremmo leggere di più qui:

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


Grazie, ma non sono riuscito a farlo funzionare. Ho modificato il mio tentativo nella mia domanda in modo da poter vedere dove ho inevitabilmente sbagliato.
Michael Rushton,

Qual è il modello?
MichaelRushton,

Ho aggiornato la mia risposta. Sembra che ci sia un bug di Magento. Dobbiamo creare un nuovo tema personalizzato. Quindi, crea il layout per impostare nuovamente la classe.
Khoa TruongDinh

Sì, ha funzionato. Grazie mille. Una giornata sprecata per un insetto ...
MichaelRushton,

devo sovrascrivere il file di blocco in custom_account_create.xml che si trova nel mio file theme.xml personalizzato è nella cartella Magento_Customer. che default.xml devo cambiare magento_theme o magento_customer ?? non riesco a scavalcare block.i sto usando Magento2.1 meglio spostare Magento 2.1.3 ??
Vijay b,

3

Per sostituire il catalogo Elenco prodotti Blocco prodotto.

1) Crea il file di.xml nella cartellaVendor/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) Creare il file di blocco ListProduct.php nella cartellaVendor/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
    }
}

Per sostituire il modello di prodotto del catalogo.

1) Aggiungi la preferenza in di.xml prima

<?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) Crea il file del modello Product.php nella cartellaVendor/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();
    }

}

Per l'override del controller

1) Aggiungi preferenza in di.xml

2) Crea il file del controller View.php suVendor/Module/Controller/Rewrite/Product

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

È possibile ignorare altri blocchi, modelli e controller usando lo stesso approccio.


Sembra sovrascrivere la classe \ Magento \ Catalog \ Block \ Product \ ListProduct non funziona (in Magento 2.2 forse?), Fare riferimento al link - github.com/magento/magento2/issues/13152
Aniruddha A Deshpande


0

A causa di questo errore: https://github.com/magento/magento2/issues/3724 non puoi limitarti alle classi di blocco delle preferenze.

1) (preferibile) Ciò che funziona invece è usare un plugin per quella classe e cambiare ciò di cui hai bisogno. http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

2) O se vuoi davvero fare la preferenza, allora devi anche copiare il modello dal core al tuo modulo / tema e aggiornarlo con xml in modo che usi quel modello, quindi inizierà magicamente a funzionare ..

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.