前言:首先,让我们先看下在这篇文章中用的比较多的方法。
- MVC Action:没什么多说的,就是mvc的action。eg:当调用category页面时将调用Mage_Catalog_CategoryController::viewAction()。
- Layout Instance:用来呈现页面。在页面呈现前,Magento总是先实例化layout。
- Layout Update Instance:当LayoutInstance建立以后,所有的layout更新都用它,包括在当前页中加载layouthandles数据。
- Output Blocks: Output blocks是直接参与响应的。当layout rendered之后,只有outputblocks是立即rendered的。可以通过$this->getChildHtml()来呈现它的子block。
1 Digging Deeper Into The Rendering Process
在magento的therendering process 分2步。
- Initializing page layout(实例化layout)。
- Sending response with the output from bAction layout handle特定的action调用。locks。
2 Layout Initialization
在magento中通过mvc的action的$this->loadLayout()来初始化layout。
loadLayout()方法可以有3个参数:
- $handles:array()or string 。当这个参数填写了,就加载特定的handle(s)。当参数为没填或者为null,那么就自动加载default handle。 当填了‘’ 或者false就不加载任何的handle。
- $generateBlocks:bool(默认为true)。当为false时,不实例化在layoutXML中定义的block。
- $generateXml:bool (默认为true)。当设置为false时,加载Layoutupdate但是不应用到页面中。那么$generateBlocks参数将无效,layoutblocks将不被初始化。
- Layout and Layout Update的实例化创建时。
- $handles参数填写的情况下在loadLayout()中。
- handle STORE_[store_code]被加入到LayoutUpdate Instance时。eg:当当前店是en,那么handleSTORE_en增加时。
- handle THEME_[area]_[package]_[layout_theme]增加时。
- Action layout handle增加时。eg:当打开category页时,将调用catalog_category_viewhandle。
- 当module激活时,相应的xml将加载。
- 当在当前的theme文件夹中存在local.xnl.它将最先被加载。
- Layout updates of all added layout handles from theloaded layout XML are merged
- Layout updates of all added layout handles from the database aremerged
- loadLayout()的$generateXML设置为false。初始化结束。
- 当更新xml中的remove标签时。
- loadLayout()的$generateBlocks设置为false。初始化结束。
- The instances of block classes are created according to the blockdefinitions in the Layout XML。
- The methods are called with specified arguments on the blocks whereaction tags are defined.
- default layout update是全局的,能被每个页面调用。
- Store layout handle特定的店调用。
- Theme layout handle特定的主题包调用。
- Action layout handle特定的action调用。
3 Output Block Rendering
当layout实例化之后,我们可以调用$this->renderLayout()。这个方法有一个参数:$output。当填写已经存在的block名字,那么这个block将被作为outputblock,那么当layoutrender时将被自动输出。在xml中如果在block中定义output属性,也是outputblock。eg:
一个layout文件至少要有一个outputblock。通常,rootblock是layout中唯一的一个outputblock。但是在一个单一页面中也可以有多个outputblock。在这种情况下,将合并每个outputblock并在响应中返回block名字和别名。
在特定的范围下,block名字和别名都是不同的,block的名字是呈现页唯一的,block的别名在父block中是唯一的。
所以,当一个block用来referenced时,是用的block的名字。当在它的parentblock时,是用它的别名来referenced的。block的名字通常是又长又有描述性的,而别名比较简单。
在上面的例子中。名字是product.info.addtocart,别名是addtocart。
当layout初始化时,将自动按before和after属性来排序。
当before和after属性的值设置为‘-‘时,将排在父block的最前或者最后面。
你能在catalog.xml中,看到上面的handles。
<blocktype="page/html"name="root"output="toHtml"template="page/3columns.phtml">
这里的rootblock被作为是一个outputblock(通过output属性)。output属性定义renderblock的方法toHtml。
一个layout文件至少要有一个outputblock。通常,rootblock是layout中唯一的一个outputblock。但是在一个单一页面中也可以有多个outputblock。在这种情况下,将合并每个outputblock并在响应中返回block名字和别名。
在特定的范围下,block名字和别名都是不同的,block的名字是呈现页唯一的,block的别名在父block中是唯一的。
<blocktype="catalog/product_view"name="product.info.addtocart"as="addtocart"template="catalog/product/view/addtocart.phtml"/>
所以,当一个block用来referenced时,是用的block的名字。当在它的parentblock时,是用它的别名来referenced的。block的名字通常是又长又有描述性的,而别名比较简单。
在上面的例子中。名字是product.info.addtocart,别名是addtocart。
4 Block ordering with after and before attributes
before和after属性能用来定义创建block的位置。这2个属性的值是block的名字或者是别名。
<blocktype="catalog/product_compare_sidebar"before="cart_sidebar"name="catalog.compare.sidebar"template="catalog/product/compare/sidebar.phtml"/>
在上面的例子中,catalog.compare.sidebarblock将出现在cart_sidebarblock的前面。
当layout初始化时,将自动按before和after属性来排序。
当before和after属性的值设置为‘-‘时,将排在父block的最前或者最后面。
5 Non-output block rendering
Non-outputblock可以通过getChildHtml()方法来呈现。而getChildChildHtml()and getBlockHtml()同样可以用来呈现。
- getChildHtml():。第一次参数是block的名字或者别名来呈现(有别名的话,必须要写别名),如果参数为空,将呈现在特定layout的所有的子block。第二个参数$useCache是bool(默认true),当设置为true,那么当后台设置的cache是enabled时,这个block将被缓存,当为false时,即使后台设置的cache是enabled时,这个block也不被缓存。第三个参数$$sorted是bool(默认false),当设置为true时,子block将按照xml中设置的before和after属性来排序。
- getChildChildHtml():getChildChildHtml()用来呈现所有的子block。对比getChildHtml()方法。如果blockA有子blockB,blockB有子blockC和D,那么:
echo $this->getChildHtml('B');
将显示blockB。
将显示blockB C D。echo $this->getChildChildHtml('B');
这方法有4个参数:$name,$childName,$useCacheand$sorted。后2个参数前面已经讲过了。
$name参数:定义了要呈现的block和它的子block的名字。
$childName参数:可选的。如果填了就只显示$nameblock下的$childNameblock。
- getBlockHtml():用来呈现block在任何layout页面中,不象getChildHtml()只能在父block中。
它只有一个参数$name,他只能填写block名,不能写别名。
6 Product Type Handles
在magento中有各种产品类型:SimpleProducts, Configurable Products, Bundle Products, GroupProducts等。而有些地方对于不同的产品类型来说都是一样的,像:productimage, product name, description, up-sell products 。像configurableproducts的配置选项框和捆绑产品显示其捆绑项目的block是一样的。
和其他页面一样,当productpage调用catalog_product_view方法时,它将自动检测产品类型并增加一种产品类型的layouthandles。这种handles是这样命名的:PRODUCT_TYPE_[product_type_code],其中[product_type_code]是产品的系统代码。
下表显示系统的handles。
和其他页面一样,当productpage调用catalog_product_view方法时,它将自动检测产品类型并增加一种产品类型的layouthandles。这种handles是这样命名的:PRODUCT_TYPE_[product_type_code],其中[product_type_code]是产品的系统代码。
下表显示系统的handles。
Producttype | Layoutupdate handle |
---|---|
Simple | PRODUCT_TYPE_simple |
Configurable | PRODUCT_TYPE_configurable |
Grouped | PRODUCT_TYPE_grouped |
Virtual | PRODUCT_TYPE_virtual |
Downloadable | PRODUCT_TYPE_downloadable |
Bundle | PRODUCT_TYPE_bundle |
你能在catalog.xml中,看到上面的handles。
7 Creating Our Own Layout Handles
做个例子:
如果我们想在所有的productpages中看到上面的改变,我们可以这样做:
我们可以把layout的更新放在一个地方,建议放在local.xml中。
- Removethe cart sidebar block from the right sidebar
- Inserta CMS block with identifier foo in the left sidebar
- Usethe 3 column layout for the page
<foo_bar_handle>
<referencename="right">
<removename="cart_sidebar"/>
</reference>
<referencename="left">
<blocktype="cms/block"name="foo">
<actionmethod="setBlockId"><identifier>foo</identifier></action>
</block>
</reference>
<referencename="root">
<actionmethod="setTemplate"><template>page/3columns.phtml</template></action>
</reference>
</foo_bar_handle>
如果我们想在所有的productpages中看到上面的改变,我们可以这样做:
<catalog_product_view>
<updatehandle="foo_bar_handle"/>
</catalog_product_view>
我们可以把layout的更新放在一个地方,建议放在local.xml中。
8 local.xml
如果local.xml存在,magento默认将在最后读取这文件当layout实例化时。在每个theme中,这让我们能改变defaultlayout而不用改写xml文件。同时能让我们的自定义layout放在一个地方。
详细的local.xml,由后面介绍。
详细的local.xml,由后面介绍。