让我们一起来构建一个模板引擎(一)
假设我们要生成下面这样的 html 字符串:
12345678 | <div> <p>welcome, Tom</p> <ul> <li>age: 20</li> <li>weight: 100</li> <li>height: 170</li> </ul></div> |
要求姓名以及 中的内容是根据变量动态生成的,也就是这样的:
123456 | <div> <p>welcome, {name}</p> <ul> {info} </ul></div> |
没接触过模板的同学可能会想到使用字符串格式化的方式来实现:
123456789101112131415161718 | HTML = \’\’\’<div> <p>welcome, {name}</p> <ul> {info} </ul></div>\’\’\’ def gen_html(person): name = person[\’name\’] info_list = [ \'<li>{0}: {1}</li>\’.format(item, value) for item, value in person[\’info\’].items() ] info = \’\\n\’.join(info_list) return HTML.format(name=name, info=info) |
这种方案有一个很明显的问题那就是,需要拼接两个 html 片段。 使用过模板技术的同学应该很容易就想到,在 Web 开发中生成 HTML 的更常用的办法是使用模板:
1234567891011121314 | HTML = \’\’\’<div> <p>welcome, {{ person[\’name\’] }}</p> <ul> {% for item, value in person[\’info\’].items() %} <li>{{ item }}: {{ value }}</li> {% endfor %} </ul></div>\’\’\’ def gen_html(person): return Template(HTML).render({\’person\’: person}) |
本系列文章要讲的就是如何从零开始实现一个这样的模板引擎( Template
)。
使用技术
我们将使用将模板编译为 python 代码的方式来解析和渲染模板。 比如上面的模板将被编译为如下 python 代码:
1234567891011121314151617181920212223 | def render_function(): result = [] result.extend([ \'<div>\\n\’, \'<p>welcome, \’ str(person[\’name\’]), \'</p>\\n\’, \'<ul>\\n\’ ]) for item, value in person[\’info\’].items(): result.extend([ \'<li>\’, str(item), \’: \’, str(value), \'</li>\\n\’ ]) result.extend([ \'</ul>\\n\’ ayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate\” data-settings=\” minimize scroll-always\” style=\” margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important;\”>
要求姓名以及 中的内容是根据变量动态生成的,也就是这样的:
使用技术我们将使用将模板编译为 python 代码的方式来解析和渲染模板。 比如上面的模板将被编译为如下 python 代码:
|