Tata letak debugging memuat XML

36

TL; DR: apakah ada cara saya bisa men-debug memuat tata letak? Karena saya percaya tata letak satu modul bertentangan dengan yang lain.

Terkait dengan pertanyaan sebelumnya yang saya buat: Cara membuat tata letak modul untuk ditampilkan pada semua tema

Saya telah berhasil memuat modul saya pada lingkungan pengujian lokal saya (alias PC pengembangan saya), diuji beralih antara 3 tema yang berbeda dan itu ok. Kemudian saya memperbarui modul pada lingkungan pengujian atau "pra-produksi" yang kami miliki, di mana ada banyak modul yang berbeda, beberapa kepemilikan lain dibuat oleh kami. Pada lingkungan ini, modul tidak menunjukkan apa yang dibutuhkan di halaman depan produk. Setelah beberapa pengujian, saya akhirnya sampai pada kesimpulan bahwa masalahnya harus pada proses load layout.

Jadi, adakah cara saya bisa men-debug memuat tata letak, bagaimana modul yang berbeda mengganti atau menambahkan blok mereka sendiri? Maksud saya adalah saya percaya setidaknya ada satu modul yang harus bertentangan dengan modul saya. Dan karena kami memiliki begitu banyak modul, saya mencari pendekatan yang berbeda untuk menonaktifkan modul satu per satu dan melihat mana yang bermasalah.

File config.xml saya adalah:

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

File Observer saya:

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

Ini adalah file layout saya:

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

Sebelumnya punya yang sedikit berbeda di mana bukannya <default></default>aku <Product_Campaign_Banner></Product_Campaign_Banner>. Itu juga berhasil.

File product.phtml saya:

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

The product.phtmlfile tidak dimuat dan oleh karena itu showCampaigntidak dijalankan dan ada di mana semua HTML yang dibutuhkan dibuat.

Yaroslav
sumber
2
Yang terbaik adalah memiliki env lokal sebanyak mungkin sama dengan Pra-Produksi env
Fra
Itulah yang saya lakukan saat ini, tetapi tidak mudah, kami memiliki lebih dari 20 modul pihak ketiga dan bahkan beberapa dari mereka tidak bekerja pada lingkungan pra-produksi dan pengembang mereka sedang memeriksa kode.
Yaroslav
4
Saya sangat ingin tahu alasan di balik pertanyaan ini ditandai untuk ditutup karena terlalu lokal. Pertanyaannya adalah debugging tata letak umum, yang jika belum Anda lakukan, cukup berguna dan luas-aplikatif.
patokan
Saya juga penasaran. Tapi saya pikir itu bisa terjadi karena setelah beberapa pengeditan ke orang lain sepertinya saya hanya mencoba untuk menyelesaikan masalah saya yang sangat terlokalisasi. Dan memang benar, tetapi pada saat yang sama saya masih berharap bahwa dengan men-debug proses pembuatan tata letak saya akan dapat menemukan di mana kesalahan saya berada. Karena itu solusinya akan bermanfaat bagi orang lain.
Yaroslav

Jawaban:

55

Anda bisa mencatat tata letak kompilasi XML arahan yang digunakan untuk menghasilkan blok. Buat pengamat aktif controller_action_layout_generate_blocks_before, dan dalam metode pengamat catat pembaruan XML dari objek tata letak yang diangkut:

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

Output akan mirip dengan:

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>
<!-- ... ->
tanda batas
sumber
Tampaknya membantu, akan mencobanya besok pada jam pertama
Yaroslav
Jawaban Anda adalah yang benar, hanya apa yang saya cari. Log yang dibuat menampilkan semua pegangan, permintaan, dll pada pemuatan halaman. Saya telah mengkonfirmasi bahwa pegangan saya dimuat dengan benar ke array pegangan utama tetapi untuk beberapa alasan blok yang sesuai tidak dimuat / ditampilkan.
Yaroslav
1
Dan itu seharusnya lebih mudah dipecahkan sekarang karena tata letak telah dikesampingkan :-).
patokan
Saya berasumsi bahwa Anda memasukkan ini ke dalam file Action.php? Juga, bagaimana ini disebut oleh Magento?
Metropolis
"Buat pengamat di controller_action_layout_generate_blocks_before" - Ini adalah pertanyaan M1.
patok
23

Anda dapat mengambil semua pegangan tata letak di controller Anda dengan melakukan ini:

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

Atau di mana saja (selama tata letak telah diinisialisasi) menggunakan ini:

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

Mungkin itu akan membantu Anda melakukan debug.

EDIT

Sudahkah Anda mengatur config.xml Anda untuk menentukan kelas blok?

    <blocks>
        <banners>
            <class>My_Banners_Block</class>
        </banners>
    </blocks>
Rick Kuipers
sumber
Keduanya diuji, pegangan saya ditambahkan dengan benar pada metode pengamat tetapi tata letak tidak dimuat. Saya akan memperbarui pertanyaan saya dengan beberapa kode, mungkin itu akan membantu.
Yaroslav
@Yaroslav memperbarui jawaban saya
Rick Kuipers
Ya, saya memilikinya pada konfigurasi, akan memperbarui pertanyaan saya.
Yaroslav
@Yaroslav Bisakah Anda memeriksa apakah product.phtml dimuat saat mengubah tipe blok core/template? Ini hanya untuk membatalkan kesalahan dalam pengaturan modul Anda.
Rick Kuipers
1
@Yaroslav sepertinya masalahnya agak terlalu luas menyebar dan sulit untuk di-debug di stackexchange. Bagi saya tidak terlalu jelas apa yang menyebabkan masalah ini.
Rick Kuipers
12

Saya menggunakan PhpStorm dengan Magicento dan jadi saya pikir saya akan menyesuaikan @benmark jawaban yang bagus untuk penggunaan saya.

Di PhpStorm, buka app/code/core/Mage/Core/Controller/Varien/Action.phpdan masukkan break point dalam metode generateLayoutBlocks(). Saya pikir intinya adalah memasukkannya ke mana saja sebelumnya $this->getLayout()->generateBlocks();. Saya taruh di baris sebelumnya.

Setelah Anda memasukkan breakpoint, ditunjukkan oleh titik merah di sebelah kiri dengan nomor baris, Anda dapat mengklik kanan untuk menyesuaikan perilaku. Klik "Lainnya" di bagian bawah untuk membuka semua opsi. masukkan deskripsi gambar di sini

Setelah Anda membukanya, Anda mencentang kotak "Log message to console" (opsional) dan "Log dievaluasi ekspresi" (di mana keajaiban terjadi). Kemudian salin tempel adaptasi kode benmark ini ke kotak teks. Satu-satunya hal yang saya ubah adalah mengeja $requestvariabel seperti Mage::app()->getRequest()setiap waktu, dan mengubah $ovariabel menjadi $this(b / c kita tidak dalam konteks pengamat di sini).

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

Jadi sekarang terlihat seperti ini: Gambar menunjukkan pengaturan breakpoint canggih

Setelah Anda menjalankan program (menggunakan xdebug atau zend debugger) Anda akan berhenti di breakpoint dan melihatnya di log:

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

Tampaknya ada batas ukuran untuk entri log yang mungkin ditentukan oleh idea.cycle.buffer.sizeproperti dalam idea.propertiesfile untuk PhpStorm, menurut ini . Anda dapat mengubahnya, atau cukup klik kanan pada jendela kode dan pilih "Evaluate Expression" dari menu dropdown, dan salin dan tempel kode untuk mengeksekusi di sana dan Anda akan mendapatkan hasil lengkap.

Dalam pop-up "Evaluasi Ekspresi", Anda dapat mengklik kanan (Windows) pada hasilnya dan memilih "Salin Nilai" untuk mendapatkan seluruh output dan menempelkannya di tempat lain untuk analisis.

PhpStorm - salin dari popup Evaluasi Ekspresi

Buttle Butkus
sumber
5

Kami menggunakan ekstensi Commerce Storm dari Alan Storm , dan merasa sangat diperlukan untuk men-debug berbagai hal di Magento, termasuk masalah tata letak. Untuk tata letak Anda dapat melihat pegangan tata letak mana yang aktif pada setiap halaman, dan konfigurasi tata letak xml mana yang diterapkan pada halaman tersebut.

Ini tidak gratis, tetapi akan menghemat banyak waktu men-debug hal-hal semacam ini.

Catatan: Saya tidak berafiliasi dengan Alan Storm atau Commerce Bug dengan cara apa pun, hanya pelanggan yang bahagia.

Luke Mills
sumber
9
Saya berafiliasi dengan Alan Storm (dalam hal ini saya adalah dia), dan hanya ingin menunjukkan bahwa Commerce Bug 2 juga memberi Anda kemampuan untuk menghasilkan diagram grafik yang diarahkan pada tata letak Anda. alanstorm.com/find_magento_block_name
Alan Storm
Kami juga senang pelanggan bug perdagangan Alan Storm. Tetapi pada sistem di mana saya mengalami masalah ini, itu tidak diinstal dan kami tidak memiliki cukup lisensi untuk semua sistem pengujian dan pra-produksi. Omong-omong, @AlanStorm, hoy kita bisa mendapatkan pembaruan untuk Commerce Bug 2?
Yaroslav
1
@Yaroslav Hubungi dukungan dan kami akan membuat Anda beres dengan pembaruan dan peningkatan pulsestorm.net/contact-us
Alan Storm
3

Thanx Ben Marks! Ini adalah versi saya dari layout logger xml yang Anda sebutkan.

Ini file yang sangat panjang jadi saya membuat XML darinya ... :-) Anda dapat membuka dengan editor biasa ....

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

Dan config.xml saya terlihat seperti ini di simpul:

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

Sekarang, saya harap desainer saya dapat menjelaskan semua ini ... \ o /

Roger Keulen
sumber
0

Anda dapat menambahkan ini ke tindakan pengontrol Anda. Ini akan menampilkan pegangan dengan cara yang lebih rapi daripada var_dump.

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
TheKitMurkit
sumber