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.