Layout local.xml versus Modullayout

7

Ich habe vor kurzem begonnen, das local.xmlals meinen Spielplatz für Layouts zu verwenden. Bevor ich meine Zweifel hatte, es aus ... Gründen zu benutzen.
Ich habe die Vorteile gesehen, aber jetzt bin ich gegen eine Mauer gestoßen.
In der Standardlayoutdatei catalog.xmlbefindet sich ein bestimmter Block (Name nicht wichtig). Mit dem habe layout.xmlich einen generischen untergeordneten Block hinzugefügt, in dem ich andere Blöcke platzieren möchte.

<reference name="not.important">
    <block type="core/text_list" name="extra.left.menu" as="extra" />
</reference>

So weit, ist es gut.
Aber jetzt habe ich eine Erweiterung, die dem oben deklarierten einen untergeordneten Block hinzufügen soll.
Wenn ich diesen neuen Block hinzufüge local.xml, funktioniert er gut.

<block type="core/text_list" name="extra.left.menu" as="extra">
    <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
</block>

Ich möchte dies jedoch nicht tun, local.xmlda diese neue Erweiterung möglicherweise in Zukunft deaktiviert wird. Wenn ich es über local.xmldie Erweiterung mache und sie deaktiviere, werden meine Protokolldateien überflutet, da der Block nicht mehr existiert.
Also füge ich in meiner Erweiterungslayoutdatei Folgendes hinzu:

<reference name="extra.left.menu">
    <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
</reference>

Aber so funktioniert es nicht. Ich habe das Gefühl, dass dies passiert, weil die local.xmlDatei zuletzt geladen wurde und ich keine Modulabhängigkeit hinzufügen kann, sodass meine Erweiterungslayoutdatei danach geladen wird layout.xml.
Wie soll ich das angehen? Habe ich etwas falsch gemacht?
Oder wenn ich es so will, muss ich die "gute alte Art" des Klonens catalog.xmlin meinem Thema verwenden und diesen neuen Block in das catalog.xmlmeines Themas einfügen?

Marius
quelle
Ich gehe davon aus, dass eine deaktivierte ifconfig auf dem Frontend-Display Ihre Anforderungen nicht abdeckt
David Manners
@ DavidManners. Ja und nein. Wenn mein Modul vollständig verschwindet und ifconfig möglicherweise nicht hilft. Aber wenn jemand das Modul entfernt, sollte es auch die Datenbank bereinigen, damit es funktioniert.
Marius
Ich habe mir das kurz angesehen und glaube nicht, dass das funktionieren würde. Sie können dem Block jederzeit einen neuen Knoten hinzufügen und die Art und Weise ändern, wie Blöcke generiert werden, aber das ist verrücktes Gerede :)
David Manners

Antworten:

6

Beim Rendern des Layouts in Magento werden einige Schritte ausgeführt:

  1. Handles sind definiert (Standard, catalog_product_view usw.)
  2. Alle XML-Dateien werden geladen und zu einer einzigen großen XML-Datei zusammengeführt. Diese Datei wird irgendwo im Cache gespeichert.
  3. Der Inhalt aller Handles wird geladen und in einer Seiten-XML-Datei zusammengeführt.
  4. Die Reihenfolge, in der die XML-Dateien geladen werden, ist alphabetisch und die Datei local.xml wird zuletzt geladen (es gibt auch Datenbanklayout-Updates, die noch später geladen werden (Quelle https://github.com/OpenMage/magento-mirror/blob/magento) -1,9 / app / code / core / Mage / Core / Modell / Layout / Update.php # L433-L438 )
  5. Schließlich wird das XML analysiert und die Blöcke initiiert.

Warum funktioniert Ihr Beispiel nicht? Dies liegt daran, dass die Modul-XML-Datei vor der Datei local.xml geladen wird. Was passiert ist, dass das System zuerst versucht, einen Block zu einer Referenz (zu einem Block) hinzuzufügen, die noch nicht existiert.

So lösen Sie das Problem: Sie können ein Update verwenden. Updates werden vor den Handles platziert, in denen sie aufgerufen werden.

<default>
    <update handle="awesome_new_container_handle"/>
</default>

<awesome_new_container_handle>
    <reference name="not.important">
        <block type="core/text_list" name="extra.left.menu" as="extra" />
    </reference>
</awesome_new_container_handle>

Und fügen Sie in Ihrer anderen Moduldatei den Block hinzu, wie Sie es getan haben.

<default>
    <reference name="extra.left.menu">
        <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
    </reference>
</default>
Paul Hachmang
quelle
Sind Sie zu 100% sicher, dass diese Lösung funktioniert? Ich habe das starke Gefühl, dass dies nicht funktionieren würde, da die Aktualisierung innerhalb des Handles defaultüber erfolgt local.xmlund Sie auf das defaultLayout-Handle selbst in einer benutzerdefinierten Layout-XML-Datei verweisen . Wenn Sie ein anderes Layout-Handle in dieser Datei verwenden, funktioniert es. Hab ich recht?
Rajeev K Tomy
Das hat nicht genau funktioniert. Aber es gab mir eine Idee und ich brachte es zum Laufen. Ich habe 2 Layoutgriffe verwendet. Also habe ich das Markup local.xmlin einem Handle local_xml_handleund das Markup aus der Erweiterungslayoutdatei in einem anderen Handle hinzugefügt extension_layout_handle. Dann habe ich beide local.xmlnacheinander benutzt. Daher wird das Layout-Handle aus der Erweiterung nach dem ersten angewendet <default><update handle="local_xml_handle" /><update handle="extension_layout_handle" /></default>. Wenn ich meine Erweiterung deaktiviere, gibt es keine, extension_layout_handlesodass nichts geladen werden kann. Vielen Dank.
Marius
Oh, und danke für die nette Erklärung für den Ablauf der Layoutdateien. Ich bin sicher, dass zukünftige Leser dies auch schätzen werden.
Marius
1

Dies ist über LAYOUT XML FILES nicht möglich. Weil die local.xmlDatei endlich geladen wird. Ein Block, der in einer local.xml-Datei "definiert" ist, kann daher nicht über eine andere Layoutdatei "referenziert" werden.

Normalerweise werde ich jeden Beobachter verwenden, um in einer solchen Situation einen Block hinzuzufügen.

Es gibt jedoch einen alternativen Weg, denke ich. Sie können diesen Block im defaultHandle durch local.xmlDatei definieren. Jetzt eröffnet sich eine Verwendungsmöglichkeit layout handles, die nach dem defaultLayout-Handle von Magento berücksichtigt wird. Da der Block über das defaultHandle enthalten ist und Sie den Block über ein anderes Layout-Handle über Ihre eigene Layout-XML-Datei referenzieren, ist Magento jetzt über Ihren Block informiert, auch wenn er über eine local.xmlDatei hinzugefügt wird.

local.xml

<default>
    <reference name="not.important">
        <block type="core/text_list" name="extra.left.menu" as="extra" />
    </reference>
</default>

your_layout.xml

<custom_handle> <!-- anything except `default` -->
    <reference name="extra.left.menu">
        <block type="myextension/some_block" template="some/template.phtml" as="some_name" name="some_name" />
    </reference>
</custom_handle>

BEARBEITEN

Zunächst möchte ich sagen, dass ich genug Zeit für dich habe :-)

Ich habe meinen Code getestet, indem ich eine Demo erstellt habe. Das habe ich versucht. Ich habe diesen Code in die local.xmlDatei eingefügt

<layout>
    <default>
        <reference name="content">
            <block type="core/text_list" name="extra.left.menu" as="extra" />
        </reference>
    </default>
</layout>

Dann habe ich unten Code direkt in die catalog.xmlDatei eingefügt .

<catalog_category_layered translate="label">
        ....

        <reference name="content">
            <reference name="extra.left.menu">
                <block type="core/template" template="test.phtml" as="some_name" name="some_name" />
            </reference>
            ......
        </reference>
</catalog_category_layered>

Dann habe ich eine geschichtete Kategorie geladen, ich sehe dort Inhalte test.phtmldavon. (Bitte nicht, ich habe core/templateBlock als untergeordneten Block für diesen Testzweck verwendet. In Ihrem Fall wird er jedoch durch Ihren eigenen Block ersetzt. Aber es ist überhaupt kein Problem. Beide Fälle sind etwas gleich.)

Ich bin hier

Mein Punkt ist also, dass diese Methode definitiv funktioniert. Ich bin mir in diesem Punkt sicher, weil ich diesen Trick schon oft benutzt habe und mein ultimativer Guru für das Magento-Layout @alanstorm ist :-)

Rajeev K Tomy
quelle
Entschuldigung, das hat nicht funktioniert. Aber danke, dass du dir Zeit genommen hast.
Marius
Danke für den Versuch. Ich habe meine Antwort aktualisiert. Nur um Sie darüber zu informieren, ist meine Methode nicht falsch.
Rajeev K Tomy
Wenn Sie sagen, dass es funktioniert, glaube ich Ihnen. es bedeutet, dass ich es nicht richtig gemacht habe. Ich werde es nochmal versuchen.
Marius
Ich warte auf Ihre Antwort. Nehmen Sie sich Zeit, um es zu testen :-)
Rajeev K Tomy
Komische Sache. Es funktioniert, wenn ich den extra.left.menuBlock direkt in den contentBlock einfüge. Aber es ist nicht so, wenn ich es in einen anderen Block einfüge, der ein Kind von contentoder ist left. Ich denke, das verdient eine +1. Wie auch immer, verbringen Sie keine Zeit mehr damit. Ich bevorzuge den Ansatz mit 2 Layoutgriffen. Wie ich in einem der Kommentare zu dieser Antwort erklärt habe: magento.stackexchange.com/a/41624/146 . Irgendwie ist es für mich sauberer.
Marius