Отладка макета Загрузка XML


TL;DR: есть ли способ отладить загрузку макета? Поскольку я считаю, что макет одного модуля противоречит другому.

В связи с предыдущим вопросом, который я задал: Как сделать макет модуля, который будет отображаться во всех темах

Я успешно загрузил свой модуль в локальную среду тестирования (он же мой компьютер для разработки), протестировал переключение между 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.

Author: Evince Development, 2013-01-23

6 answers

Вы можете регистрировать скомпилированные 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>
<!-- ... ->
 56
Author: benmarks, 2013-01-23 16:26:38

Вы можете получить все дескрипторы макета в своем контроллере, выполнив следующее:

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

Или где угодно (если макет был инициализирован), используя это:

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

Возможно, это поможет вам отладить.

РЕДАКТИРОВАТЬ

Установили ли вы свой config.xml чтобы указать класс блока?

    <blocks>
        <banners>
            <class>My_Banners_Block</class>
        </banners>
    </blocks>
 23
Author: Rick Kuipers, 2013-01-23 13:39:31

Я использую PhpStorm с Magicento, и поэтому я подумал, что адаптирую @benmarks отличный ответ к своему использованию.

В PhpStorm откройте app/code/core/Mage/Core/Controller/Varien/Action.php и поставьте точку останова в методе generateLayoutBlocks(). Я думаю, что смысл в том, чтобы вставить его в любом месте перед $this->getLayout()->generateBlocks();. Я поставил его на предыдущую строку.

После вставки точки останова, обозначенной красной точкой слева от номера строки, вы можете щелкнуть ее правой кнопкой мыши, чтобы настроить поведение. Нажмите "Еще" внизу, чтобы открыть все опции. enter image description here

Как только вы откроете это, вы установите флажок "Регистрировать сообщение для консоли" (необязательно) и "Регистрировать оцененное выражение" (где происходит волшебство). Затем скопируйте и вставьте эту адаптацию кода бенмарка в текстовое поле. Единственное, что я изменил, это каждый раз указывать переменную $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())

Итак, теперь это выглядит так этот: Image shows advanced breakpoint settings

После запуска программы (с помощью отладчика 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 - copy from Evaluate Expression popup

 14
Author: Buttle Butkus, 2016-02-13 01:53:09

Мы используем расширение Алана Шторма Commerce Bug и считаем его незаменимым для отладки различных вещей в Magento, включая проблемы с макетом. Для макетов вы можете видеть, какие дескрипторы макета активны на каждой странице и какие конфигурации xml макета применяются к странице.

Это не бесплатно, но сэкономит много времени на отладке подобных вещей.

Примечание: Я никоим образом не связан с Аланом Штормом или коммерческой ошибкой, просто счастливый клиент.

 5
Author: Luke Mills, 2013-01-23 23:58:07

Спасибо Бену Марксу! Это моя версия описанного вами регистратора 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/

 3
Author: Roger Keulen, 2015-09-13 14:45:15

Вы можете добавить это в действие вашего контроллера. Он будет отображать дескрипторы более аккуратно, чем var_dump.

Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
 1
Author: TheKitMurkit, 2017-12-15 16:57:07