Fehlerbehebung beim Laden von Layout-XML


36

TL; DR: Gibt es eine Möglichkeit, das Laden des Layouts zu debuggen? Wie ich glaube, widerspricht das Layout eines Moduls dem eines anderen.

Im Zusammenhang mit einer früheren Frage stellte ich die Frage, wie ein Modullayout für alle Themen angezeigt werden kann

Ich habe mein Modul erfolgreich in meine lokale Testumgebung (auch bekannt als mein Entwicklungs-PC) geladen, das Umschalten zwischen 3 verschiedenen Themen getestet und es ist in Ordnung. Dann habe ich das Modul in der Test- oder "Pre-Production" -Umgebung aktualisiert, in der es viele verschiedene Module gibt, einige proprietäre andere von uns. In dieser Umgebung zeigt das Modul nicht an, was auf der Produktvorderseite benötigt wird. Nach einigen Tests bin ich zu dem Schluss gekommen, dass das Problem beim Laden des Layouts liegen sollte.

Gibt es eine Möglichkeit, das Laden des Layouts zu debuggen, wie verschiedene Module ihre eigenen Blöcke ersetzen oder hinzufügen? Mein Punkt ist, dass ich glaube, dass es mindestens ein Modul gibt, das mit meinem in Konflikt stehen sollte. Und da wir so viele Module haben, suche ich nach einem anderen Ansatz, um die Module einzeln zu deaktivieren, und finde heraus, welches das Problem ist.

Meine config.xml-Datei ist:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Dts_Banners>
            <version>0.1.0</version>
        </Dts_Banners>
    </modules>
    <global>
        <blocks>
            <banners>
                <class>Dts_Banners_Block</class>
            </banners>
        </blocks>
  ....
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <attributesethandle>
                        <class>Dts_Banners_Model_Observer</class>
                        <method>addAttributeSetHandle</method>
                    </attributesethandle>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </global>    
  ....
</config>

Meine Observer-Datei:

<?php
class Dts_Banners_Model_Observer
{
    /**
     * Checks if the search text on the list of active campaigns (dts_banners_admin table) has some of the comma separated text on the product name
     * If text found, add a layout handle PRODUCT_CAMPAIGN_BANNER after PRODUCT_TYPE_<product_type_id> handle
     * This handle is handled on the banners.xml layout file that triggers the use of the Front.php frontend block
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer) {
        $product = Mage::registry('current_product');
        if (!($product instanceof Mage_Catalog_Model_Product)) return;
      ....
      ....
}

Dies ist meine Layoutdatei:

<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
    <default>
        <reference name="content">
            <block type="banners/front" name="banners.front" as="banners_front" template="banners/product.phtml" before="-"/>
        </reference>
    </default>
</layout>

Hatte vorher eine etwas andere wo <default></default>ich statt hatte <Product_Campaign_Banner></Product_Campaign_Banner>. Es hat auch funktioniert.

Meine product.phtml Datei:

<div class="visual">
    <?php echo $this->showCampaign(); ?>
</div>

Die product.phtmlDatei wird nicht geladen und daher showCampaignnicht ausgeführt. Dort wird der gesamte erforderliche HTML-Code erstellt.


2
Am besten ist es, wenn das lokale Umfeld so weit wie möglich
Fra

Das ist, was ich gerade mache, aber es ist nicht einfach, wir haben über 20 Module von Drittanbietern und sogar einige von ihnen arbeiten nicht an der Vorproduktionsumgebung und ihre Entwickler überprüfen den Code.
Jaroslaw

4
Ich bin sehr gespannt, warum diese Frage als zu lokal gekennzeichnet wurde. Die Frage bezieht sich auf das allgemeine Debuggen von Layouts, was, wenn Sie es nicht getan haben, sehr nützlich und allgemein anwendbar ist.
benmarks

Ich bin auch neugierig. Ich denke jedoch, dass dies dazu führen könnte, dass ich nach einigen Änderungen an anderen nur versuche, mein eigenes, sehr lokalisiertes Problem zu lösen. Und das bin ich auch, aber gleichzeitig hoffe ich, dass ich durch das Debuggen des Layout-Generierungsprozesses in der Lage bin, zu finden, wo sich mein Fehler befindet. Daher wird die Lösung für andere nützlich sein.
Jaroslaw

Antworten:


55

Sie können die kompilierten Layout-XML-Anweisungen protokollieren, die zum Generieren von Blöcken verwendet werden. Erstellen Sie einen Beobachter controller_action_layout_generate_blocks_before, und protokollieren Sie in der Beobachtermethode die Aktualisierungs-XML des transportierten Layoutobjekts:

public function logCompiledLayout($o)
{
    $req  = Mage::app()->getRequest();
    $info = sprintf(
        "\nRequest: %s\nFull Action Name: %s_%s_%s\nHandles:\n\t%s\nUpdate XML:\n%s",
        $req->getRouteName(),
        $req->getRequestedRouteName(),      //full action name 1/3
        $req->getRequestedControllerName(), //full action name 2/3
        $req->getRequestedActionName(),     //full action name 3/3
        implode("\n\t",$o->getLayout()->getUpdate()->getHandles()),
        $o->getLayout()->getUpdate()->asString()
    );

    // Force logging to var/log/layout.log
    Mage::log($info, Zend_Log::INFO, 'layout.log', true);
}

Die Ausgabe wird ähnlich sein wie:

2013-01-23T16:24:26+00:00 INFO (6): 
Request: cms
Full Action Name: cms_index_index
Handles:
    default
    cms_page
    STORE_default
    THEME_frontend_default_default
    cms_index_index
    page_two_columns_right
    customer_logged_out
Update XML:
<block name="formkey" type="core/template" template="core/formkey.phtml"/>
<label>All Pages</label>
<!-- ... ->

Scheint hilfreich, werde es morgen in der ersten Stunde ausprobieren
Jaroslaw

Ihre Antwort war die richtige, genau das, wonach ich gesucht habe. Das erstellte Protokoll gibt alle Handles, Anforderungen usw. beim Laden der Seite aus. Ich habe bestätigt, dass mein Handle korrekt in das Haupt-Handle-Array geladen wurde, aber aus irgendeinem Grund wird der entsprechende Block nicht geladen / angezeigt.
Jaroslaw

1
Und das sollte einfacher zu beheben sein, da das Layout ausgeschlossen wurde :-).
Benmarks

Ich gehe davon aus, dass Sie dies in der Action.php-Datei setzen? Wie wird das auch von Magento genannt?
Metropolis

"Beobachter erstellen am controller_action_layout_generate_blocks_before" - Dies ist eine M1-Frage.
benmarks

23

Auf diese Weise können Sie alle Layout-Handles in Ihrem Controller abrufen:

var_dump($this->getLayout()->getUpdate()->getHandles());

Oder irgendwo (solange das Layout initialisiert wurde) mit diesem Befehl:

var_dump(Mage::app()->getLayout()->getUpdate()->getHandles());

Vielleicht hilft Ihnen das beim Debuggen.

BEARBEITEN

Haben Sie Ihre config.xml so eingestellt, dass sie die Blockklasse angibt?

    <blocks>
        <banners>
            <class>My_Banners_Block</class>
        </banners>
    </blocks>

Bei beiden Tests wurde mein Handle korrekt zur Observer-Methode hinzugefügt, aber dann wird das Layout nicht geladen. Ich werde meine Frage mit etwas Code aktualisieren, vielleicht hilft es.
Jaroslaw

@Yaroslav hat meine Antwort aktualisiert
Rick Kuipers

Ja, ich habe das in der Konfig, werde meine Frage aktualisieren.
Jaroslaw

@Yaroslav Kannst du überprüfen, ob die product.phtml geladen wird, wenn du den Blocktyp auf änderst core/template? Dies dient nur zur Beseitigung von Fehlern in Ihren Moduleinstellungen.
Rick Kuipers

1
@Yaroslav es scheint, dass das Problem ein bisschen zu weit verbreitet und schwierig ist, hier auf stackexchange zu debuggen. Mir ist nicht klar, was das Problem verursachen könnte.
Rick Kuipers

12

Ich benutze PhpStorm mit Magicento und dachte, ich würde @benmarks großartige Antwort auf meine Verwendung anpassen.

Öffnen Sie in PhpStorm app/code/core/Mage/Core/Controller/Varien/Action.phpund fügen Sie einen Haltepunkt in die Methode ein generateLayoutBlocks(). Ich denke, es geht darum, es irgendwo vorher einzufügen $this->getLayout()->generateBlocks();. Ich habe es in die vorige Zeile gestellt.

Nachdem Sie den Haltepunkt eingefügt haben, der durch den roten Punkt links neben der Zeilennummer gekennzeichnet ist, können Sie mit der rechten Maustaste darauf klicken, um das Verhalten anzupassen. Klicken Sie unten auf "Mehr", um alle Optionen zu öffnen. Bildbeschreibung hier eingeben

Sobald Sie dies geöffnet haben, aktivieren Sie das Kontrollkästchen für "Nachricht an Konsole protokollieren" (optional) und "Auswertungsausdruck protokollieren" (wo die Magie passiert). Kopieren Sie dann diese Anpassung von Benmarks Code in das Textfeld. Das einzige, was ich geändert habe, ist, die $requestVariable wie Mage::app()->getRequest()jedes Mal zu buchstabieren und $oin $this(b / c, wir sind hier nicht im Beobachterkontext) zu ändern .

sprintf("\nRequest: %s\nFull Action Name: %s_%s_%s\nHandles:\n\t%s\nUpdate XML:\n%s",Mage::app()->getRequest()->getRouteName(),Mage::app()->getRequest()->getRequestedRouteName(),Mage::app()->getRequest()->getRequestedControllerName(),Mage::app()->getRequest()->getRequestedActionName(),implode("\n\t",$this->getLayout()->getUpdate()->getHandles()),$this->getLayout()->getUpdate()->asString())

So sieht es jetzt aus: Bild zeigt erweiterte Haltepunkteinstellungen

Nachdem Sie das Programm ausgeführt haben (mit xdebug oder zend debugger), halten Sie am Haltepunkt an und sehen dies im Protokoll:

Update XML:
<block name="formkey" type="core/template" template="core/formkey.phtml"/>
<label>All Pages</label>
<block type="page/html" name="root" output="toHtml" template="page/2columns-left.phtml">
   <block type="page/html_head" name="head" as="head">
      <action method="addJs">
         <script>jquery/jquery-migrate-1.2.1.min.js</script>
      </action>
      <action method="addJs">
         <script>jquery/jquery-ui/jquery-ui.min.js</script>
      </action>
      <action method="addJs">
         <script>prototype/prototype.js</script>
      </action>
      <action method="addJs" ifconfig="dev/js/deprecation">
         <script>prototype/deprecation.js</script>
      </action>
      <action method="addJs">
         <script>lib/ccard.js</scrip

Es scheint eine Größenbeschränkung für die Protokolleinträge zu sein , die durch die bestimmt werden könnten idea.cycle.buffer.sizeEigenschaft in der idea.propertiesDatei für PhpStorm, nach diesem . Sie können dies ändern oder einfach mit der rechten Maustaste auf das Codefenster klicken und "Ausdruck auswerten" aus dem Dropdown-Menü auswählen und den auszuführenden Code kopieren und einfügen, um die vollständige Ausgabe zu erhalten.

Im Popup "Ausdruck auswerten" können Sie mit der rechten Maustaste (Windows) auf das Ergebnis klicken und "Wert kopieren" auswählen, um die gesamte Ausgabe abzurufen und zur Analyse an einer anderen Stelle einzufügen.

PhpStorm - Kopieren aus dem Popup "Ausdruck auswerten"


5

Wir verwenden die Commerce Bug- Erweiterung von Alan Storm und finden sie für das Debuggen einer Vielzahl von Dingen in Magento, einschließlich Layoutproblemen, unverzichtbar. In Layouts können Sie sehen, welche Layout-Handles auf jeder Seite aktiv sind und welche Layout-XML-Konfigurationen auf die Seite angewendet werden.

Es ist nicht kostenlos, spart aber viel Zeit beim Debuggen dieser Art von Dingen.

Hinweis: Ich bin in keiner Weise mit Alan Storm oder Commerce Bug verbunden, sondern nur ein zufriedener Kunde.


9
Ich bin mit Alan Storm verbunden (insofern bin ich er) und wollte nur darauf hinweisen, dass Commerce Bug 2 Ihnen auch die Möglichkeit gibt, ein gerichtetes Diagramm Ihrer Layouts zu erstellen. alanstorm.com/find_magento_block_name
Alan Storm

Wir sind auch zufriedene Kunden von Alan Storm Commerce Bug. Aber auf dem System, auf dem ich diese Probleme habe, ist es nicht installiert und wir haben nicht genügend Lizenzen für alle Test- und Vorproduktionssysteme. Und übrigens, @AlanStorm, können wir das Update für Commerce Bug 2 bekommen?
Jaroslaw

1
Wenden Sie sich an den Support und wir werden Sie mit Updates und Upgrades versorgen. Pulsestorm.net/contact-us
Alan Storm

3

Vielen Dank, Ben Marks! Dies ist meine Version des von Ihnen beschriebenen XML-Layout-Loggers.

Es ist eine sehr lange Datei, also habe ich XML daraus gemacht ... :-) Du kannst sie mit einem normalen Editor öffnen ...

    <?php

class Gn_Optimization_Model_Debug_Layout {
  public function logCompiledLayout($o) {
    $req = Mage::app()->getRequest();

    $routeName = $req->getRouteName();
    $fullname = $req->getRequestedRouteName() . '_' . $req->getRequestedControllerName() . '_' . $req->getRequestedActionName();

    $info = sprintf(
      "\nRequest: %s\nFull Action Name: %s\nHandles:\n\t%s\n",
      $routeName, $fullname, implode("\n\t", $o->getLayout()->getUpdate()->getHandles())
    );

    Mage::log($info, Zend_Log::DEBUG, 'debug.'.$routeName.'.layout.log', true);
    file_put_contents(Mage::getBaseDir('log').DS.'debug.'.$routeName.'.layout.xml',
                      '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL
                      .'<layout>'.PHP_EOL.
                      $o->getLayout()->getUpdate()->asString().
                      '</layout>');
  }
}

Und meine config.xml sieht im Knoten so aus:

<events>
  <controller_action_layout_generate_blocks_before>
    <observers>
      <gn_optimization_controller_action_layout_generate_blocks_before>
        <type>singleton</type>
        <class>gn_optimization/debug_layout</class>
        <method>logCompiledLayout</method>
      </gn_optimization_controller_action_layout_generate_blocks_before>
    </observers>
  </controller_action_layout_generate_blocks_before>
</events>

Nun hoffe ich, dass mein Designer all dies erklären kann ... \ o /


0

Sie können dies zu Ihrer Controller-Aktion hinzufügen. Es zeigt die Handles übersichtlicher als var_dump.

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.