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


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

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>

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


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.


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 /


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