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?

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
}

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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.