在 Magento 后端添加自定义仪表板“框”而不编辑默认模板的正确方法是啥?

Posted

技术标签:

【中文标题】在 Magento 后端添加自定义仪表板“框”而不编辑默认模板的正确方法是啥?【英文标题】:What is the proper way to add a custom dashboard "box" in the Magento backend without editing default templates?在 Magento 后端添加自定义仪表板“框”而不编辑默认模板的正确方法是什么? 【发布时间】:2012-03-02 09:39:15 【问题描述】:

我正在努力创建我希望有一天能成为公开可用的 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" >
                <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 将其移动到正确的位置。我猜这会相当容易,但由于明显的原因感觉非常“hacky”。

是否有人对这样做的方式有任何反馈,或者如果有办法吗?请记住,我想再次公开发布这个模块,所以我的目标是做好工作并尽可能少地“黑客”。

非常感谢您的阅读!

【问题讨论】:

我一直在寻找 0) 解决方案已经有一段时间了,但没有运气。到目前为止,我想出的最好的方法是通过观察 html 渲染,但它涉及到 str_replace(),它看起来永远不会很干净。如果你有兴趣,我可以解释一下我是怎么做的。 嘿,感谢 OSdave 的回复!我想我可以想象 str_replace 方法是如何工作的,但我可能会将它与我的其他解决方案一起包括在内,因为(显然)有点“hacky”。目前(我只花了几个小时试图弄清楚这一点)我个人最好的解决方案可能是 JS 解决方案,仅仅是因为大多数人都会有 JS,我也许可以在其他地方渲染盒子并拥有它在 JS 由于某种原因无法工作的情况下看起来不错,但是如果将其移动到需要的位置。不过,我希望有人能睁开我的眼睛;) 【参考方案1】:

没有真正干净的选项,正如你所说,模板是以不可扩展的方式编码的,所以总会有某种程度的hackiness。这是我个人喜欢的使用事件观察器的方式。这样至少不会与其他模块发生冲突。

首先,为core_block_abstract_prepare_layout_aftercore_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);
            
        
    

您的模板需要适应这样一个事实,即您从兄弟姐妹内部插入兄弟&lt;div&gt;,否则您应该没问题。

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

保留它,因为父模板将为您关闭 &lt;fieldset&gt;&lt;div&gt;(我知道,这太丑了)。

【讨论】:

维奈,一如既往,你很棒。非常感谢您的周到和完善的回答。我当然可以看到这样做的好处,“hacky” 位让我有点畏缩,但我想也许在这一点上它可能是两害相权取其轻!关于为什么 Magento 可能选择创建这些块的任何见解?我想我不是第一个想要在后端添加自己的仪表板框的人......我知道选项卡(图表在仪表板上的位置)更容易/“干净”可扩展/可修改。再次感谢维奈! 我也多次问过自己同样的问题。我认为这在当时似乎是一个很好的方法。也许今天它会以不同的方式构建,并考虑到可扩展性。

以上是关于在 Magento 后端添加自定义仪表板“框”而不编辑默认模板的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Magento 2 访问管理仪表板

Magento 自定义支付网关

如何在 Magento 中添加自定义字段来订购?

Magento 2:在 head 标签之后添加自定义脚本

将“添加到购物车”按钮重定向到 Magento 中的不同自定义页面/在 Magento 的产品页面中添加新按钮

用于添加产品愿望清单的 Magento 自定义 API