Caricamento XML del layout di debug


36

TL; DR: esiste un modo per eseguire il debug del caricamento del layout? Poiché credo che il layout di un modulo sia in conflitto con un altro.

Relativo a una domanda precedente che ho fatto: Come creare un layout del modulo da mostrare su tutti i temi

Ho caricato con successo il mio modulo sul mio ambiente di test locale (ovvero il mio PC di sviluppo), ho testato il passaggio tra 3 temi diversi ed è ok. Quindi ho aggiornato il modulo sull'ambiente di test o "pre-produzione" che abbiamo, dove ci sono molti moduli diversi, alcuni proprietari altri realizzati da noi. In questo ambiente, il modulo non mostra ciò che è necessario sulla prima pagina del prodotto. Dopo alcuni test, sono finalmente giunto alla conclusione che il problema dovrebbe riguardare il processo di caricamento del layout.

Quindi, c'è un modo in cui posso eseguire il debug del caricamento del layout, in che modo i diversi moduli sostituiscono o aggiungono i propri blocchi? Il mio punto è che credo che ci sia almeno un modulo che dovrebbe essere in conflitto con il mio. E dato che abbiamo così tanti moduli, sto cercando un approccio diverso dalla disabilitazione dei moduli uno per uno e vedo qual è quello problematico.

Il mio file config.xml è:

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

Il mio file Observer:

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

Questo è il mio file di layout:

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

Precedentemente ne avevo una leggermente diversa, invece di <default></default>me <Product_Campaign_Banner></Product_Campaign_Banner>. Funzionava anche.

Il mio file product.phtml:

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

Il product.phtmlfile non viene caricato e quindi showCampaignnon viene eseguito ed è lì che viene creato tutto l'HTML necessario.


2
La cosa migliore sarebbe avere un ambiente locale il più possibile uguale a un ambiente di pre-produzione
Fra

Questo è quello che sto facendo in questo momento, ma non è facile, abbiamo oltre 20 moduli di terze parti e anche alcuni di loro non funzionano sull'ambiente di pre-produzione e i loro sviluppatori stanno controllando il codice.
Yaroslav,

4
Sono molto curioso di sapere che i motivi alla base di questa domanda sono stati contrassegnati per la chiusura come troppo localizzati. La domanda parla del debug generale del layout, che se non lo hai fatto, è abbastanza utile e ampiamente applicativo.
benmarks

Sono anche curioso. Ma penso che potrebbe essere il risultato che dopo varie modifiche ad altri sembra che sto solo cercando di risolvere il mio problema molto localizzato. E in effetti lo sono, ma allo stesso tempo spero ancora che eseguendo il debug del processo di generazione del layout sarò in grado di trovare dove si trova il mio errore. Pertanto la soluzione sarà utile per gli altri.
Yaroslav,

Risposte:


55

È possibile registrare le direttive XML di layout compilate utilizzate per generare blocchi. Crea un osservatore controller_action_layout_generate_blocks_beforee, nel metodo osservatore, registra l'XML di aggiornamento dall'oggetto layout trasportato:

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);
}

L'output sarà simile a:

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

Sembra utile, lo proverò domani alla prima ora
Yaroslav il

La tua risposta è stata quella giusta, proprio quello che stavo cercando. Il registro creato genera tutti gli handle, le richieste, ecc. Al caricamento della pagina. Ho confermato che il mio handle è stato caricato correttamente nella matrice degli handle principali ma per qualche motivo il blocco corrispondente non è stato caricato / visualizzato.
Yaroslav,

1
E questo dovrebbe essere più facile da risolvere ora che il layout è stato escluso :-).
benmarks

Suppongo che lo stai inserendo nel file Action.php? Inoltre, come viene chiamato dal magento?
Metropolis,

"Crea un osservatore su controller_action_layout_generate_blocks_before" - Questa è una domanda M1.
benmarks

23

È possibile recuperare tutti gli handle di layout nel controller in questo modo:

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

O ovunque (purché il layout sia stato inizializzato) usando questo:

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

Forse questo ti aiuterà a eseguire il debug.

MODIFICARE

Hai impostato config.xml per specificare la classe di blocco?

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

Entrambi testati, il mio handle è stato correttamente aggiunto sul metodo observer ma il layout non viene caricato. Aggiornerò la mia domanda con un po 'di codice, forse mi aiuterà.
Yaroslav,

@Yaroslav ha aggiornato la mia risposta
Rick Kuipers il

Sì, ce l'ho sulla configurazione, aggiornerò la mia domanda.
Yaroslav,

@Yaroslav Puoi verificare se il product.phtml viene caricato quando si cambia il tipo di blocco in core/template? Questo è solo per annullare gli errori nelle impostazioni del modulo.
Rick Kuipers,

1
@Yaroslav sembra che il problema sia un po 'troppo diffuso e difficile da debug qui su stackexchange. Non è molto chiaro per me cosa potrebbe causare il problema.
Rick Kuipers,

12

Sto usando PhpStorm con Magicento e quindi ho pensato di adattare la risposta di @benmarks al mio utilizzo.

In PhpStorm, apri app/code/core/Mage/Core/Controller/Varien/Action.phpe inserisci un punto di interruzione nel metodo generateLayoutBlocks(). Penso che il punto sia quello di inserirlo ovunque prima $this->getLayout()->generateBlocks();. L'ho messo sulla riga precedente.

Dopo aver inserito il punto di interruzione, indicato dal punto rosso a sinistra dal numero di riga, è possibile fare clic con il pulsante destro del mouse per personalizzare il comportamento. Fai clic su "Altro" in basso per aprire tutte le opzioni. inserisci qui la descrizione dell'immagine

Una volta aperto, spunta la casella "Registra messaggio su console" (opzionale) e "Registra espressione valutata" (dove accade la magia). Quindi copia incolla questo adattamento del codice benmark nella casella di testo. L'unica cosa che ho cambiato è precisare la $requestvariabile come Mage::app()->getRequest()ogni volta, e ha cambiato la $ovariabile in $this(b / c non siamo nel contesto dell'osservatore qui).

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

Quindi ora sembra così: L'immagine mostra le impostazioni avanzate del punto di interruzione

Dopo aver eseguito il programma (usando xdebug o zend debugger) ti fermerai al punto di interruzione e vedrai questo nel registro:

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

Sembra che ci sia un limite di dimensione per le voci del registro che potrebbe essere determinato dalla idea.cycle.buffer.sizeproprietà nel idea.propertiesfile per PhpStorm, secondo questo . È possibile modificarlo o fare semplicemente clic con il pulsante destro del mouse sulla finestra del codice e selezionare "Valuta espressione" dal menu a discesa, quindi copiare e incollare il codice per eseguirlo e ottenere l'output completo.

Nel pop-up "Valuta espressione", puoi fare clic con il pulsante destro del mouse (Windows) sul risultato e selezionare "Copia valore" per ottenere l'intero output e incollarlo altrove per l'analisi.

PhpStorm: copia dal popup Valuta espressione


5

Usiamo l' estensione Commerce Bug di Alan Storm e lo troviamo indispensabile per il debug di una varietà di cose in Magento, inclusi i problemi di layout. Per i layout puoi vedere quali handle di layout sono attivi su ciascuna pagina e quali configurazioni xml di layout vengono applicate alla pagina.

Non è gratuito, ma farà risparmiare molto tempo durante il debug di questo tipo di cose.

Nota: non sono affiliato con Alan Storm o Commerce Bug in alcun modo, solo un cliente felice.


9
Sono affiliato ad Alan Storm (in quanto io sono lui) e volevo solo sottolineare che Commerce Bug 2 ti dà anche la possibilità di produrre un diagramma grafico diretto dei tuoi layout. alanstorm.com/find_magento_block_name
Alan Storm

Siamo anche felici clienti del bug commerciale di Alan Storm. Ma sul sistema in cui sto riscontrando questi problemi non è installato e non abbiamo abbastanza licenze per tutti i sistemi di test e pre-produzione. A proposito, @AlanStorm, eh, possiamo ottenere l'aggiornamento per Commerce Bug 2?
Yaroslav

1
@Yaroslav Contatta l'assistenza e ti faremo risolvere con gli aggiornamenti e gli aggiornamenti pulsestorm.net/contact-us
Alan Storm

3

Grazie Ben Marks! Questa è la mia versione del logger di layout XML che hai descritto.

È un file molto lungo, quindi ne ho ricavato XML ... :-) Puoi aprirlo con un normale editor ....

    <?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>');
  }
}

E il mio config.xml si presenta così nel nodo:

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

Ora spero che il mio designer possa spiegare tutto questo ... \ o /


0

Puoi aggiungerlo all'azione del tuo controller. Mostrerà le maniglie in modo più ordinato rispetto a var_dump.

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
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.