Skip to content

Commit 42c80ab

Browse files
committed
update
1 parent 2876748 commit 42c80ab

File tree

1 file changed

+34
-81
lines changed

1 file changed

+34
-81
lines changed

raw/How a template engine works.md

Lines changed: 34 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,13 @@
22

33
---
44

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+
我已经使用模板引擎很长一段时间了,现在终于有时间来了解一下模板引擎是如何工作的。
76

8-
### Introduction
7+
### 概述
98

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模块,找出一个模板引擎是如何工作的,这是一个简单的系统,这样我们就可以专注于过程的基本思路。
1810

19-
Before we go into the implementation detail, let's look at the simple API
20-
usage first:
11+
进入实现细节之前,让我们首先来看看简单的API使用:
2112

2213
```python
2314

@@ -38,18 +29,11 @@ usage first:
3829

3930
```
4031

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`,然后运行代码来看看输出。
4333

44-
### Implementation
34+
### 实现
4535

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函数:
5337

5438
```python
5539

@@ -59,26 +43,16 @@ one Python function:
5943

6044
```
6145

62-
During the processing procedure, the template engine has two phases:
46+
在处理过程中,模板引擎有两个阶段:
6347

64-
* _parsing_
65-
* _rendering_
48+
* _解析_
49+
* _渲染_
6650

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模块都使用编译器作为解析工具。
7652

77-
### Compiling
53+
### 编译
7854

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代码:
8256

8357
```python
8458

@@ -88,8 +62,7 @@ is simply one Python function that does Python code generation:
8862

8963
```
9064

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`的实现之前,让我们看看它所生成的代码,下面是一个样例模板源字符串:
9366

9467
```python
9568

@@ -104,8 +77,7 @@ produces, here is an example template source string:
10477

10578
```
10679

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代码,它仅仅是一个函数,简化版本如下:
10981

11082
```python
11183

@@ -125,12 +97,7 @@ is just one function, the simplified version is:
12597

12698
```
12799

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`中,查询局部变量比查询全局变量快得多。这里,还可以做一些其他的优化,例如:
134101

135102
```python
136103

@@ -142,18 +109,11 @@ like:
142109

143110
```
144111

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。
149113

150-
### The Code
114+
### 代码
151115

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`对象时,会对模板字符串进行编译,接着可以用它来渲染一个给定的上下文。我们仅需一次编译,就可以把该模板对象缓存起来,构造器的简化版本如下:
157117

158118
```python
159119

@@ -254,7 +214,7 @@ context manager:
254214

255215
```
256216

257-
In the begining of the `parse_template`, we create one template reader first:
217+
`parse_template`的开头,我们首先创建一个模板读取器:
258218

259219
```python
260220

@@ -318,16 +278,15 @@ have found one template directive.
318278

319279
```
320280

321-
Before we handle the special token, we append the text node if there is static
322-
part.
281+
在我们处理了特殊的token后,如果有静态部分,则将其附加到文本节点。
323282

324283
```python
325284

326285
start_brace = reader.consume(2)
327286

328287
```
329288

330-
Get our start brace, if should be `'{{'` or `'{%'`.
289+
获取起始括号,它应该是`'{{'`或者`'{%'`
331290

332291
```python
333292

@@ -345,8 +304,7 @@ Get our start brace, if should be `'{{'` or `'{%'`.
345304

346305
```
347306

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`节点。
350308

351309
```python
352310

@@ -402,7 +360,7 @@ It is time to find out the secrets of `_Node` class, it is quite simple:
402360

403361
```
404362

405-
A `_ChunkList` is just a list of nodes.
363+
一个`_ChunkList`仅是一个节点列表。
406364

407365
```python
408366

@@ -419,7 +377,7 @@ A `_ChunkList` is just a list of nodes.
419377

420378
```
421379

422-
A `_File` node write the `_execute` function to the CodeWriter.
380+
`_File`节点将`_execute`函数写入到CodeWriter。
423381

424382
```python
425383

@@ -478,20 +436,15 @@ compiled Python code:
478436

479437
```
480438

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`函数,然后调用它。
484440

485-
### Next
441+
### 下一步
486442

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模块比我们这里讨论的特性要多得多,但我们已经了解到了基本思想,如果感兴趣的话,你可以发现更多:
491444

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

Comments
 (0)