Skip to content

模板继承 {/programmers/advanced-features/.template.inheritance}

继承将面向对象编程的概念引入到模板中,允许你定义一个(或多个)可以被子模板扩展的基础模板。扩展意味着子模板可以覆盖父模板的所有或部分命名块区域。

  • 继承树可以尽你所愿地深入,也就是说,你可以扩展一个文件,该文件又扩展了另一个文件,以此类推。

  • 子模板不能定义除重写的 {block} 标签内的内容以外的任何内容。{block} 标签外的任何内容都将被移除。

  • 子模板和父模板的 {block} 标签内容可以通过 appendprepend {block} 标签选项标志以及 {$smarty.block.parent}{$smarty.block.child} 占位符进行合并。

  • 模板继承是一个编译时的过程,它创建一个单独的编译模板文件。与基于 {include} 标签包含的子模板的相应解决方案相比,渲染时的性能要好得多。

  • 子模板通过 {extends} 标签扩展其父模板,该标签必须是子模板的第一行。你可以在调用 fetch()display() 时,在 PHP 脚本中定义整个模板继承树,而不是在模板文件中使用 {extends} 标签,使用 extends: 模板资源类型。后者提供了更大的灵活性。

注意

当启用 $compile_check 时,每次调用都会检查继承树中的所有文件是否有修改。因此,你可能希望在生产服务器上禁用 $compile_check

注意

如果你有一个使用 {include} 包含的子模板,并且它包含 {block} 区域,只有当 {include} 本身是从一个包围的 {block} 中调用时,它才能工作。在最终的父模板中,你可能需要一个虚拟的 {block}

layout.tpl (父模板)

<html>
  <head>
    <title>{block name=title}默认页面标题{/block}</title>
    {block name=head}{/block}
  </head>
  <body>
    {block name=body}{/block}
  </body>
</html>

myproject.tpl (子模板)

{extends file='layout.tpl'} {block name=head}
<link href="/css/mypage.css" rel="stylesheet" type="text/css" />
<script src="/js/mypage.js"></script>
{/block}

mypage.tpl (孙模板)

{extends file='myproject.tpl'} {block name=title}我的页面标题{/block} {block
name=head}
<link href="/css/mypage.css" rel="stylesheet" type="text/css" />
<script src="/js/mypage.js"></script>
{/block} {block name=body}我的HTML页面内容在这里{/block}

要渲染上述内容,使用

     $smarty->display('mypage.tpl');

结果输出为

<html>
  <head>
    <title>我的页面标题</title>
    <link href="/css/mypage.css" rel="stylesheet" type="text/css" />
    <script src="/js/mypage.js"></script>
  </head>
  <body>
    我的HTML页面内容在这里
  </body>
</html>

你可以通过使用 extends: 资源 类型在你的 PHP 脚本中定义继承树,而不是在模板文件中使用 {extends} 标签。

下面的代码将返回与上述示例相同的结果。

    <?php
    $smarty->display('extends:layout.tpl|myproject.tpl|mypage.tpl');
    ?>

参见 {block}{extends}extends: 资源