Как правильно добавить настраиваемую панель инструментов в бэкэнд Magento без редактирования шаблонов по умолчанию? - PullRequest
2 голосов
/ 10 февраля 2012

Я работаю над созданием того, что, я надеюсь, однажды станет общедоступным расширением Magento (эту часть я упоминаю, потому что для меня важно, чтобы я сделал «правильную вещь» здесь).Одна из вещей, которую я хотел бы сделать, это добавить поле на панели инструментов Magento по умолчанию, в основном новый «ящик», точно такой же, как «5 лучших поисковых терминов», за исключением моего собственного контента.Я хотел бы, чтобы мой новый пользовательский ящик был последним, который отображается (в идеале).

Проблема, с которой я сталкиваюсь, заключается в том, что шаблон, отвечающий за рендеринг панели инструментов, вызывает определенные блоки для рендеринга, и эти блоки вложены в html.Другими словами, где часто есть область, где дочерние блоки будут отображаться в хороший разумный HTML-элемент, в этой ситуации оказывается, что конкретные блоки отображаются.Вот содержимое / app / design / adminhtml / default / default / template / dashboard / index.phtml

  <div class="dashboard-container">
            <?php echo $this->getChildHtml('store_switcher') ?>
            <table cellspacing="25" width="100%">
                <tr>
                    <td><?php echo $this->getChildHtml('sales') ?>
                        <div class="entry-edit">
                            <div class="entry-edit-head"><h4><?php echo $this->__('Last 5 Orders') ?></h4></div>
                            <fieldset class="np"><?php echo $this->getChildHtml('lastOrders'); ?></fieldset>
                        </div>
                        <div class="entry-edit">
                            <div class="entry-edit-head"><h4><?php echo $this->__('Last 5 Search Terms') ?></h4></div>
                            <fieldset class="np"><?php echo $this->getChildHtml('lastSearches'); ?></fieldset>
                        </div>
                        <div class="entry-edit">
                            <div class="entry-edit-head"><h4><?php echo $this->__('Top 5 Search Terms') ?></h4></div>
                            <fieldset class="np"><?php echo $this->getChildHtml('topSearches'); ?></fieldset>
                        </div>
                    </td>
                    <td>
                        <div class="entry-edit" style="border:1px solid #ccc;">
                            <?php echo $this->getChildHtml('diagrams') ?>
                            <?php if (is_array($this->getChild('diagrams')->getTabsIds())) : ?>
                                <div id="diagram_tab_content"></div>
                            <?php endif; ?>
                            <div style="margin:20px;">
                                <?php echo $this->getChildHtml('totals') ?>
                            </div>
                            <div style="margin:20px;">
                                <?php echo $this->getChildHtml('grids') ?>
                                <div id="grid_tab_content"></div>
                            </div>
                        </div>
                    </td>
                </tr>
            </table>
        </div>

Если я делал это в моем собственном магазине, я считаю,Я мог бы достичь этого относительно легко, отредактировав базовый шаблон панели инструментов Magento index.phtml выше, добавив, что мне нужно, чтобы мой блок рендеринга, что-то вроде:

<div class="entry-edit">
     <div class="entry-edit-head">
         <h4><?php echo $this->__('Top 5 Search Terms') ?></h4></div>
         <fieldset class="np"><?php echo $this->getChildHtml('myDashboardBox'); ?></fieldset>
     </div>
</div>

Но это не мой собственный магазин,так что на самом деле это не похоже на вариант.

Теперь, после некоторых размышлений, мои варианты выглядят следующим образом (обратите внимание, что большинство из них кажутся «плохими», и я не был бы очень горд иметь их).в общественных местах):

0) Что-то очевидное, что я не вижу, чтобы вы сказали мне, является идеальным / правильным решением

1) Я мог бы (возможно?) быть в состояниидобавьте мой пользовательский блок внутри одного из этих других блоков в этой области ("topSearches", "sales" и т. д.) и просмотрите мой блок.Это не кажется очень «чистым»

2) Возможно, я смогу визуализировать блок где-нибудь еще на странице панели инструментов, а затем переместить его с помощью JavaScript в правильное место.Полагаю, это было бы довольно легко, но по понятным причинам кажется очень "хакерским".

Есть ли у кого-нибудь отзывы о том, как это сделать, или если есть способ?Имейте в виду, что снова я хотел бы опубликовать этот модуль публично, поэтому моя цель - сделать хорошую работу и сделать как можно меньше «взлома».

Большое спасибо за чтение!

1 Ответ

9 голосов
/ 10 февраля 2012

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

Сначала добавьте наблюдателя для события core_block_abstract_prepare_layout_after и core_block_abstract_to_html_after.

<adminhtml>
    <events>
        <core_block_abstract_prepare_layout_after>
            <observers>
                <your_module>
                    <class>your_module/observer</class>
                    <method>coreBlockAbstractPrepareLayoutAfter</method>
                </your_module>
            </observers>
        </core_block_abstract_prepare_layout_after>
        <core_block_abstract_to_html_after>
            <observers>
                <your_module>
                    <class>your_module/observer</class>
                    <method>coreBlockAbstractToHtmlAfter</method>
                </your_module>
            </observers>
        </core_block_abstract_to_html_after>
    </events>
</adminhtml>

Эти два события отправляются для каждого блока, который создается и отображается в Mage_Core_Block_Abstract. По моему опыту, это не такая проблема - использовать их в интерфейсе adminhtml, но сторонние наблюдатели этих событий добавляют слишком много накладных расходов.

Возвращаясь к поставленной задаче, вам нужно создать класс наблюдателя.

class Your_Module_Model_Observer
{
    public function coreBlockAbstractPrepareLayoutAfter(Varien_Event_Observer $observer)
    {
        if (Mage::app()->getFrontController()->getAction()->getFullActionName() === 'adminhtml_dashboard_index')
        {
            $block = $observer->getBlock();
            if ($block->getNameInLayout() === 'dashboard')
            {
                $block->getChild('topSearches')->setUseAsDashboardHook(true);
            }
        }
    }

    public function coreBlockAbstractToHtmlAfter(Varien_Event_Observer $observer)
    {
        if (Mage::app()->getFrontController()->getAction()->getFullActionName() === 'adminhtml_dashboard_index')
        {
            if ($observer->getBlock()->getUseAsDashboardHook())
            {
                $html = $observer->getTransport()->getHtml();
                $myBlock = $observer->getBlock()->getLayout()
                    ->createBlock('you_module/block')
                    ->setTheValuesAndTemplateYouNeed('HA!');
                $html .= $myBlock->toHtml();
                $observer->getTransport()->setHtml($html);
            }
        }
    }
}

Ваш шаблон должен быть приспособлен для того факта, что вы вставляете родного брата <div> из внутри родного брата, но в остальном у вас все будет хорошо.

</fieldset></div>
<div class="entry-edit">
    <div class="entry-edit-head"><h4>Your Module</h4></div>
    <fieldset class="np">Your Content

Оставьте это при этом, потому что родительский шаблон будет закрывать для вас <fieldset> и <div> (уродливо, черт возьми, я знаю).

...