레이아웃 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>

내 관찰자 파일 :

<?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
가장 좋은 것은 생산 전 환경과 가능한 한 동일한 지역 환경을 유지하는 것입니다.
Fra

그것이 지금 당장하고 있지만 쉽지는 않습니다. 20 개 이상의 타사 모듈이 있으며 일부 모듈은 사전 프로덕션 환경에서 작동하지 않으며 개발자가 코드를 확인하고 있습니다.
야로슬라프

4
나는 아주 너무 국부적으로 폐쇄을 받았습니다되는이 질문 뒤에 이유를 알고 호기심. 질문은 일반 레이아웃 디버깅에 관한 것으로, 아직 완료하지 않은 경우 매우 유용하고 광범위하게 적용됩니다.
benmarks

나도 궁금하다. 그러나 다른 사람들을 여러 번 편집 한 후에는 매우 현지화 된 문제를 해결하려고하는 것 같습니다. 그리고 실제로는 있지만 동시에 레이아웃 생성 프로세스를 디버깅하여 오류가있는 곳을 찾을 수 있기를 바랍니다. 따라서이 솔루션은 다른 사람들에게 유용 할 것입니다.
야로슬라프

답변:


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 파일에 넣었다고 가정하고 있습니까? 또한, 이것은 magento에 의해 어떻게 호출됩니까?
메트로폴리스

"에 옵저버 만들기 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 내 답변을 업데이트
Rick Kuipers

예, 구성에 해당 질문이 있습니다.
야로슬라프

@Yaroslav 블록 유형을 변경할 때 product.phtml이로드되는지 확인할 수 있습니까 core/template? 이것은 모듈 설정에서 오류를 취소하기위한 것입니다.
Rick Kuipers

1
@ Yaroslav 문제가 너무 광범위하게 퍼져서 stackexchange에서 디버깅하기가 어려운 것 같습니다. 문제의 원인이 무엇인지 명확하지 않습니다.
Rick Kuipers

12

나는 Magicento와 함께 PhpStorm을 사용하고 있기 때문에 @benmarks를 내 사용법에 잘 맞출 것이라고 생각했습니다.

PhpStorm app/code/core/Mage/Core/Controller/Varien/Action.php에서 메소드를 열고 중단 점을 둡니다 generateLayoutBlocks(). 요점은 이전 어느 곳에 나 삽입하는 것 $this->getLayout()->generateBlocks();입니다. 나는 이전 줄에 넣었다.

줄 번호로 왼쪽에 빨간색 점으로 표시된 중단 점을 삽입 한 후 마우스 오른쪽 단추를 클릭하여 동작을 사용자 정의 할 수 있습니다. 모든 옵션을 열려면 하단의 "추가"를 클릭하십시오. 여기에 이미지 설명을 입력하십시오

일단 열면 "콘솔에 메시지 로그"(선택 사항) 및 "로그 평가 식"(마술이 발생하는 위치) 상자를 선택합니다. 그런 다음 벤 마크 코드에 맞게 수정하여 텍스트 상자에 붙여 넣습니다. 내가 변경 한 유일한 것은 매번 $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 디버거를 사용하여 프로그램을 실행하면 중단 점에서 멈추고 로그에서이를 볼 수 있습니다.

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

우리는 Alan Storm의 Commerce Bug 확장을 사용하며 레이아웃 문제를 포함하여 Magento의 다양한 것들을 디버깅하는 데 반드시 필요합니다. 레이아웃의 경우 각 페이지에서 활성화 된 레이아웃 핸들과 페이지에 적용되는 레이아웃 xml 구성을 확인할 수 있습니다.

무료는 아니지만 이러한 종류의 것들을 디버깅하는 데 많은 시간을 절약 할 수 있습니다.

참고 : 저는 Alan Storm 또는 Commerce Bug와 아무런 관련이 없으며 단지 행복한 고객입니다.


9
나는 Alan Storm과 제휴를 맺고 있으며 Commerce Bug 2가 레이아웃의 직접 그래프 다이어그램을 생성 할 수 있다는 점을 지적하고 싶었습니다. alanstorm.com/find_magento_block_name
Alan Storm

Alan Storm 커머스 버그의 고객도 만족합니다. 그러나이 문제가있는 시스템에는 설치되어 있지 않으며 모든 테스트 및 사전 프로덕션 시스템에 대한 라이센스가 충분하지 않습니다. 그런데 @AlanStorm, Commerce Bug 2에 대한 업데이트를 얻을 수 있습니까?
야로슬라프

1
@Yaroslav 문의 지원 및 업데이트 및 업그레이드로 분류 할 수 있습니다 pulsestorm.net/contact-us
Alan Storm

3

고맙습니다 벤 마크! 이것은 당신이 설명 한 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.