您的位置:首页 > Web前端 > HTML

第三章 – Magento的布局(Layout),块(Block)和模板(Template)1

2011-03-31 11:11 507 查看
我们接着研究Magento。根据我们第二章讲的Magento
MVC的架构,我们接下来应该讲模型(Model),但是我们跳过模型先来看布局和块。和一些流行的PHP
MVC架构不同的是,Magento的执行控制器不直接将数据传给试图,相反的视图将直接引用模型,从模型取数据。这样的设计就导致了视图被拆分成两部
分,块(Block)和模板(Template)。块是PHP对象,而模板是原始PHP文件,混合了XHTML和PHP代码(也就是把PHP作为模板语言
来使用了)。每一个块都和一个唯一的模板文件绑定。在模板文件phtml中,“$this”就是指该模板文件对应的快对象。

让我们来看一个例子

File: app/design/frontend/base/default/template/catalog/product/list.phtml


你将看到如下代码

<?php
$_productCollection
=
$this
->
getLoadedProductCollection
(
)
?>

<?php
if
(
!
$_productCollection
->
count
(
)
)
:
?>

<p class="note-msg"><?php
echo
$this
->
__(
'There are no products matching the selection.'
)
?>
</p>
<?php
else
:
?>


这里“getLoadedProductCollection”方法可以在这个模板的块对象“Mage_Catalog_Block_Product_List”中找到

File
:
app/
code/
core/
Mage/
Catalog/
Block/
Product/
List
.
php
...

public
function
getLoadedProductCollection(
)

{

return
$this
->
_getProductCollection(
)
;

}

...


块的“_getProductCollection”方法会实例化模型,并读取数据然后返回给模板。

 

嵌套块

Magento把视图分离成块和模板的真正强大之处在于“getChildHtml”方法。这个方法可以让你实现在块中嵌套块的功能。顶层的块调用第二层的块,然后是第三层……这就是Magento如何输出HTML的。让我们来看一下单列的顶层模板

File: app/design/frontend/base/default/template/page/1column.phtm


 

<?php

/**

* Template for Mage_Page_Block_Html

*/

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php
echo
$this
->
getLang
(
)
?>
" lang="<?php
echo
$this
->
getLang
(
)
?>
">

<head>
<?php
echo
$this
->
getChildHtml
(
'head'
)
?>

</head>

<body<?php
echo
$this
->
getBodyClass
(
)
?' class="'
.
$this
->
getBodyClass
(
)
.
'"'
:
''
?>
>
<?php
echo
$this
->
getChildHtml
(
'after_body_start'
)
?>

<div class="wrapper">
<?php
echo
$this
->
getChildHtml
(
'global_notices'
)
?>

<div class="page">
<?php
echo
$this
->
getChildHtml
(
'header'
)
?>

<div class="main-container col1-layout">

<div class="main">
<?php
echo
$this
->
getChildHtml
(
'breadcrumbs'
)
?>

<div class="col-main">
<?php
echo
$this
->
getChildHtml
(
'global_messages'
)
?>

<?php
echo
$this
->
getChildHtml
(
'content'
)
?>

</div>

</div>

</div>
<?php
echo
$this
->
getChildHtml
(
'footer'
)
?>

<?php
echo
$this
->
getChildHtml
(
'before_body_end'
)
?>

</div>

</div>
<?php
echo
$this
->
getAbsoluteFooter
(
)
?>

</body>

</html>


我们可以看到这个模板里面很多地调用了“$this->getChildHtml(…)”。每次调用都会引入另外一个块的HTML内容,直到最底层的块。

布局对象

看到这里,你可能有这样的疑问

Magento怎么知道在一个页面上要用那些块?

Magento怎么知道哪一个块是顶层块?

“$this->getChildHtml(…)”里面的参数是什么意思?块的名字吗?

Magento引入了布局对象(Layout Object)来解决上面的那些问题。布局对象(或者说布局文件)就是一个XML文件,定义了一个页面包含了哪些块,并且定义了哪个块是顶层块。

在第二章的时候我们在执行方法(Action Method)里面直接输出了HTML内容。现在我们要为我们的Hello World模块创建一个简单的HTML模板。首先我们要创建如下文件

app/design/frontend/default/default/layout/local.xml


包含以下内容

<?xml
version
="1.0"
encoding
="UTF-8"
?>

<layout
version
="0.1.0"
>

<helloworld_index_index>

<reference
name
="root"
>

<block
type
="page/html"
name
="root"
output
="toHtml"
template
="helloworld/simple_page.phtml"
/>

</reference>

</helloworld_index_index>

</layout>


再创建如下文件

app/design/frontend/default/default/template/helloworld/simple_page.phtml


包含以下内容

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Untitled</title>

<style type="text/css">

body {

background-color:#f00;

}

</style>

</head>

<body>

<h4>Links</h4>
<?php
echo
$this
->
getChildHtml
(
'top.links'
)
;
?>

<?php
echo
$this
->
getChildHtml
(
'customer_form_register'
)
;
?>

</body>

</html>


最后,我们要在执行控制器里面调用布局文件,开始输出HTML。修改执行方法如下

public
function
indexAction(
)
{

//remove our previous echo

//echo 'Hello Index!';

$this
->
loadLayout
(
)
;

$this
->
renderLayout
(
)
;

}


清空Magento缓存,访问URL “http://exmaple.com/helloworld/index/index”。你应该看到一个纯红色背景的页面。这个页面的源代码应该和我们创建的文件“simple_page.phtml”一模一样。

究竟是怎么回事呢?

也许你看到这里一头雾水,没关系,我们来慢慢解释。首先你得安装一个 Layout Viewer
模块,这和我们第一章讲的 Config Viewer
模块很相似,都是查看Magento的内部信息。安装完这个模块之后【注:你需要参照第一章的内容,为这个模块创建“app/etc/modules/App_Layoutviewer.xml”】,打开如下URL

http://example.com/helloworld/index/index?showLayout=page


你看到的是你正在请求的页面的布局文件。它是由block,reference和remove组成的。当你在执行方法中调用“loadLayout”时,Magento会做如下处理

生成这个布局文件

为每一个block和reference标签实例化一个块对象。块对象的类名是通过标签的name属性来查找的。这些块对象被存储在布局对象的_blocks数组中

如果block标签包含了output属性,那么这个块的名字和output属性的值会被添加到布局对象的_output数组中

然后,当你在执行方法中调用“renderLayout”方法时,Magento会遍历_output数组中所有的块名字,从_blocks数组中获得该

名字的块,并调用块对象中使用output属性的值作为名字的函数。这个函数往往是“toHtml”。这个output属性也告诉Magento这里就是
输出HTML的起点,也就是顶层块。【注:直接阅读Layout类的代码应该比较容易理解这里的逻辑

File
:
app/
code/
core/
Mage/
Core/
Model/
Layout.
php
public
function
getOutput(
)

{

$out
=
''
;

if
(
!
empty
(
$this
->
_output)
)
{

foreach
(
$this
->
_output as
$callback
)
{

$out
.=
$this
->
getBlock
(
$callback
[
0
]
)
->
$callback
[
1
]
(
)
;

}

}

return
$out
;

}


从这里我们也可以看出,一个页面的布局文件可以拥有多个顶层块。】

下面我们要讲解块对象是如何被实例化的,这个布局文件时如何被生成的,最后我们将动手做一个例子来实践这一章讲的内容。

实例化块对象

在布局文件中,block和reference标签有一个“type”属性,这个属性其实是一个URI

<block type="page/html" ...

<block type="page/template_links"...


Magento就是通过这个URI是用来查找块对应的类名。这个URI分为两部分,第一部分“page”是用来在全局配置中查找一个基本类名,第二部分“html”或者“template_link”将被添加到基本类名后面生成一个具体的将被实例化的类名。

我们以“page/html”为例。首先Magento在全局配置中找到节点

/global/blocks/page


有以下内容

<page>

<class>

Mage_Page_Block

</class>

</page>


这里我们拿到了一个基本类名“Mage_Page_Block”,然后添加URI的第二部分“html”到基本类名后面,我们就得到最终的块对象的
类名 “Mage_Page_Block_Html”。块的类名在Magento中被称为“分组类名”(Grouped Class
Names),这些类都用相似的方法被实例化。我们将在以后的章节中详细介绍这个概念。

为了您的安全,请只打开来源可靠的网址
打开网站
    取消

来自: http://hi.baidu.com/190420456/blog/item/2fa0803c2a61e5c89e3d620c.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息