我有一个自定义 info.phtml 文件,如果放在 app\design\frontend\default\default\template\sales\order\info.phtml 中,它已经可以工作。
但是,我不想使用这种方法,因为这是模块的一部分,所以如果以后其他人覆盖了这个文件,它会破坏功能。我已经阅读了有关使用自定义块的信息,但我尝试了许多不同的方法但没有成功。
我有一个自定义 info.phtml 文件,如果放在 app\design\frontend\default\default\template\sales\order\info.phtml 中,它已经可以工作。
但是,我不想使用这种方法,因为这是模块的一部分,所以如果以后其他人覆盖了这个文件,它会破坏功能。我已经阅读了有关使用自定义块的信息,但我尝试了许多不同的方法但没有成功。
实际上,您引用的路径只有在主题包设置为default
. 自 CE1.4 以来所有文件的预期后备主题是base/default
. 这里有很多要考虑的地方,所以让我们分解一下。当然,作为 Magento 实例的最终实现者是很奢侈的,因为您可以使用任意数量的自定义选项,而不必担心如何支持其他开发人员的需求。但是,在开发第三方模块以供其他人发布/使用时(您似乎是这样),如果您希望确保以您的模块预期/需要的方式修改输出,则需要做出一些艰难的决定. 让我们看一下您提到的模板,它是生成输出的方式的一部分。这个例子包含了输出生成过程中涉及的几个因素。
app/design/frontend/base/default/template/sales/order/info.phtml
:
<?php $_order = $this->getOrder() ?>
<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<div class="page-title title-buttons">
<h1><?php echo $this->__('Order #%s - %s', $_order->getRealOrderId(), $_order->getStatusLabel()) ?></h1>
<?php echo $this->getChildHtml('buttons') ?>
</div>
要问的第一个问题是,“我需要改变什么,在哪里改变?” 如果答案在于子块的输出(例如 的输出$this->getChildHtml('buttons')
),则自定义输出意味着指定备用子块(具有多种自定义可能性)。如果不是,则更改可能是模板/块环境的本地更改。
对于第三方开发者,理想的解决方案是尽可能避免依赖主题的输出。例如,如果您需要更改或添加直接从组成对象之一获得的数据,则可以通过 Magento 的配置 XML 使用基于配置的重写或通过事件观察器架构来修改该对象或其行为。在当前示例中,$this->getOrder()
是 的一个实例Mage_Sales_Model_Order
,$this
是 的一个实例Mage_Sales_Block_Order_Info
,并且可以将其中任何一个重写为不同的类。此外,sales_order_load_after
可以观察到该方法修改订单对象的属性。
如果只需要修改一个字符串,通常可以通过 Magento 的翻译功能来实现此更改。在模板中,通过该__()
方法呈现的任何字符串都会通过翻译传递。translate.csv
在特定于主题的文件中,对于最终实现者来说,这很容易修改。对于第三方开发人员来说,一个小的配置 XML 允许指定一个额外的翻译 CSV 文件,即使是一个核心模块。
如果需要更改呈现的视图标记,则有必要修改标记的来源,通常是模板文件。这可以通过几种方式实现。在订单信息块的情况下,sales/order/info.phtml
模板在 Magento 构造函数中定义:
class Mage_Sales_Block_Order_Info extends Mage_Core_Block_Template
{
//snip...
protected function _construct()
{
parent::_construct();
$this->setTemplate('sales/order/info.phtml');
}
//snip...
}
这通常意味着布局 XML 中没有指定的模板。下一步是确定该块实际上是通过布局 XML 还是在控制器中实例化。在后者的情况下,无法通过布局 XML 操作块,因此您需要使用许多可能的 Magento/PHP 选项之一来更改_template
属性。如果块是通过布局 XML 实例化的,那就太好了 - 很容易指定一些自定义布局 XML 来指向一个不会出现在任何主题中的替代模板;您只需要知道块的句柄和名称,这可以通过搜索块实例化标记来确定(例如搜索 * app/design/frontend/*
for type="sales/order_info"
。这将引导您到 * .../base/default/layout/sales.xml*
:
<sales_order_view translate="label">
<label>Customer My Account Order View</label>
<update handle="customer_account"/>
<reference name="my.account.wrapper">
<block type="sales/order_info" as="info" name="sales.order.info">
<block type="sales/order_info_buttons" as="buttons" name="sales.order.info.buttons" />
</block>
<!-- etc. -->
然后可以使用句柄和名称_template
在模块的自定义布局更新 XML 文件中更新块的属性,例如:
<sales_order_view>
<reference name="sales.order.info">
<action method="setTemplate"><tpl>my/custom/template.phtml</...>
<!--
Instead of <reference> you can use the 'block' attribute:
<action method="setTemplate" block="sales.order.info"><tpl>my/custom/template.phtml</...>
-->
这将允许您将自定义模板放在base/default
它所属的模板目录中。但是,您会注意到此块在多个句柄中实例化:
您可能希望使用实用程序句柄和<update />
指令将指令封装到一个位置并将其提供给所有库存句柄。
这是几种方法之一,但它并非万无一失。根据您的扩展消费者受众,您可能希望扫描布局 XML 和模板目录以对库存模板进行自定义/更改,并向管理员提供通知。
这是从模块的布局 xml 完成的。
只需根据调用该文件的命名空间、模块和控制器操作将以下代码放入布局 xml 中并进行必要的更改:
<checkout_onepage_index>//Use correct Controller action
<reference name="checkout.onepage.payment">//Change reference name as per your need
<action method="setTemplate">
<template>giftcard/checkout/onepage/payment.phtml</template>//Path of phtml file in yourmodule template folder
</action>
</reference>
</checkout_onepage_index>
如果您需要自定义 info.phtml 作为模块的一部分,请在模块的 xml 中声明它。然后您可以将您的自定义 phtml 文件放在 app\design\frontend\whatever\somethingelse\template\sales\order 中,它将覆盖它。例如,请参阅有关如何覆盖现有模板文件的线程。