Come posso sovrascrivere / riscrivere una classe di blocco in Magento 1?


12

Nota: questa è intesa come una domanda canonica che spiega come funzionano le riscritture dei blocchi e che può essere utilizzata come destinazione duplicata per domande più specifiche su "Come posso sovrascrivere il blocco X" o "Perché la mia riscrittura non funziona".

Vedi anche: Alla ricerca di domande canoniche sulle sostituzioni di Magento 1

Diciamo, devo apportare modifiche a una classe di blocchi core in un modulo personalizzato (cambiare metodi o aggiungere metodi). Come posso fare questo, passo dopo passo?

Risposte:


23

Ogni blocco o gruppo di blocchi è dichiarato nel config.xmlfile di un modulo come questo (all'interno del <global>tag).
Ecco un esempio dal modulo del catalogo

    <blocks><!-- marks definition of a block group -->
        <catalog><!-- unique alias for blocks in the module -->
            <class>Mage_Catalog_Block</class><!-- class prefix for all blocks -->
        </catalog>
    </blocks>

Ciò significa che un blocco può essere istanziato usando l'alias catalog/class_name_heredove si class_name_heretrova il resto del percorso di classe a partire dal prefisso.
Questo significa catalog/class_name_hereche verrà mappato per impostazione predefinita su Mage_Catalog_Block_Class_Name_Here.

Per riscrivere un blocco è necessario creare un modulo che dipende dal modulo che si sta tentando di modificare ( Magento_Catalog) nel mio esempio.
E devi aggiungere questo nel tag config.xmlsotto <global>.

<blocks>
    <catalog><!-- alias of the block group you are rewriting -->
        <rewrite><!-- reserved tag: specify that you are rewriting something -->
             <class_name_here>YourNamespace_YourModule_Block_Your_New_Class_Here</class_name_here> <!-- tag: the rest of the alias of the class you are rewriting. value: the name of your class that rewrites the core class -->
        </rewrite>
    </catalog>
</blocks>

Quindi creare la classe YourNamespace_YourModule_Block_Your_New_Class_Here(seguendo la struttura delle cartelle ZF) e fare in modo che questa classe estenda la classe originale.

class YourNamespace_YourModule_Block_Your_New_Class_Here extends Mage_Catalog_Block_Class_Name_Here
{
    //your awesome code here
}

Al termine, disabilitare la compilazione e abilitarla di nuovo (se necessario) e cancellare la cache.

Questo non funzionerà per i blocchi astratti.
Funziona solo per le classi che vengono istanziate.

Esempio

Supponiamo che tu voglia riscrivere il file app \ code \ core \ Mage \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php che ha la classe Mage_Catalog_Block_Product_View_Options_Type_Selectnel tuo modulo Marius_Test .

Quindi avresti bisogno di questa voce nel tuo config.xml:

<blocks>
    <catalog>
        <rewrite>
            <product_view_options_type_select>Marius_Test_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>
        </rewrite>
    </catalog>
</blocks>

app \ code \ local \ Marius \ Test \ Block \ Catalog \ Product \ View \ Options \ Type \ Select.php :

class Marius_Test_Block_Catalog_Product_View_Options_Type_Select extends Mage_Catalog_Block_Product_View_Options_Type_Select
{
    //your awesome code here
}

Non funziona. Provo a sovrascrivere la classe Mage_Catalog_Block_Product_View_Options_Type_Selectin app \ code \ local \ WR \ EPO \ Block \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php . L'ho provato in questo modo: codepen.io/anon/pen/WYOqBr
Black

E se non funziona, pensi che la mia risposta sia sbagliata, quindi riduci il voto invece di pensare che forse stai facendo qualcosa di sbagliato. Comunque ... sostituiscilo <Mage_Catalog_Block_Product_View_Options_Type_Select> WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select </Mage_Catalog_Block_Product_View_Options_Type_Select>con <product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>e assicurati che non ci siano spazi all'internoproduct_view_options_type_select
Marius

Ho annullato il voto perché la tua risposta non era precisa e anche se l'ho seguita passo dopo passo non ha prodotto il risultato giusto. Hai scritto che dobbiamo usare il nome della classe, quindi l'ho usato e non ha funzionato. Dobbiamo usare al product_view_options_type_selectposto del vero nome della classe Mage_Catalog_Block_Product_View_Options_Type_Select. Se cambi di conseguenza la tua risposta, voterò.
Nero,

Se lo leggi passo dopo passo hai perso un passaggio. Quello in cui spiego qual è l'alias di classe. Se copi solo copia incolla sostituirai. 17 persone comprese. Penso di averlo spiegato bene
Marius

Sì, ma manca un buon esempio in modo da poter essere sicuri di capire correttamente la tua teoria
Black,

4

Per il mio punto di vista, ignorare e riscrivere queste due cose sono diverse,

Oltrepassare:

Quando utilizziamo il meccanismo di fallback del design, stiamo eseguendo l'override

Riscrivere:

Quando riscriviamo le classi Magento Core nella nostra classe, allora stiamo riscrivendo.

1) Esempio di override:

Se app/code/core/Mage/Catalog/Block/Product/List.phpdevo sovrascrivere il file, lo copio nel mio modulo locale con lo stesso percorso mostrato di seguitoapp/code/local/Mage/Catalog/Block/Product/List.php

Questo non è suggerito da Magento Ma puoi farlo in questo modo.

2) Esempio di riscrittura:

Se voglio riscrivere questa classe di blocchi, Mage_Adminhtml_Block_Sales_Order_Createallora codice nel mio modulo config.xml come sotto

    <global>
        <blocks>
            <adminhtml>
                <rewrite>

                    <sales_order_create>Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create</sales_order_create>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>

E nella mia classe Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

Codifico come di seguito

class Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create extends Mage_Adminhtml_Block_Sales_Order_Create {
      My Function Or funcions That I want to Rewrite..
}

2

È importante aggiungere qui che le riscritture dei blocchi (così come tutte le altre riscritture dei moduli Magento) implicano un maggiore sforzo di manutenzione e quindi dovrebbero essere considerate come un'ultima possibilità per estendere la funzionalità dopo la manipolazione della configurazione, gli eventi e la personalizzazione del tema.

Potenziale problema 1: il modello riscritto non verrà aggiornato quando l'utente o altri manutentori aggiorneranno i file di origine di Magento. Significa che la correzione di sicurezza o il miglioramento non verranno applicati al tuo codice. Lo stesso vale per le altre classi riscritte, inclusi i blocchi, ma dipende dalla quantità di riscrittura eseguita (vedere di seguito).

Potenziale problema 2: Rewritten Block (o altra classe) potrebbe sembrare riscritto da un'altra estensione che l'utente o un altro manutentore tenteranno di installare. Quindi dovrai risolvere questo conflitto.

Alternativa 1: utilizzare gli eventi, ovvero scavare attraverso il codice che si sta per riscrivere e verificare se ci sono eventi che potrebbero essere utilizzati per ottenere la funzionalità desiderata.

Alternativa 2: Riscrivi in ​​modo intelligente, ovvero guardati intorno: magari controlla il luogo in cui viene istanziata la classe che stai per riscrivere e controlla se puoi influenzare quale classe viene scelta tramite configurazione o eventi; forse c'è una classe intorno che ti permette di sovrascrivere un metodo a 3 righe per sostituire il nome della classe invece di copiare il metodo a 30 righe dalla classe originale a quella riscritta.

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.