magento前端的View视图层,由layout/template/block三者共同组成,不同于国内开源框架(并不是在controler层做数据绑定,同时也没有使用模板引擎的),magento将view抽出来,交由xml配置文件定义,导致很多刚接触magento的开发人员无所适从,其实主要搞清楚layout/template/block这几个东西,其实也就明白了。

magento在前端开发中,template其实是非常灵活的,具体是模板与数据可以随意调用,一个写好的模板可以在A\B多个控制器输出显示,且还不用修改控制器的代码(在layout的xml文件里面配置好就行),这与国内常用开源框架是有差异的。

template:模板,由html标签语言编写,以phtml为后缀的模板文件

template代码位置: app/design/frontend/base/default/template(base/default是magneto基础主题位置,实际开发中依后台配置的主题而有所不同)
template并没有使用国内框架所谓的模板引擎,并不像国内的框架那样,把简单的事情搞复杂了,在phtml页面,可以直接使用<?php标签输出php代码,当然也可以直接使用Mage::getModel方式来获取数据,这也是可以的!

template文件里,总会使用php的$this,这个$this调用的方法,实际是调用Block里面的方法,一般来说,通过模板所处的文件路径能找到相应的Block,如:template/sales/order/totals.phtml,对应的Block就是app/code/core/Mage/Sales/Block/Order/Totals.php
如果在layout里面修改了block的话,Block路径就会不一样了,这种情况下,在后台开启debug调试就会在前台页面上显示出来,详见前篇开发辅助


block:块,按官方解释起来可能很麻烦,是简单的方式可理解View层的Model层,所有template的数据都是从这里获取的。

block代码位置: 各模块下的Block文件夹,如:app/code/core/Mage/Sales/Block
在开发过程中,block里面可以自定义function,然后function里面使用getModel方式获取数据,而在template层使用$this->自定义function的方式实现在template层输出数据。

当然也有能见到block里面有_construct()、_prepareLayout()、_toHtml()等方法,这些方法总会使用$this->setTemplate()方式改变模板路径,实现使用不同的模板;
具体的block核心方法有哪些function并有什么作用,在这里就不过多说了,想深入了解的话多看看Block里面的代码,百度查一查就行


layout:布局 :这是template与block的桥梁,layout的作用其实挺像mvc架构下的controler,magento前端页面的输出就是一个层层嵌套block,通过xml标签配置将block与template做绑定,最后再输出指定的block数据及template页面 ,layout配置文件会嵌套多层block,并给block一个name属性,方便其它地方进行重写或调整

layout代码位置: app/design/frontend/base/default/layout(base/default是magneto基础主题位置,实际开发中依后台配置的主题而有所不同),layout下的文件都是xml后缀的文件,实际也是xml标签;
那么多的layout配置文件,其是怎么与模块及控制器绑定关系呢?其实是在magento模块的confing.xml里面声明的,对应着frontend>layout标签,上一文的layout中有讲到模块是怎么声明调用layout.xml的。

在此就用我订单模块做一个说明(重写的订单模块),如下面代码,重写的模块为app/code/local/Sna/Sales,在模块下的config.xml配置好了layout文件名为hysales.xml,而在我主题sna,app/design/frontend/default/sna/layout/目录下将会有一个hysales.xml的xml布局文件。

<!--自定义模块位置:app/code/local/Sna/Sales/etc/config.xml-->
    <frontend>
        <layout>
            <updates>
                <hysales>
                    <file>hysales.xml</file>
                </hysales>
            </updates>
        </layout>
    </frontend>


<!--路径:app/design/frontend/default/sna/layout/hysales.xml-->
<layout version="0.1.0">
  <sales_order_repay translate="label">
      <label>Customer My Account Order Repay</label>
      <remove name="left"/>
      <reference name="head">
          <action method="addItem"><type>skin_css</type><name>aw_onestepcheckout/css/style.css</name></action>
          <action method="addItem"><type>skin_css</type><name>aw_onestepcheckout/css/additional.css</name></action>
      </reference>
      <update handle="customer_account"/>
      <reference name="my.account.wrapper">
          <block type="sales/order_repay" name="sales.order.repay">
            <block type="sales/order_payment" name="choose-payment-method" template="sales/order/repay/payment_method.phtml" as="choose-payment-method">
            </block>
          </block>
      </reference>
  </sales_order_repay>
</layout>
layout布局文件配置代码(示例)

下面咱将对layout的标签做一个简单的说明,在理解了这些标签的意义,那么Magento最为重要的View层,咱也就完成理解了,建议大家多看看magento核心的catalog.xml、sales.xml、cms.xml、customer.xml的写法来加强理解,在这里面只做一个引导解说之用

sales_order_repay:可以理解url路由标签 sales_order_repay对应为<model_controlpath_function>,
model是config.xml模块声明文件的models下级标签sales,
而controlpath就是模块控制器的路径或控制器文件名,如order就代表着controllers/OrderController.php文件,如果是后台文件,则controlpath写法就是adminhtml_order,对应的文件也变成controllers/adminhtml/OrderController.php
最后的function就不多说了,也就是控制器里实际的function;

remove name="left":移除块标签 magento前端灵活性就体现在此,magento有一个page.xml文件,里面有default标签,这个default会声明一个全局都会用到的基础页面布局如:root(顶层)\head(头部)\top.menu(导航)\breadcrumbs(面包屑)\left(左侧)\right(右侧)……这些都是一个常规页面会显示出来的东西,先声明了,如不需要的话,再在不同的layout下使用remove进行移除就好。

reference name="head":重写头部标签 reference就是重写的意思,name=head指定为html的head标签,从上面代码来看,就是为当前控制器重写头部内容,增加两个css样式文件

update handle="customer_account" 这个标签,我其实也并不太理解,用得不多,可以理解为要操作customer_account下的所有block

block type="sales/order_repay" name="sales.order.repay": 这就是magento的block核心,如上所述,block层层嵌套的,magente前端其实也是输出block为主,后台开启dubeg后,前台页面显示红色背景带虚线的html就是这些block块内容而已
type: 声明着前端输出这个block将使用哪个模块block获取数据,sales模块的block/order/repay.php文件,你也可以换成catalog/category_view,那么将使用catalog模块的block/category/view.php这个文件来获取数据
name: 就是一个命名,方便在block层通过name做调整,或者由其它layout进行重写或下级嵌套。
as: 这应该是一个别名,跟上面的name差不多,在block里面经常看到echo $this->getChildHtml('xxx'),xxx就对应着这个as的值,是返回一个block之用
template: 也就是指定要使用的模板路径了

magento模板性灵活性就在体现在layout配置里,model_controlpath_function标签,指定了控制器,通过多层嵌套的block,再由block的type属性声明使用哪个block,由template指定具体模板,就能动态的调用不同的block,使用不同的phtml模板。

更多的layout属性,多看看核心的layout代码,自行百度多了解下

后记:

用magento1开发已经4年,从不熟悉到现在独立开发模块、拆分magento系统做独立接口去实现业务…此magento开发教程,将会从开发角度讲解一些开发细节的问题,这也算是对M1开发记录的一个小总结吧。
目前magento官方已经停止对1版本更新,但依然有很多公司还会用着M1版本(功能太多,平滑迁移还是要花时间)希望此文章能对m1开发者一些帮助。