Ładowanie pliku XML układu debugowania

36

TL; DR: czy istnieje sposób na debugowanie ładowania układu? Jak wierzę, układ jednego modułu jest w konflikcie z innym.

Powiązane z poprzednim pytaniem, które zadałem: Jak zrobić układ modułu, aby był wyświetlany na wszystkich motywach

Z powodzeniem załadowałem mój moduł do lokalnego środowiska testowego (zwanego też moim komputerem programistycznym), przetestowałem przełączanie między 3 różnymi motywami i jest w porządku. Następnie zaktualizowałem moduł w testowym lub „przedprodukcyjnym” środowisku, które mamy, gdzie jest wiele różnych modułów, niektóre zastrzeżone przez nas. W tym środowisku moduł nie pokazuje, co jest potrzebne na stronie głównej produktu. Po kilku testach w końcu doszedłem do wniosku, że problemem powinien być proces ładowania układu.

Czy jest więc sposób, w jaki mogę debugować ładowanie układu, jak różne moduły zastępują lub dodają własne bloki? Chodzi mi o to, że uważam, że istnieje co najmniej jeden moduł, który powinien kolidować z moim. Ponieważ mamy tak wiele modułów, szukam innego podejścia niż wyłączanie modułów jeden po drugim i sprawdzanie, który jest problematyczny.

Mój plik config.xml to:

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

Plik mojego obserwatora:

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

To jest mój plik układu:

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

Wcześniej miałem nieco inny, w którym zamiast <default></default>miałem <Product_Campaign_Banner></Product_Campaign_Banner>. To też działało.

Mój plik product.phtml:

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

product.phtmlPlik nie jest załadowany, a zatem showCampaignnie jest stracony i nie ma gdzie wszystkie potrzebne HTML jest tworzony.

Jarosław
źródło
2
Najlepiej byłoby mieć lokalną środowisko w możliwie największym stopniu takim samym jak środowisko w fazie przedprodukcyjnej
Fra
Właśnie to robię teraz, ale nie jest to łatwe, mamy ponad 20 modułów innych firm, a nawet niektóre z nich nie działają w środowisku przedprodukcyjnym, a ich programiści sprawdzają kod.
Jarosław
4
Jestem bardzo ciekawy, dlaczego przyczyny tego pytania zostały oznaczone jako zbyt zlokalizowane. Pytanie dotyczy debugowania ogólnego układu, który, jeśli jeszcze tego nie zrobiłeś, jest dość przydatny i ma szerokie zastosowanie.
zyskuje
Też jestem ciekawa. Ale myślę, że w rezultacie może po kilku edycjach innych wydaje się, że po prostu próbuję rozwiązać mój bardzo zlokalizowany problem. I rzeczywiście tak jest, ale jednocześnie wciąż mam nadzieję, że debugując proces generowania układu, będę w stanie znaleźć miejsce, w którym znajduje się mój błąd. Dlatego rozwiązanie będzie przydatne dla innych.
Jarosław

Odpowiedzi:

55

Możesz rejestrować skompilowane dyrektywy XML układu, które są używane do generowania bloków. Utwórz obserwatora controller_action_layout_generate_blocks_before, a następnie w metodzie obserwatora zaloguj aktualizację XML z transportowanego obiektu układu:

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

Dane wyjściowe będą podobne do:

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>
<!-- ... ->
zalety
źródło
Wydaje się pomocny, wypróbuje to jutro o pierwszej godzinie
Jarosław
Twoja odpowiedź była właściwa, właśnie tego szukałem. Utworzony dziennik wyświetla wszystkie uchwyty, żądania itp. Przy ładowaniu strony. Potwierdziłem, że mój uchwyt jest poprawnie załadowany do głównej tablicy uchwytów, ale z jakiegoś powodu odpowiedni blok nie został załadowany / wyświetlony.
Jarosław
1
I to powinno być łatwiejsze do rozwiązania, ponieważ układ został wykluczony :-).
zyskuje
Zakładam, że umieszczasz to w pliku Action.php? Jak to się nazywa magento?
Metropolis
„Utwórz obserwatora na controller_action_layout_generate_blocks_before - To jest pytanie M1.
zaznacza
23

Możesz pobrać wszystkie uchwyty układu w kontrolerze, wykonując następujące czynności:

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

Lub w dowolnym miejscu (o ile układ został zainicjowany) przy użyciu tego:

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

Być może pomoże ci to w debugowaniu.

EDYTOWAĆ

Czy ustawiłeś config.xml, aby określał klasę bloków?

    <blocks>
        <banners>
            <class>My_Banners_Block</class>
        </banners>
    </blocks>
Rick Kuipers
źródło
Oba przetestowane, mój uchwyt jest poprawnie dodany do metody obserwatora, ale wtedy układ nie jest ładowany. Zaktualizuję moje pytanie za pomocą kodu, może to pomoże.
Jarosław
@Yaroslav zaktualizował moją odpowiedź
Rick Kuipers
Tak, mam to w konfiguracji, zaktualizuję moje pytanie.
Jarosław
@Yaroslav Czy możesz sprawdzić, czy product.phtml jest ładowany przy zmianie typu bloku na core/template? Ma to na celu anulowanie błędów w ustawieniach modułu.
Rick Kuipers
1
@ Yaroslav wydaje się, że problem jest zbyt szeroko rozpowszechniony i trudny do debugowania tutaj na stosie wymiany. Nie jest dla mnie jasne, co może być przyczyną problemu.
Rick Kuipers
12

Korzystam z PhpStorm z Magicento, więc pomyślałem, że dostosuję @benmarks świetną odpowiedź na moje użycie.

W PhpStorm otwórz app/code/core/Mage/Core/Controller/Varien/Action.phpi umieść punkt przerwania w metodzie generateLayoutBlocks(). Myślę, że chodzi o to, aby wstawić go gdziekolwiek wcześniej $this->getLayout()->generateBlocks();. Umieściłem go w poprzedniej linii.

Po wstawieniu punktu przerwania, oznaczonego czerwoną kropką po lewej stronie numeru linii, możesz kliknąć go prawym przyciskiem myszy, aby dostosować zachowanie. Kliknij „Więcej” u dołu, aby otworzyć wszystkie opcje. wprowadź opis zdjęcia tutaj

Kiedy to otworzysz, zaznacz pole „Loguj wiadomość do konsoli” (opcjonalnie) i „Loguj wyrażone wyrażenie” (tam, gdzie dzieje się magia). Następnie skopiuj wklej tę adaptację kodu Benmarka do pola tekstowego. Jedyne, co zmieniłem, to wypisywanie $requestzmiennej jak za Mage::app()->getRequest()każdym razem i zmieniłem $ozmienną na $this(b / c nie jesteśmy tutaj w kontekście obserwatora).

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

Teraz wygląda to tak: Obraz pokazuje zaawansowane ustawienia punktu przerwania

Po uruchomieniu programu (przy użyciu debugera xdebug lub Zend) zatrzymasz się w punkcie przerwania i zobaczysz to w dzienniku:

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

Wydaje się, że istnieje limit rozmiaru wpisów dziennika, który może być określony przez idea.cycle.buffer.sizewłaściwość idea.propertiespliku PhpStorm, zgodnie z tym . Możesz to zmienić lub po prostu kliknij prawym przyciskiem myszy okno kodu i wybierz z menu rozwijanego opcję „Oceń wyrażenie”, a następnie skopiuj i wklej kod, aby tam wykonać, a otrzymasz pełne wyjście.

W wyskakującym okienku „Oceń wyrażenie” możesz kliknąć wynik prawym przyciskiem myszy (Windows) i wybrać „Kopiuj wartość”, aby uzyskać cały wynik i wkleić go w innym miejscu do analizy.

PhpStorm - skopiuj z wyskakującego okienka oceny wyrażenia

Buttle Butkus
źródło
5

Używamy rozszerzenia Commerce Bug Alana Storma i uważamy , że jest ono niezbędne do debugowania różnych rzeczy w Magento, w tym problemów z układem. W przypadku układów możesz zobaczyć, które uchwyty układu są aktywne na każdej stronie i jakie konfiguracje XML układu są stosowane na stronie.

To nie jest darmowe, ale zaoszczędzi dużo czasu na debugowanie tego rodzaju rzeczy.

Uwaga: w żaden sposób nie jestem związany z Alan Storm ani Commerce Bug, tylko zadowolony klient.

Luke Mills
źródło
9
Jestem związany z Alanem Stormem (w tym sensie, że jestem nim) i chciałem tylko podkreślić, że Commerce Bug 2 daje również możliwość stworzenia ukierunkowanego schematu graficznego twoich układów. alanstorm.com/find_magento_block_name
Alan Storm
Jesteśmy również zadowolonymi klientami błędu handlu Alan Storm. Ale w systemie, w którym mam te problemy, nie jest on zainstalowany i nie mamy wystarczającej liczby licencji na wszystkie systemy testowe i przedprodukcyjne. A tak przy okazji, @AlanStorm, czy możemy pobrać aktualizację do Commerce Bug 2?
Jarosław
1
@Yaroslav Skontaktuj się z pomocą techniczną, a my zajmiemy się Tobą dzięki aktualizacjom i aktualizacjom pulsestorm.net/contact-us
Alan Storm
3

Thanx Ben Marks! To jest moja wersja rejestratora układu XML, który opisałeś.

Jest to bardzo długi plik, więc utworzyłem z niego XML ... :-) Możesz otworzyć za pomocą normalnego edytora ....

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

A mój config.xml wygląda tak w węźle:

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

Mam nadzieję, że mój projektant to wszystko wyjaśni ... \ o /

Roger Keulen
źródło
0

Możesz dodać to do akcji kontrolera. Pokaże uchwyty w bardziej schludny sposób niż var_dump.

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
TheKitMurkit
źródło