Magento использует собственную ручку в виджетах не работает - PullRequest
4 голосов
/ 12 августа 2010

Я обнаружил, что могу добавить собственные дескрипторы макетов с помощью этого сценария:

$this->getLayout()->getUpdate()->addHandle('myhandle');

Затем я проверил средства просмотра Alan Storm Layout: http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz

? ShowLayout = handles

Дескрипторы для этого запроса

  1. по умолчанию
  2. cms_page
  3. STORE_default
  4. THEME_frontend_default_default
  5. cms_index_index
  6. customer_logged_out
  7. myhandle

Был мой дескриптор, но мой пользовательский макет xml не использовался.

Вот мой xml:

<?xml version="1.0"?>
<layout version="0.1.0">

    <myhandle>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </myhandle>
</layout>

Это отлично работает, поэтому файл xml загружен:

<?xml version="1.0"?>
<layout version="0.1.0">

    <default>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </default>
</layout>

Что не так?Почему не работает это решение?

Если это не правильный путь, как я могу добавить пользовательские CSS и JavaScript для страницы, где использовался виджет?

Обновление: вот кое-что, что может бытьприблизимся к решению:

Если я добавлю этот код после добавления нового дескриптора на страницу:

$this->getLayout()->getUpdate()->fetchPackageLayoutUpdates('myhandle');
$this->getLayout()->generateXml();

После этого вызов «index.php? showLayout = page»обрабатывать код в xml, но страница его не использует.

Ответы [ 2 ]

7 голосов
/ 17 августа 2010

Суть в том, что вы действительно не хотите вводить дескрипторы макетов таким образом. Это становится довольно сложным (достаточно сложным, так что я не могу достаточно быстро проследить его вниз для ответа на переполнение стека), но

  1. Если вы добавите свой дескриптор перед вызовом $ this-> loadLayout () из контроллера, это слишком рано.

  2. Если вы добавите свой дескриптор после вызова $ this-> loadLayout (), будет слишком поздно.

Вот эксперимент, попробуйте изменить метод loadLayout в базовом контроллере действий

File: app/code/core/Mage/Core/Controller/Varien/Action.php
public function loadLayout($handles=null, $generateBlocks=true, $generateXml=true)
{    
    // if handles were specified in arguments load them first
    if (false!==$handles && ''!==$handles) {
        $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
    }

    //YOUR NEW CALL HERE
    $this->getLayout()->getUpdate()->addHandle('myhandle');         

    ...

Это должно сработать и применить ваш макет. Теперь, делать это в производстве было бы плохой идеей, я упомяну это только для того, чтобы показать вам, что маркеры нужно добавлять в очень специфический процесс визуализации макета времени. Как конечный программист, вставлять дескрипторы макетов на самом деле не ваша задача.

Система макетов предназначена для того, чтобы быть слоем, который находится между дизайнерами и необработанным системным кодом PHP. Поскольку вы явно можете писать PHP-код, я бы просто посмотрел, как напрямую внедрить ваш javascript в блок pre-render блока head.

    //from a controller, but could be modified to be used elsewhere
    //also pseudo code
$this->getLayout()->getBlock('header')->append(
    $this->getLayout()
    ->createBlock('core/text', 'some-unique-name')
    ->setText('<script type="text/javascript" src="/foo/baz/bar.js"></script>')
);
2 голосов
/ 04 июля 2012

Если вы хотите добавить новый дескриптор, лучшее решение, вероятно, состоит в том, чтобы добавить дескриптор с наблюдателем.Если у вас есть модуль с собственным URL-адресом, у него уже есть уникальный дескриптор.

Создайте модуль, который вызывает правильный дескриптор.

Создайте файл etc / config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Ho_AttributeSetHandle>
            <version>0.1.0</version>
        </Ho_AttributeSetHandle>
    </modules>
    <global>
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <attributesethandle>
                        <class>Ho_AttributeSetHandle_Model_Observer</class>
                        <method>addAttributeSetHandle</method>
                    </attributesethandle>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </global>
</config>

В моем случае код для Model / Observer.php:

<?php
class Ho_AttributeSetHandle_Model_Observer
{
    /**
     * Converts attribute set name of current product to nice name ([a-z0-9_]+).
     * Adds layout handle PRODUCT_ATTRIBUTE_SET_<attribute_set_nicename> after
     * PRODUCT_TYPE_<product_type_id> handle
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer)
    {
        $product = Mage::registry('current_product');

        /**
         * Return if it is not product page
         */
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $attributeSet = Mage::getModel('eav/entity_attribute_set')->load($product->getAttributeSetId());

        /* Convert attribute set name to alphanumeric + underscore string */
        $niceName = strpos($product->formatUrlKey($attributeSet->getAttributeSetName()), '-') !== FALSE
                    ? str_replace('-', '_', $product->formatUrlKey($attributeSet->getAttributeSetName()))
                    : $product->formatUrlKey($attributeSet->getAttributeSetName());
        $niceName = strpos($niceName, ' ') !== FALSE ? str_replace(' ', '_', $product->formatUrlKey($niceName)) : $niceName;

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer->getEvent()->getLayout()->getUpdate();
        $handles = $update->getHandles(); // Store all handles in a variable
        $update->resetHandles(); // Remove all handles

        /**
         * Rearrange layout handles to ensure PRODUCT_ATTRIBUTE_SET_<attribute_set>
         * handle is added last
         */
        foreach ($handles as $handle) {
            $update->addHandle($handle);
            if ($handle == 'PRODUCT_TYPE_' . $product->getTypeId()) {
                $update->addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName);
            }
        }
    }
}

Не забудьте создать приложение / etc / modules / Ho_AttributeSetHandle.xml:

<config>
    <modules>
        <Ho_AttributeSetHandle>
            <active>true</active>
            <codePool>local</codePool>
        </Ho_AttributeSetHandle>
    </modules>
</config>  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...