有好多网站各个页面都采用相同的风格,但是如果每个页面都是独立地去开发模版,工作量会比较大,即使采用“复制”去修改局部的方式也不是很理想,如果要修改页面风格,每个页面都要修改。模版继承可以解决这个问题,只要父模版修改,子模版一样会变化
1. 使用{extends}函数实现模版继承
smarty模版继承和面向对象非常相似,它允许你定义一个或多个基模版供子模版继承。但是所有文件都必须在运行时检查修改设置,更多的继承以为者更大的开销。
在smarty中使用{extends}
标签用在模版继承中子模版对父模版的继承:
注意:继承模版时使用的{extends}标签,必须用在子模版中的第一行
#父类模版(parent.tpl)- 作为模版顶层的基模版
<html>
<head>
<title>Default Page Title</title>
</head>
<body>
主体内容
</body>
</html>
#子模版(child.tpl),继承parent.tpl
{extends file="parent.tpl"}
#子孙模版(grandchild.tpl)
{extends 'child.tpl'}
除了在子模版文件中使用{extends}
继承父模版,还可以使用”extends:模版资源类型”在调用display()函数时,在PHP脚本中定义整个模版继承树。
使用来自PHP脚本的模版继承,输出grandchild.tpl的示例如下:
<?php
$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl')
2. 在模版中覆盖父模版中的部分内容区域
用{block}
块函数定义一个命名的模版继承源区域,然后在子模版中也使用同样的{block}
标签,声明一个子模版源区将取代父模版中的相应区域。
可以在父模版中声明一个或多个继承的源区域,通过{block}
的name属性进行区分,同时{block}
也可以嵌套使用。
#父模版(parent.tpl)- 作为模版顶层的基模版,使用两次{block}在父模版中声明了两组源区域
<html>
<head>
<title>{block name="title"}Default Title{/block}</title>
</head>
<body>
{block name="content"}Default Content{/block}
</body>
</html>
#在子模版(child.tpl)- 使用相同的{block}区域,将父模版对应的内容覆盖
{extends file="parent.tpl"}
{block name='title'} #在子模版中重写父模版中的同名区域
Page Title
{/block}
#加载输出child.tpl模版的结果如下所示:
<html>
<head>
<title>Page Title</title> #输出的时子模版中的重写区域源的内容
</head>
<body>
Default Content #没有被子模版重写,还是父模版中的内容
</body>
</html>
注意:
-
{block}
虽然在父模版中声明,但是不会影响到父模版的输出,只为了在子模版中能够找到区域源并将其覆盖- 如果子模版用
{extends}
标签继承父模版,那么它只能包含{block}
标签(内容),其他任何模版内容都将忽略
- 如果子模版用
3. 合并子模版和父模版的{block}标签内容
如果对父模版中定义的区域源内容,在父模版中不需要全部覆盖,而是需要对部分内容做一些调整,则任意的子、父模版{block}区域可以彼此结合。Samrty提供了下面两种方法。
3.1 用append添加或prepend、prepend选项标记
append与prepend作用方向是相反的,append时添加到父模版后面,而prepend时添加到父模版前面,只对子模版有效。
添加到父模版后面:
#父模版(parent.tpl)- 作为父模版顶层的基模版,使用{block}在模版中声明了一组源区域
<html>
<head>
<title>{block name="title"}Title- {/block}</title>
</head>
<body>
Default Content
</body>
</html>
#子模版(child.tpl)- 使用相同的{block}区域,使用append添加内容到父模版原内容的后面
{extends file="parent.tpl"}
{block name="title" append} #在子模版和父模版同名的区域后追加内容
Page Title
{/block}
#加载输出的child.tpl模版结构如下:
<html>
<head>
<title>Title-Page Title</title> #输出的是子模版与父模版合并后的内容
</head>
<body>
Default Content
</body>
</html>
添加内容到父模版前面:
#父模版(parent.tpl)- 作为父模版顶层的基模版,使用{block}在模版中声明了一组源区域
<html>
<head>
<title>{block name="title"} is my title {/block}</title>
</head>
<body>
Default Content
</body>
</html>
#子模版(child.tpl)- 使用相同的{block}区域,使用append添加内容到父模版原内容的后面
{extends file="parent.tpl"}
{block name="title" prepend} #在子模版和父模版同名的区域前追加内容
Page Title
{/block}
#加载输出的child.tpl模版结构如下:
<html>
<head>
<title>Page Title is my title</title> #输出的是子模版与父模版合并后的内容
</head>
<body>
Default Content
</body>
</html>
3.2 使用{smarty.block.parent}或{smarty.block.child}保留变量作为占位符
可以使用{$smarty.block.parent}
将父模版的{block}
内容插入至子{block}
内容中的任何位置。还可以使用{$smarty.block.child}
将子模版{block}
内容插入值父{block}
内容中的任何位置
{$smarty.block.child}
:
#父模版(parent.tpl)- 作为父模版顶层的基模版,使用{block}在模版中声明了一组源区域
<html>
<head>
<title>{block name="title"}The {$smarty.block.child} was inserted here{/block}</title>
</head>
<body>
Default Content
</body>
</html>
#子模版(child.tpl)- 使用相同的{block}区域,与父模版中同名的区域合并
{extends file="parent.tpl"}
{block name="title"} #将子模版中的内容插入到父{block}内容中{$smarty.block.child}对应的位置
Child Title
{/block}
#加载输出的child.tpl模版结构如下:
<html>
<head>
<title>The Child Title was inserted here</title> #输出的是子模版与父模版合并后的内容
</head>
<body>
Default Content
</body>
</html>
使用{$smarty.block.parent}
例子:
#父模版(parent.tpl)- 作为父模版顶层的基模版,使用{block}在模版中声明了一组源区域
<html>
<head>
<title>{block name="title"}Parent Title{/block}</title>
</head>
<body>
Default Content
</body>
</html>
#子模版(child.tpl)- 使用相同的{block}区域,与父模版中同名的区域合并
{extends file="parent.tpl"}
{block name="title"} #将父模版中的内容插入到子{block}内容中{$smarty.block.parent}对应的位置
You will see now {$smarty.block.parent} here
{/block}
#加载输出的child.tpl模版结构如下:
<html>
<head>
<title> You will see now Parent Title here</title> #输出的是子模版与父模版合并后的内容
</head>
<body>
Default Content
</body>
</html>