Skip to content

3.1.模板编译过程

zhangwentao edited this page Jun 14, 2016 · 1 revision

模板编译过程

Her 的编译过程中,Smarty 模板将经历以下几个阶段

replaceScriptTag

replaceScriptTag 阶段会将模板文件中的 <script runat="server"></script> 替换为 {script}{/script} 标签

explandPath

explandPath 阶段将模板文件中所有的相对资源路径替换为绝对的资源路径,方便线上查找文件。 这一阶段处理的标签包括:

  • {html} 标签的 lib 属性
  • {require} 标签的 name 属性
  • {widget} 标签的 name 属性
  • {script} 标签中的 requirerequire.deferrequire.async 调用路径

例如:

{* index:pages/index.html.tpl *}
{html lib="common:js/lib.js"}
    {head}
        {title}XXX{/title}
    {/head}
    {body}
        {require name="./index.css"}
        {widget name="widget/tip/tip.tpl"}
        {script}
            var index = require("./index.js");
            index.init();
            require.defer(["common:js/jquery.js"], function($){
                $.xxx();
            });
        {/script}
    {/body}
{/html}

替换后会变为:

{* index:pages/index.html.tpl *}
{html lib="common:js/lib.js"}
    {head}
        {title}XXX{/title}
    {/head}
    {body}
        {require name="index:pages/index.css"}
        {widget name="index:widget/tip/tip.tpl"}
        {script}
            var index = require("index:pages/index.js");
            index.init();
            require.defer(["common:js/jquery.js"], function($){
                $.xxx();
            });
        {/script}
    {/body}
{/html}

analyseScript

analyseScript 阶段将会分析模板中的 {script} {/script} 代码段中 requirerequire.deferrequire.async 调用,并且将分析结果作为 {script} 的参数保存下来。这样可以避免运行时大量的正则运算。

例如:

{script}
    var index = require("index:pages/index.js");
    require.defer(["common:js/jquery.js"], function($){
        $("XXX").xxx();
        index.init();
    });
{/script}

分析后会变为

{script require=["index:pages/index.js"] async=["common:js/jquery.js"]}
    var index = require("index:pages/index.js");
    require.defer(["common:js/jquery.js"], function($){
        $("XXX").xxx();
        index.init();
    });
{/script}

defineWidget

defineWidget 阶段主要目的是建立 {widget} 调用中文件和对应函数的关系。方便运行时调用。 这个阶段会将模板文件中的 {define} 标签替换为 {function} 标签,并根据资源路径和 method 参数生成 name 参数。 此外,defineWidget 阶段还会修改模板文件中的 {widget} 标签的 method 属性为对应 {function} 标签的 name 属性同值。

例如:

{* common:widget/tip/tip.tpl *}
{define arg1="xxx"}
    我是默认方法
{/define}
{define method="showTip" arg1="xxx"}
    我是命名方法
{/define}

{widget name="common:widget/tip/tip.tpl" method="showTip"}

替换后会变为:

{* common:widget/tip/tip.tpl *}
{function name="_0e5de799a2091aeaa2bce3ea17c6c5b0___main" arg1="xxx"}
    我是默认方法
{/function}
{function name="_0e5de799a2091aeaa2bce3ea17c6c5b0_showTip" arg1="xxx"}
    我是命名方法
{/function}

{widget name="common:widget/tip/tip.tpl" method="_0e5de799a2091aeaa2bce3ea17c6c5b0_showTip"}