在 上篇文章 中我们的模板引擎实现了对 iffor 对支持,同时在文章的最后我给大家留了一个 问题:如何实现支持 includeextends 的标签功能。

在本篇文章中我们将一起来动手实现这两个功能。

include

include 标签对语法是这样的:假设有一个 item.html 模板文件,它的内容如下:

1
  • {{ item }}
  • 还有一个我们要渲染的模板 list.html 内容如下:

    12345
        {% for item in items %}    {% include \”item.html\” %}  {% endfor %}

    渲染 list.html 后的结果类似:

    12345
        
    • item1
    •   
    • item2
    •   
    • item3

    从上面可以看出来 include 标签的作用类似使用 include 所在位置的名字空间 渲染另一个模板然后再使用渲染后的结果。所以我们可以将 include 的模板文件 当作普通的模板文件来处理,用解析那个模板生成后的代码替换 include 所在的位置, 再将结果追加到 result_var 。 生成的代码类似:

    1234567891011 def func_name():    result = []     # 解析 include 的模板    def func_name_include():        result_include = []        return \’\’.join(result_include)    # 调用生成的 func_name_include 函数获取渲染结果    result.append(func_name_include())     return \’\’.join(result)

    生成类似上面的代码就是 include 的关键点,下面看一下实现 include 功能 都做了哪些改动 (可以从 Github 上下载 template3a.py):

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 class Template:     def __init__(self, ..., template_dir=\’\’, encoding=\’utf-8\’):        # ...        self.template_dir = template_dir        self.encoding = encoding        # ...     def _handle_tag(self, token):        \”\”\”处理标签\”\”\”        # ...        tag_name = tag.split()[0]        if tag_name == \’include\’:            self._handle_include(tag)        else:            self._handle_statement(tag)     def _handle_include(self, tag):        filename = tag.split()[1].strip(\’\”\\\’\’)        included_template = self._parse_another_template_file(filename)        # 把解析 include 模板后得到的代码加入当前代码中        # def __func_name():        #    __result = []class=\”crayon-o\”>:        #    __result = []实现支持 includeextends 的标签功能。

    在本篇文章中我们将一起来动手实现这两个功能。

    include

    include 标签对语法是这样的:假设有一个 item.html 模板文件,它的内容如下:

    1
  • {{ item }}
  • 还有一个我们要渲染的模板 list.html 内容如下:

    12345
        {% for item in items %}    {% include \”item.html\” %}  {% endfor %}

    渲染 list.html 后的结果类似:

    12345
        
    • item1
    •   
    • item2
    •   
    • item3

    从上面可以看出来 include 标签的作用类似使用 include 所在位置的名字空间 渲染另一个模板然后再使用渲染后的结果。所以我们可以将 include 的模板文件 当作普通的模板文件来处理,用解析那个模板生成后的代码替换 include 所在的位置, 再将结果追加到 result_var 。 生成的代码类似:

    1234567891011 def func_name():    result = []     # 解析 include 的模板    def func_name_include():        result_include = []        return \’\’.join(result_include)    # 调用生成的 func_name_include 函数获取渲染结果    result.append(func_name_include())     return \’\’.join(result)

    生成类似上面的代码就是 include 的关键点,下面看一下实现 include 功能 都做了哪些改动 (可以从 Github 上下载 template3a.py):

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 class Template:     def __init__(self, ..., template_dir=\’\’, encoding=\’utf-8\’):        # ...        self.template_dir = template_dir        self.encoding = encoding        # ...     def _handle_tag(self, token):        \”\”\”处理标签\”\”\”        # ...        tag_name = tag.split()[0]        if tag_name == \’include\’:            self._handle_include(tag)        else:            self._handle_statement(tag)     def _handle_include(self, tag):        filename = tag.split()[1].strip(\’\”\\\’\’)        included_template = self._parse_another_template_file(filename)        # 把解析 include 模板后得到的代码加入当前代码中        # def __func_name():        #    __result = []