9. Smarty3:模版继承

时间:2022-12-16 19:01:21

有好多网站各个页面都采用相同的风格,但是如果每个页面都是独立地去开发模版,工作量会比较大,即使采用“复制”去修改局部的方式也不是很理想,如果要修改页面风格,每个页面都要修改。模版继承可以解决这个问题,只要父模版修改,子模版一样会变化


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>

注意:

  1. {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>