2
2
3
3
---
4
4
5
- I have used template engines for a long time and finally have some time to
6
- find out how a template engine works.
5
+ 我已经使用模板引擎很长一段时间了,现在终于有时间来了解一下模板引擎是如何工作的。
7
6
8
- ### Introduction
7
+ ### 概述
9
8
10
- Briefly, a template engine is a tool that you can use to do programming tasks
11
- involving a lot of textual data. The most common usage is HTML generation in
12
- web applications. Specifically in Python, we have a few options right now if
13
- you want one template engine, like [ jinja] ( http://jinja.pocoo.org/ ) or
14
- [ mako] ( http://www.makotemplates.org/ ) . Here we are going to find out how a
15
- template engine works by digging in the template module of the tornado web
16
- framework, it is a simple system so we can focus on the basic ideas of the
17
- process.
9
+ 简单地说,模板引擎是一个工具,你可以用它来进行涉及到很多的文本数据的编程任务。最常见的用法是Web应用程序中的HTML生成。尤其是在Python中,如果你想要使用一个模板引擎,那么现在我们有几种选择,例如[ jinja] ( http://jinja.pocoo.org/ ) 或者[ mako] ( http://www.makotemplates.org/ ) 。在这里,我们要通过深入tornado web框架的template模块,找出一个模板引擎是如何工作的,这是一个简单的系统,这样我们就可以专注于过程的基本思路。
18
10
19
- Before we go into the implementation detail, let's look at the simple API
20
- usage first:
11
+ 进入实现细节之前,让我们首先来看看简单的API使用:
21
12
22
13
``` python
23
14
@@ -38,18 +29,11 @@ usage first:
38
29
39
30
```
40
31
41
- Here the user's name will be dynamic in the page html, so are a list of jobs.
42
- You can install ` tornado ` and run the code to see the output.
32
+ 这里,用户名在PAGE_HTML中是动态的,工作列表也是。你可以安装` tornado ` ,然后运行代码来看看输出。
43
33
44
- ### Implementation
34
+ ### 实现
45
35
46
- If we look at the ` PAGE_HTML ` closely, we could easily find out that a
47
- template string has two parts, the static literal text part and the dynamic
48
- part. We use special notation to distinguish the dynamic part. In the whole,
49
- the template engine should take the template string and output the static part
50
- as it is, it also needs to handle the dynamic pieces with the given context
51
- and produce the right string result. So basically a template engine is just
52
- one Python function:
36
+ 如果我们进一步看看` PAGE_HTML ` ,那我们很容易就可以发现,一个模板字符串有两个部分,静态文本部分和动态部分。我们使用特殊标记来区分开动态部分。总的来说,模板引擎应该接受模板字符串,然后原样输出静态部分,它还需要利用给定的上下文来处理动态部分,然后生成正确的字符串结果。所以,基本上,一个模板引擎就是一个Python函数:
53
37
54
38
``` python
55
39
@@ -59,26 +43,16 @@ one Python function:
59
43
60
44
```
61
45
62
- During the processing procedure, the template engine has two phases:
46
+ 在处理过程中,模板引擎有两个阶段:
63
47
64
- * _ parsing _
65
- * _ rendering _
48
+ * _ 解析 _
49
+ * _ 渲染 _
66
50
67
- The parsing stage takes the template string and produces something that could
68
- be rendered. Consider the template string as source code, the parsing tool
69
- could be either a programming language interpreter or a programming language
70
- compiler. If the tool is an interpreter, parsing produces a data structure,
71
- the rendering tool will walk through the structure and produces the result
72
- text. The Django template engine parsing tool is an interpreter. Otherwise,
73
- parsing produces some executable code, the rendering tool does nothing but
74
- executes the code and produces the result. The Jinja2, Mako and Tornado
75
- template module are all using a compiler as parsing tool.
51
+ 解析阶段接受模板字符串,然后生成可以渲染的结果。将模板字符串想成源代码的话,解析工具可以是一个编程语言解释器或者编程语言编译器。如果工具是解释器,那么解析会生成一个数据结构,而渲染工具将会根据这个结构来生成结果文本。Django模板引擎解析工具就是这么一个解释器。另外,解析生成一些可执行代码,那么渲染工具仅仅执行代码并生成结果。Jinja2, Mako和Tornado的template模块都使用编译器作为解析工具。
76
52
77
- ### Compiling
53
+ ### 编译
78
54
79
- As said above, we now need to parse the template string, and the parsing tool
80
- in tornado template module compiles templates to Python code. Our parsing tool
81
- is simply one Python function that does Python code generation:
55
+ 如上所述,现在,我们需要解析模板字符串,而tornado的template模块中的解析工具将模板编译成Python代码。我们的解析工具只是一个Python函数,它生成Python代码:
82
56
83
57
``` python
84
58
@@ -88,8 +62,7 @@ is simply one Python function that does Python code generation:
88
62
89
63
```
90
64
91
- Before we get to the implementation of ` parse_template ` , let's see the code it
92
- produces, here is an example template source string:
65
+ 在我们进入` parse_template ` 的实现之前,让我们看看它所生成的代码,下面是一个样例模板源字符串:
93
66
94
67
``` python
95
68
@@ -104,8 +77,7 @@ produces, here is an example template source string:
104
77
105
78
```
106
79
107
- Our ` parse_template ` function will compile this template to Python code, which
108
- is just one function, the simplified version is:
80
+ 我们的` parse_template ` 函数将把这个模板编译成Python代码,它仅仅是一个函数,简化版本如下:
109
81
110
82
``` python
111
83
@@ -125,12 +97,7 @@ is just one function, the simplified version is:
125
97
126
98
```
127
99
128
- Now our template is parsed into a function called ` _execute ` , this function
129
- access all context variables from global namespace. This function creates a
130
- list of strings and join them together as the result string. The ` username ` is
131
- put in a local name ` _tmp ` , looking up a local name is much faster than
132
- looking up a global. There are other optimizations that can be done here,
133
- like:
100
+ 现在,我们的模板被解析到一个名为` _execute ` 的函数中,该函数访问全局命名空间的所有上下文变量。该函数创建一个字符串列表,然后将它们连在一起变成结果字符串。` username ` 位于局部变量` _tmp ` 中,查询局部变量比查询全局变量快得多。这里,还可以做一些其他的优化,例如:
134
101
135
102
``` python
136
103
@@ -142,18 +109,11 @@ like:
142
109
143
110
```
144
111
145
- Expressions in ` {{ ... }} ` are evaluated and appended to the string buffer
146
- list. In the tornado template module, there is no restrictions on the
147
- expressions you can include in your statements, if and for blocks get
148
- translated exactly into Python.
112
+ ` {{ ... }} ` 中的字符串被分析附加到字符串缓冲列表中。在tornado template模块中,对你的语句中可以包含的表达式并无限制,if和for块直接被转换成Python。
149
113
150
- ### The Code
114
+ ### 代码
151
115
152
- Let's see the real implementation now. The core interface that we are using is
153
- the ` Template ` class, when we create one ` Template ` object, we compile the
154
- template string and later we can use it to render a given context. We only
155
- need to compile once and you can cache the template object anywhere, the
156
- simplified version of constructor:
116
+ 现在,让我们看看实际实现。我们所使用的核心接口是` Template ` 类,当我们创建一个` Template ` 对象时,会对模板字符串进行编译,接着可以用它来渲染一个给定的上下文。我们仅需一次编译,就可以把该模板对象缓存起来,构造器的简化版本如下:
157
117
158
118
``` python
159
119
@@ -254,7 +214,7 @@ context manager:
254
214
255
215
```
256
216
257
- In the begining of the ` parse_template ` , we create one template reader first:
217
+ 在 ` parse_template ` 的开头,我们首先创建一个模板读取器:
258
218
259
219
``` python
260
220
@@ -318,16 +278,15 @@ have found one template directive.
318
278
319
279
```
320
280
321
- Before we handle the special token, we append the text node if there is static
322
- part.
281
+ 在我们处理了特殊的token后,如果有静态部分,则将其附加到文本节点。
323
282
324
283
``` python
325
284
326
285
start_brace = reader.consume(2 )
327
286
328
287
```
329
288
330
- Get our start brace, if should be ` '{{' ` or ` '{%' ` .
289
+ 获取起始括号,它应该是 ` '{{' ` 或者 ` '{%' ` 。
331
290
332
291
``` python
333
292
@@ -345,8 +304,7 @@ Get our start brace, if should be `'{{'` or `'{%'`.
345
304
346
305
```
347
306
348
- The start brace is ` '{{' ` and we have an expression here, just get the
349
- contents of the expression and append one ` _Expression ` node.
307
+ 起始括号是` '{{' ` ,说明这里有一个表达式,仅需获取表达式内容,然后附加一个` _Expression ` 节点。
350
308
351
309
``` python
352
310
@@ -402,7 +360,7 @@ It is time to find out the secrets of `_Node` class, it is quite simple:
402
360
403
361
```
404
362
405
- A ` _ChunkList ` is just a list of nodes.
363
+ 一个 ` _ChunkList ` 仅是一个节点列表。
406
364
407
365
``` python
408
366
@@ -419,7 +377,7 @@ A `_ChunkList` is just a list of nodes.
419
377
420
378
```
421
379
422
- A ` _File ` node write the ` _execute ` function to the CodeWriter.
380
+ ` _File ` 节点将 ` _execute ` 函数写入到CodeWriter。
423
381
424
382
``` python
425
383
@@ -478,20 +436,15 @@ compiled Python code:
478
436
479
437
```
480
438
481
- The ` exec ` function executes the compiled code object in the given global
482
- namespace, then we grab our ` _execute ` function from the global namespace and
483
- call it.
439
+ ` exec ` 函数在给定的全局命名空间内执行编译好的代码,然后,从全局命名空间内抓取` _execute ` 函数,然后调用它。
484
440
485
- ### Next
441
+ ### 下一步
486
442
487
- So that's all, compile the template to Python function and execute it to get
488
- result. The tornado template module has more features than we've discussed
489
- here, but we already know well about the basic idea, you can find out more if
490
- you are interested:
443
+ 就是这样啦,将模板编译成Python函数,然后执行以获取结果。tornado的template模块比我们这里讨论的特性要多得多,但我们已经了解到了基本思想,如果感兴趣的话,你可以发现更多:
491
444
492
- * Template inheritance
493
- * Template inclusion
494
- * More control logic like else , elif, try, etc
495
- * Whitespace controls
496
- * Escaping
497
- * More template directives
445
+ * 模板继承
446
+ * 模板包含
447
+ * 更多控制逻辑,例如else , elif, try, 等等
448
+ * 空格控制
449
+ * 转义
450
+ * 更多模板指令
0 commit comments