การดีบักการโหลด XML โครงร่าง


36

TL: DR:มีวิธีที่ฉันสามารถดีบักการโหลดเค้าโครงหรือไม่ เพราะฉันเชื่อว่าเลย์เอาต์ของโมดูลหนึ่งขัดแย้งกับโมดูลอื่น

ที่เกี่ยวข้องกับคำถามก่อนหน้านี้ที่ฉันทำ: วิธีการทำให้รูปแบบโมดูลที่จะแสดงในทุกรูปแบบ

ฉันโหลดโมดูลของฉันสำเร็จแล้วในสภาพแวดล้อมการทดสอบในพื้นที่ (หรือที่เรียกว่า PC สำหรับการพัฒนาของฉัน) ทดสอบการสลับระหว่าง 3 ธีมที่แตกต่างกันและมันก็โอเค จากนั้นฉันอัปเดตโมดูลในการทดสอบหรือสภาพแวดล้อม "ก่อนการผลิต" ที่เรามีซึ่งมีโมดูลที่แตกต่างกันจำนวนมากบางส่วนเป็นกรรมสิทธิ์อื่น ๆ ที่ทำโดยเรา ในสภาพแวดล้อมนี้โมดูลจะไม่แสดงสิ่งที่จำเป็นในหน้าแรกของผลิตภัณฑ์ หลังจากการทดสอบบางอย่างในที่สุดฉันก็มาถึงข้อสรุปว่าปัญหาควรจะอยู่ในกระบวนการโหลดรูปแบบ

ดังนั้นมีวิธีที่ฉันสามารถดีบักการโหลดโครงร่างโมดูลต่าง ๆ แทนที่หรือเพิ่มบล็อกของตัวเองได้อย่างไร ประเด็นของฉันคือฉันเชื่อว่ามีอย่างน้อยหนึ่งโมดูลที่ควรขัดแย้งกับของฉัน และในขณะที่เรามีโมดูลจำนวนมากฉันกำลังมองหาวิธีการที่แตกต่างกันในการปิดใช้งานโมดูลทีละคนและดูว่าเป็นปัญหาที่มีปัญหา

ไฟล์ 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>

ไฟล์ 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;
      ....
      ....
}

นี่คือไฟล์เลย์เอาต์ของฉัน:

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

ก่อนหน้านี้มีความแตกต่างกันเล็กน้อยหนึ่งที่แทนของฉันได้<default></default> <Product_Campaign_Banner></Product_Campaign_Banner>มันยังใช้งานได้

ไฟล์ product.phtml ของฉัน:

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

product.phtmlไฟล์ไม่โหลดและดังนั้นจึงshowCampaignไม่ได้ดำเนินการและมีที่ทุก HTML จำเป็นจะถูกสร้างขึ้น


2
สิ่งที่ดีที่สุดคือการมี env ในท้องถิ่นให้มากที่สุดเท่าที่จะเป็นไปได้เช่นเดียวกับ Pre-Production env
Fra

นั่นคือสิ่งที่ฉันกำลังทำอยู่ตอนนี้ แต่ไม่ใช่เรื่องง่ายเรามีโมดูลของบุคคลที่สามมากกว่า 20 รายการและแม้แต่บางโมดูลก็ไม่สามารถทำงานได้ในสภาพแวดล้อมก่อนการผลิตและนักพัฒนาของพวกเขากำลังตรวจสอบรหัส
Yaroslav

4
ฉันมากอยากรู้รู้เหตุผลที่อยู่เบื้องหลังคำถามนี้ถูกตั้งค่าสถานะสำหรับการปิดเป็นภาษาท้องถิ่นมากเกินไป คำถามพูดถึงการดีบักเลย์เอาต์ทั่วไปซึ่งหากคุณยังไม่ได้ทำค่อนข้างมีประโยชน์และปรับใช้อย่างกว้างขวาง
benmarks

ฉันก็สงสัยเช่นกัน แต่ฉันคิดว่ามันน่าจะเป็นผลที่หลังจากการแก้ไขหลายต่อหลายครั้งดูเหมือนว่าฉันแค่พยายามที่จะแก้ปัญหาที่แปลแล้วของตัวเอง และแน่นอนฉันเป็น แต่ในเวลาเดียวกันฉันยังคงหวังว่าโดยการดีบักกระบวนการสร้างเค้าโครงฉันจะสามารถค้นหาที่ข้อผิดพลาดของฉันอยู่ ดังนั้นการแก้ปัญหาจะเป็นประโยชน์สำหรับผู้อื่น
Yaroslav

คำตอบ:


55

คุณสามารถบันทึกคำสั่ง XML ของโครงร่างที่คอมไพล์ซึ่งใช้เพื่อสร้างบล็อก สร้างผู้สังเกตการณ์controller_action_layout_generate_blocks_beforeและในเมธอดผู้สังเกตการณ์จะอัพเดต XML จากวัตถุโครงร่างที่ถูกขนส่ง:

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

ผลลัพธ์จะคล้ายกับ:

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

ดูเหมือนจะเป็นประโยชน์และจะลองใช้ในวันพรุ่งนี้ในชั่วโมงแรก
Yaroslav

คำตอบของคุณคือสิ่งที่ถูกต้องสิ่งที่ฉันกำลังมองหา บันทึกที่สร้างขึ้นจะส่งออกการจัดการการร้องขอและอื่น ๆ ทั้งหมดในการโหลดหน้า ฉันยืนยันว่าหมายเลขอ้างอิงของฉันโหลดอย่างถูกต้องลงในอาร์เรย์หมายเลขอ้างอิงหลัก แต่ด้วยเหตุผลบางอย่างบล็อกที่เกี่ยวข้องไม่ได้ถูกโหลด / แสดง
ยาโรสลาฟ

1
และที่ควรจะง่ายต่อการแก้ไขปัญหาในขณะนี้ว่ารูปแบบที่ได้รับการปกครองออก :-)
benmarks

ฉันสมมติว่าคุณกำลังวางสิ่งนี้ไว้ในไฟล์ Action.php? วีโอไอพีนี้เรียกได้ว่าเป็นยังไงบ้าง?
Metropolis

"สร้างผู้สังเกตการณ์บนcontroller_action_layout_generate_blocks_before" - นี่คือคำถาม M1
benmarks

23

คุณสามารถดึงที่จับเค้าโครงทั้งหมดในคอนโทรลเลอร์ของคุณได้โดยทำดังนี้

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

หรือที่ใดก็ได้ (ตราบใดที่เค้าโครงเริ่มต้น) โดยใช้สิ่งนี้:

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

บางทีนั่นอาจช่วยให้คุณแก้ปัญหาได้

แก้ไข

คุณได้ตั้งค่า config.xml เพื่อระบุคลาสบล็อกหรือไม่

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

ทั้งทดสอบที่จับของฉันถูกเพิ่มอย่างถูกต้องในวิธีการสังเกตการณ์ แต่จากนั้นรูปแบบไม่ได้โหลด ฉันจะอัปเดตคำถามของฉันด้วยรหัสบางอย่างอาจช่วยได้
Yaroslav

@Yaroslav อัปเดตคำตอบของฉันแล้ว
Rick Kuipers

ใช่ฉันมีสิ่งนั้นอยู่ในการกำหนดค่าจะอัปเดตคำถามของฉัน
Yaroslav

@Yaroslav คุณสามารถตรวจสอบว่า product.phtml ได้รับการโหลดเมื่อเปลี่ยนประเภทบล็อกเป็นcore/templateหรือไม่ นี่เป็นเพียงการยกเลิกข้อผิดพลาดในการตั้งค่าโมดูลของคุณ
ริก Kuipers

1
@Yaroslav ดูเหมือนว่าปัญหาจะแพร่กระจายอย่างกว้างขวางเกินไปและยากที่จะแก้ปัญหาที่นี่ใน stackexchange ไม่ชัดเจนสำหรับฉันว่าอะไรที่ทำให้เกิดปัญหา
Rick Kuipers

12

ฉันใช้ PhpStorm กับ Magicento ดังนั้นฉันคิดว่าฉันจะปรับ @benmarks ให้เป็นคำตอบที่ดีสำหรับการใช้งานของฉัน

ใน PhpStorm เปิดและวางจุดพักในวิธีการapp/code/core/Mage/Core/Controller/Varien/Action.php ผมคิดว่าประเด็นคือการใส่ที่ไหนมาก่อนgenerateLayoutBlocks() $this->getLayout()->generateBlocks();ฉันใส่มันในบรรทัดก่อนหน้า

หลังจากที่คุณใส่เบรกพอยต์ซึ่งระบุด้วยจุดสีแดงทางซ้ายของหมายเลขบรรทัดคุณสามารถคลิกขวาเพื่อกำหนดลักษณะการทำงาน คลิก "เพิ่มเติม" ที่ด้านล่างเพื่อเปิดตัวเลือกทั้งหมด ป้อนคำอธิบายรูปภาพที่นี่

เมื่อคุณเปิดขึ้นคุณจะทำเครื่องหมายในช่องสำหรับ "บันทึกข้อความเพื่อคอนโซล" (ตัวเลือก) และ "นิพจน์ที่ประเมินการบันทึก" (ที่ซึ่งเวทมนตร์เกิดขึ้น) จากนั้นคัดลอกวางการดัดแปลงโค้ด benmark นี้ลงในกล่องข้อความ สิ่งเดียวที่ฉันเปลี่ยนคือการสะกด$requestตัวแปรMage::app()->getRequest()ทุกครั้งและเปลี่ยน$oตัวแปรเป็น$this(b / c เราไม่ได้อยู่ในบริบทผู้สังเกตการณ์ที่นี่)

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

ดังนั้นตอนนี้ดูเหมือนว่านี้: ภาพแสดงการตั้งค่าเบรกพอยต์ขั้นสูง

หลังจากที่คุณเรียกใช้โปรแกรม (ใช้ xdebug หรือ zend debugger) คุณจะหยุดที่เบรกพอยต์และดูสิ่งนี้ในบันทึก:

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

ดูเหมือนจะมีขนาด จำกัด สำหรับรายการบันทึกที่อาจจะมีการกำหนดโดยidea.cycle.buffer.sizeทรัพย์สินในidea.propertiesไฟล์ PhpStorm ตามนี้ คุณสามารถเปลี่ยนได้หรือเพียงคลิกขวาที่หน้าต่างรหัสและเลือก "ประเมินการแสดงออก" จากเมนูแบบเลื่อนลงและคัดลอกและวางรหัสเพื่อดำเนินการที่นั่นและคุณจะได้ผลลัพธ์เต็ม

ในป๊อปอัป "ประเมินนิพจน์" คุณสามารถคลิกขวา (Windows) ที่ผลลัพธ์และเลือก "คัดลอกค่า" เพื่อรับผลลัพธ์ทั้งหมดและวางที่อื่นเพื่อวิเคราะห์

PhpStorm - คัดลอกจากป๊อปอัปการประเมินผลนิพจน์


5

เราใช้ส่วนขยายCommerce Bugของอลันสตอร์มและพบว่ามันขาดไม่ได้สำหรับการแก้ไขข้อบกพร่องหลายอย่างใน Magento รวมถึงปัญหาการจัดวาง สำหรับเลย์เอาต์คุณสามารถดูว่าตัวจัดการโครงร่างใดที่แอ็คทีฟในแต่ละหน้าและโครงร่าง xml โครงร่างใดที่ถูกนำไปใช้กับเพจ

มันไม่ฟรี แต่จะประหยัดเวลาได้มากในการดีบั๊กสิ่งเหล่านี้

หมายเหตุ: ฉันไม่ได้มีส่วนเกี่ยวข้องกับ Alan Storm หรือ Commerce Bug แต่อย่างใดเพียงแค่ลูกค้ามีความสุข


9
ฉันเป็นพันธมิตรกับอลันสตอร์ม (ในที่ฉันเป็นเขา) และเพียงแค่ต้องการชี้ให้เห็นว่า Commerce Bug 2 ยังให้ความสามารถในการสร้างไดอะแกรมกราฟกำกับของเลย์เอาต์ของคุณ alanstorm.com/find_magento_block_name
Alan Storm

นอกจากนี้เรายังเป็นลูกค้าที่มีความสุขกับข้อบกพร่องทางการค้าของอลันสตอร์ม แต่ในระบบที่ฉันมีปัญหาเหล่านี้มันไม่ได้ติดตั้งและเราไม่มีใบอนุญาตเพียงพอสำหรับระบบทดสอบและก่อนการผลิตทั้งหมด @AlanStorm เฮ้ยเราจะได้รับการอัปเดตสำหรับ Commerce Bug 2 ไหม
ยาโรสลาฟ

1
@Yaroslav ติดต่อฝ่ายสนับสนุนแล้วเราจะช่วยคุณอัปเดตและอัปเดตpulsestorm.net/contact-us
Alan Storm

3

เครื่องหมาย Thanx Ben! นี่คือตัวบันทึกโครงร่าง xml รุ่นที่ฉันเลิกใช้

มันเป็นไฟล์ที่ยาวมากดังนั้นฉันจึงสร้าง XML จากมัน ... :-) คุณสามารถเปิดด้วยเครื่องมือแก้ไขปกติ ....

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

และ config.xml ของฉันมีลักษณะเช่นนี้ในโหนด:

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

ตอนนี้ฉันหวังว่านักออกแบบของฉันจะสามารถอธิบายทั้งหมดได้ ... \ o /


0

คุณสามารถเพิ่มสิ่งนี้ไปยังการกระทำของตัวควบคุมของคุณ มันจะแสดงจุดจับอย่างประณีตกว่า var_dump

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.