Jak zastąpić / przepisać klasę bloków w Magento 1?

12

Uwaga: Jest to pytanie kanoniczne, które w pełni wyjaśnia, jak działa przepisywanie bloków i może być użyte jako duplikat celu dla bardziej szczegółowych pytań „Jak zastąpić blok X” lub „Dlaczego moje przepisywanie nie działa”.

Zobacz także: Szukanie kanonicznych pytań dotyczących przesłonięć Magento 1

Powiedzmy, że muszę wprowadzić zmiany w klasie bloków podstawowych w module niestandardowym (zmień metody lub dodaj metody). Jak to zrobić krok po kroku?

Fabian Schmengler
źródło

Odpowiedzi:

23

Każdy blok lub grupa bloków jest zadeklarowana w config.xmlpliku modułu takiego jak ten (wewnątrz <global>znacznika).
Oto przykład z modułu katalogu

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

Oznacza to, że blok może zostać utworzony za pomocą aliasu, w catalog/class_name_herektórym class_name_herereszta ścieżki klasy zaczyna się od prefiksu.
Oznacza to catalog/class_name_here, że domyślnie zostanie zamapowany na Mage_Catalog_Block_Class_Name_Here.

Aby przepisać blok, musisz utworzyć moduł, który zależy od modułu, który próbujesz zmienić ( Magento_Catalog) w moim przykładzie.
I musisz dodać to config.xmlpod <global>tagiem.

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

Następnie utwórz klasę YourNamespace_YourModule_Block_Your_New_Class_Here(zgodnie ze strukturą folderów ZF) i spraw, aby ta klasa rozszerzyła klasę oryginalną.

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

Po zakończeniu wyłącz kompilację i włącz ją ponownie (w razie potrzeby) i wyczyść pamięć podręczną.

To nie zadziała dla bloków abstrakcyjnych.
Działa tylko w przypadku klas, które są tworzone.

Przykład

Załóżmy, że chcesz przepisać plik app \ code \ core \ Mage \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php, który ma klasę Mage_Catalog_Block_Product_View_Options_Type_Selectwe własnym module Marius_Test .

Następnie potrzebujesz tego wpisu w 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
}
Marius
źródło
Nie działa. Próbuję zastąpić klasę Mage_Catalog_Block_Product_View_Options_Type_Selectw app \ code \ local \ WR \ EPO \ Block \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php . Próbowałem tak: codepen.io/anon/pen/WYOqBr
Black
A jeśli to nie zadziała, uważasz, że moja odpowiedź jest zła, dlatego głosuj za nią, zamiast myśleć, że może robisz coś złego. W każdym razie ... zastąpić ten <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>z <product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>i upewnij się, że nie istnieją przestrzenie wewnątrzproduct_view_options_type_select
Marius
Głosowałem za odrzuceniem, ponieważ twoja odpowiedź nie była precyzyjna i chociaż podążałem za nią krok po kroku, nie przyniosła właściwego rezultatu. Napisałeś, że musimy użyć nazwy klasy, więc użyłem jej i to nie zadziałało. Musimy użyć product_view_options_type_selectzamiast prawdziwej nazwy klasy Mage_Catalog_Block_Product_View_Options_Type_Select. Jeśli odpowiednio zmienisz swoją odpowiedź, będę głosować.
Czarny
Jeśli czytasz to krok po kroku, przegapiłeś krok. Ten, w którym wyjaśniam, czym jest alias klasy. Jeśli po prostu skopiujesz wklej zastąp, dostaniesz go do pracy. 17 osób zrozumiało. Chyba dobrze to wytłumaczyłem
Marius
Tak, ale brakuje dobrego przykładu, abyśmy mogli zapewnić, że poprawnie zrozumieliśmy twoją teorię
Black
4

Dla mojego punktu widzenia zastąpienie i przepisanie tych dwóch różnych rzeczy,

Nadpisanie:

Kiedy używamy mechanizmu zastępczego projektu, wówczas zastępujemy

Przepisać:

Kiedy przepisujemy klasy Magento Core w naszej klasie, robimy przepisywanie.

1) Przykład zastąpienia:

Jeśli muszę przesłonić app/code/core/Mage/Catalog/Block/Product/List.phpplik, kopiuję do modułu lokalnego tą samą ścieżką, jak pokazano poniżejapp/code/local/Mage/Catalog/Block/Product/List.php

To nie jest sugerowane przez magento Ale możesz to zrobić w ten sposób.

2) Przykład przepisywania:

Jeśli chcę przepisać tę klasę bloku, Mage_Adminhtml_Block_Sales_Order_Createto koduję w moim module config.xml jak poniżej

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

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

I w mojej klasie Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

Koduję jak poniżej

class Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create extends Mage_Adminhtml_Block_Sales_Order_Create {
      My Function Or funcions That I want to Rewrite..
}
Murtuza Zabuawala
źródło
2

Ważne jest, aby dodać tutaj, że przepisywanie bloków (podobnie jak wszystkie inne przepisywania modułów Magento) implikuje większy wysiłek konserwacyjny i dlatego powinno być traktowane jako ostatnia szansa na rozszerzenie funkcjonalności po manipulacji konfiguracją, zdarzeniach i dostosowaniu motywu.

Potencjalny problem 1: Przepisany szablon nie zostanie zaktualizowany, gdy Ty lub inny opiekun zaktualizujesz pliki źródłowe Magento. Oznacza, że ​​poprawka zabezpieczeń lub ulepszenia nie zostaną zastosowane w kodzie. To samo dotyczy innych przepisanych klas, w tym bloków, ale zależy od tego, ile przeróbek zostało zrobionych (patrz poniżej).

Potencjalny problem 2: Przepisany blok (lub inna klasa) może wydawać się przepisany przez inne rozszerzenie, które Ty lub inny opiekun będzie próbował zainstalować. Następnie będziesz musiał rozwiązać ten konflikt.

Alternatywa 1: Użyj zdarzeń, tj. Przekop kod, który właśnie chcesz przepisać, i sprawdź, czy istnieją zdarzenia, które mogą być wykorzystane do osiągnięcia pożądanej funkcjonalności.

Alternatywa 2: Przepisz inteligentnie, tzn. Rozejrzyj się: może sprawdź miejsce, w którym tworzona jest instancja klasy, którą zamierzasz przepisać i sprawdź, czy możesz wpłynąć na to, która klasa zostanie wybrana przez konfigurację lub zdarzenia; być może istnieje klasa, która pozwala zastąpić 3-liniową metodę, aby zastąpić nazwę klasy, zamiast kopiować 30-liniową metodę z oryginalnej klasy do przepisanej.

Anton Boritskiy
źródło