ID English原文 中文翻译 最近翻译记录 状态 操作
0#翻译 Chapter 9: Advanced Templates 第九章 模板高级进阶 翻译
3#翻译 Although most of your interactions with Django's template language will be in the role of template author, you may want to customize and extend the template engine either to make it do something it doesn't already do, or to make your job easier in some other way. 虽然大多数和Django模板语言的交互都是模板作者的工作,但你可能想定制和扩展模板引擎,让它做一些它不能做的事情,或者是以其他方式让你的工作更轻松。 翻译
5#翻译 This chapter delves deep into the guts of Django's template system. 本章深入探讨Django的模板系统。 翻译
6#翻译 It covers what you need to know if you plan to extend the system or if you're just curious about how it works. 如果你想扩展模板系统或者只是对它的工作原理感觉到好奇,本章涉及了你需要了解的东西。 翻译
7#翻译 It also covers the auto-escaping feature, a security measure you'll no doubt notice over time as you continue to use Django. 它也包含一个自动转意特征,如果你继续使用django,随着时间的推移你一定会注意这个安全考虑。 翻译
9#翻译 If you're looking to use the Django template system as part of another application (i.e., without the rest of the framework), make sure to read the Configuring the Template System in Standalone Mode section later in the chapter. 如果你想把Django的模版系统作为另外一个应用程序的一部分(就是说,仅使用Django的模板系统而不使用Django框架的其他部分),那你一定要读一下“配置独立模式下的模版系统”这一节。 翻译
11#翻译 Template Language Review 模板语言回顾 翻译
13#翻译 First, let's quickly review a number of terms introduced in Chapter 4: 首先,让我们快速回顾一下第四章介绍的若干专业术语: 翻译
15#翻译 A <emphasis>template</emphasis> is a text document, or a normal Python string, that is marked up using the Django template language. <emphasis>模板</emphasis> 是一个纯文本文件,或是一个用Django模板语言标记过的普通的Python字符串。 翻译
16#翻译 A template can contain template tags and variables. 模板可以包含模板标签和变量。 翻译
18#翻译 A <emphasis>template tag</emphasis> is a symbol within a template that does something. <emphasis>模板标签</emphasis> 是在一个模板里面起作用的的标记。 翻译
19#翻译 This definition is deliberately vague. 这个定义故意搞得模糊不清。 翻译
20#翻译 For example, a template tag can produce content, serve as a control structure (an <literal>if</literal> statement or <literal>for</literal> loop), grab content from a database, or enable access to other template tags. 例如,一个模版标签能够产生作为控制结构的内容(一个 <literal>if</literal>语句或<literal>for</literal> 循环), 可以获取数据库内容,或者访问其他的模板标签。 翻译
22#翻译 Template tags are surrounded by <literal>{%</literal> and <literal>%}</literal> : 区块标签被 <literal>{%</literal> 和 <literal>%}</literal> 包围: 翻译
25#翻译 A <emphasis>variable</emphasis> is a symbol within a template that outputs a value. <emphasis>变量</emphasis> 是一个在模板里用来输出值的标记。 翻译
27#翻译 Variable tags are surrounded by <literal>{{</literal> and <literal>}}</literal> : 变量标签被 <literal>{{</literal> 和 <literal>}}</literal> 包围: 翻译
30#翻译 A <emphasis>context</emphasis> is a name -> value mapping (similar to a Python dictionary) that is passed to a template. <emphasis>context</emphasis> 是一个传递给模板的名称到值的映射(类似Python字典)。 翻译
32#翻译 A template <emphasis>renders</emphasis> a context by replacing the variable holes with values from the context and executing all template tags. 模板 <emphasis>渲染</emphasis> 就是是通过从context获取值来替换模板中变量并执行所有的模板标签。 翻译
34#翻译 For more details about the basics of these terms, refer back to Chapter 4. 关于这些基本概念更详细的内容,请参考第四章。 翻译
36#翻译 The rest of this chapter discusses ways of extending the template engine. 本章的其余部分讨论了扩展模板引擎的方法。 翻译
37#翻译 First, though, let's take a quick look at a few internals left out of Chapter 4 for simplicity. 首先,我们快速的看一下第四章遗留的内容。 翻译
39#翻译 RequestContext and Context Processors RequestContext和Context处理器 翻译
41#翻译 When rendering a template, you need a context. 你需要一段context来解析模板。 翻译
42#翻译 Usually this is an instance of <literal>django.template.Context</literal> , but Django also comes with a special subclass, <literal>django.template.RequestContext</literal> , that acts slightly differently. 一般情况下,这是一个 <literal>django.template.Context</literal> 的实例,不过在Django中还可以用一个特殊的子类, <literal>django.template.RequestContext</literal> ,这个用起来稍微有些不同。 翻译
43#翻译 <literal>RequestContext</literal> adds a bunch of variables to your template context by default things like the <literal>HttpRequest</literal> object or information about the currently logged-in user. <literal>RequestContext</literal> 默认地在模板context中加入了一些变量,如 <literal>HttpRequest</literal> 对象或当前登录用户的相关信息。 翻译
45#翻译 Use <literal>RequestContext</literal> when you don't want to have to specify the same set of variables in a series of templates. 当你不想在一系例模板中都明确指定一些相同的变量时,你应该使用 <literal>RequestContext</literal> 。 翻译
46#翻译 For example, consider these two views: 例如,考虑这两个视图: 翻译
49#翻译 (Note that we're deliberately <emphasis>not</emphasis> using the <literal>render_to_response()</literal> shortcut in these examples we're manually loading the templates, constructing the context objects and rendering the templates. (注意,在这些例子中,我们故意 <emphasis>不</emphasis> 使用 <literal>render_to_response()</literal> 这个快捷方法,而选择手动载入模板,手动构造context对象然后渲染模板。 翻译
50#翻译 We're spelling out all of the steps for the purpose of clarity.) 是为了能够清晰的说明所有步骤。) 翻译
52#翻译 Each view passes the same three variables <literal>app</literal> , <literal>user</literal> and <literal>ip_address</literal> to its template. 每个视图都给模板传入了三个相同的变量:<literal>app</literal>、<literal>user</literal>和<literal>ip_address</literal>。 翻译
53#翻译 Wouldn't it be nice if we could remove that redundancy? 如果我们把这些冗余去掉会不会更好? 翻译
55#翻译 <literal>RequestContext</literal> and <strong>context processors</strong> were created to solve this problem. 创建 <literal>RequestContext</literal> 和 <strong>context处理器</strong> 就是为了解决这个问题。 翻译
56#翻译 Context processors let you specify a number of variables that get set in each context automatically without you having to specify the variables in each <literal>render_to_response()</literal> call. Context处理器允许你设置一些变量,它们会在每个context中自动被设置好,而不必每次调用 <literal>render_to_response()</literal> 时都指定。 翻译
57#翻译 The catch is that you have to use <literal>RequestContext</literal> instead of <literal>Context</literal> when you render a template. 要点就是,当你渲染模板时,你要用 <literal>RequestContext</literal> 而不是 <literal>Context</literal> 。 翻译
59#翻译 The most low-level way of using context processors is to create some processors and pass them to <literal>RequestContext</literal> . Here's how the above example could be written with context processors: 最直接的做法是用context处理器来创建一些处理器并传递给 <literal>RequestContext</literal> 。上面的例子可以用context processors改写如下: 翻译
62#翻译 Let's step through this code: 我们来通读一下代码: 翻译
64#翻译 First, we define a function <literal>custom_proc</literal> . This is a context processor it takes an <literal>HttpRequest</literal> object and returns a dictionary of variables to use in the template context. 首先,我们定义一个函数 <literal>custom_proc</literal> 。这是一个context处理器,它接收一个 <literal>HttpRequest</literal> 对象,然后返回一个字典,这个字典中包含了可以在模板context中使用的变量。 翻译
65#翻译 That's all it does. 它就做了这么多。 翻译
67#翻译 We've changed the two view functions to use <literal>RequestContext</literal> instead of <literal>Context</literal> . There are two differences in how the context is constructed. 我们在这两个视图函数中用 <literal>RequestContext</literal> 代替了 <literal>Context</literal> 。在context对象的构建上有两个不同点。 翻译
68#翻译 One, <literal>RequestContext</literal> requires the first argument to be an <literal>HttpRequest</literal> object the one that was passed into the view function in the first place (<literal>request</literal> ). Two, <literal>RequestContext</literal> takes an optional <literal>processors</literal> argument, which is a list or tuple of context processor functions to use. 一, <literal>RequestContext</literal> 的第一个参数需要传递一个 <literal>HttpRequest</literal> 对象,就是传递给视图函数的第一个参数( <literal>request</literal> )。二, <literal>RequestContext</literal> 有一个可选的参数 <literal>processors</literal> ,这是一个包含context处理器函数的列表或者元组。 翻译
69#翻译 Here, we pass in <literal>custom_proc</literal> , the custom processor we defined above. 在这里,我们传递了我们之前定义的处理器函数 <literal>curstom_proc</literal> 。 翻译
71#翻译 Each view no longer has to include <literal>app</literal> , <literal>user</literal> or <literal>ip_address</literal> in its context construction, because those are provided by <literal>custom_proc</literal> . 每个视图的context结构里不再包含 <literal>app</literal> 、 <literal>user</literal> 、 <literal>ip_address</literal> 等变量,因为这些由 <literal>custom_proc</literal> 函数提供了。 翻译
73#翻译 Each view <emphasis>still</emphasis> has the flexibility to introduce any custom template variables it might need. 每个视图 <emphasis>仍然</emphasis> 具有很大的灵活性,可以引入我们需要的任何模板变量。 翻译
74#翻译 In this example, the <literal>message</literal> template variable is set differently in each view. 在这个例子中, <literal>message</literal> 模板变量在每个视图中都不一样。 翻译
76#翻译 In Chapter 4, we introduced the <literal>render_to_response()</literal> shortcut, which saves you from having to call <literal>loader.get_template()</literal> , then create a <literal>Context</literal> , then call the <literal>render()</literal> method on the template. 在第四章,我们介绍了 <literal>render_to_response()</literal> 这个快捷方式,它可以简化调用 <literal>loader.get_template()</literal> ,然后创建一个 <literal>Context</literal> 对象,最后再调用模板对象的 <literal>render()</literal>过程。 翻译
77#翻译 In order to demonstrate the lower-level workings of context processors, the above examples didn't use <literal>render_to_response()</literal> , . But it's possible and preferable to use context processors with <literal>render_to_response()</literal> . Do this with the <literal>context_instance</literal> argument, like so: 为了讲解context处理器底层是如何工作的,在上面的例子中我们没有使用 <literal>render_to_response()</literal> 。但是建议选择 <literal>render_to_response()</literal> 作为context的处理器。这就需要用到<literal>context_instance</literal>参数: 翻译
80#翻译 Here, we've trimmed down each view's template rendering code to a single (wrapped) line. 在这,我们将每个视图的模板渲染代码写成了一个单行。 翻译
82#翻译 This is an improvement, but, evaluating the conciseness of this code, we have to admit we're now almost overdosing on the <emphasis>other</emphasis> end of the spectrum. 虽然这是一种改进,但是,请考虑一下这段代码的简洁性,我们现在不得不承认的是在 <emphasis>另外</emphasis> 一方面有些过分了。 翻译
83#翻译 We've removed redundancy in data (our template variables) at the cost of adding redundancy in code (in the <literal>processors</literal> call). 我们以代码冗余(在 <literal>processors</literal> 调用中)的代价消除了数据上的冗余(我们的模板变量)。 翻译
84#翻译 Using context processors doesn't save you much typing if you have to type <literal>processors</literal> all the time. 由于你不得不一直键入 <literal>processors</literal> ,所以使用context处理器并没有减少太多的输入量。 翻译
86#翻译 For that reason, Django provides support for <emphasis>global</emphasis> context processors. Django因此提供对 <emphasis>全局</emphasis> context处理器的支持。 翻译
87#翻译 The <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> setting (in your <literal>settings.py</literal> ) designates which context processors should <emphasis>always</emphasis> be applied to <literal>RequestContext</literal> . This removes the need to specify <literal>processors</literal> each time you use <literal>RequestContext</literal> . <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> 指定了哪些<literal>context processors</literal><emphasis>总是</emphasis>默认被使用。这样就省去了每次使用 <literal>RequestContext</literal> 都指定 <literal>processors</literal> 的麻烦。 翻译
89#翻译 By default, <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> is set to the following: 默认情况下, <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> 设置如下: 翻译
92#翻译 This setting is a tuple of callables that use the same interface as our <literal>custom_proc</literal> function above functions that take a request object as their argument and return a dictionary of items to be merged into the context. 这个设置项是一个可调用函数的元组,其中的每个函数使用了和上文中我们的 <literal>custom_proc</literal> 相同的接口,它们以request对象作为参数,返回一个会被合并传给context的字典: 翻译
93#翻译 Note that the values in <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> are specified as <emphasis>strings</emphasis> , which means the processors are required to be somewhere on your Python path (so you can refer to them from the setting). 接收一个request对象作为参数,返回一个包含了将被合并到context中的项的字典。 翻译
95#翻译 Each processor is applied in order. 每个处理器将会按照顺序应用。 翻译
96#翻译 That is, if one processor adds a variable to the context and a second processor adds a variable with the same name, the second will override the first. 也就是说如果你在第一个处理器里面向context添加了一个变量,而第二个处理器添加了同样名字的变量,那么第二个将会覆盖第一个。 翻译
98#翻译 Django provides a number of simple context processors, including the ones that are enabled by default: Django提供了几个简单的context处理器,有些在默认情况下被启用的。 翻译
100#翻译 django.core.context_processors.auth django.core.context_processors.auth 翻译
102#翻译 If <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> contains this processor, every <literal>RequestContext</literal> will contain these variables: 如果 <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> 包含了这个处理器,那么每个 <literal>RequestContext</literal> 将包含这些变量: 翻译
104#翻译 <literal>user</literal> : A <literal>django.contrib.auth.models.User</literal> instance representing the current logged-in user (or an <literal>AnonymousUser</literal> instance, if the client isn't logged in). <literal>user</literal> :一个 <literal>django.contrib.auth.models.User</literal> 实例,描述了当前登录用户(或者一个 <literal>AnonymousUser</literal> 实例,如果客户端没有登录)。 翻译
106#翻译 <literal>messages</literal> : A list of messages (as strings) for the current logged-in user. <literal>messages</literal> :一个当前登录用户的消息列表(字符串)。 翻译
107#翻译 Behind the scenes, this variable calls <literal>request.user.get_and_delete_messages()</literal> for every request. 在后台,对每一个请求,这个变量都调用 <literal>request.user.get_and_delete_messages()</literal> 方法。 翻译
108#翻译 That method collects the user's messages and deletes them from the database. 这个方法收集用户的消息然后把它们从数据库中删除。 翻译
110#翻译 <literal>perms</literal> : An instance of <literal>django.core.context_processors.PermWrapper</literal> , which represents the permissions the current logged-in user has. <literal>perms</literal> : <literal>django.core.context_processors.PermWrapper</literal> 的一个实例,包含了当前登录用户有哪些权限。 翻译
112#翻译 See Chapter 14 for more information on users, permissions, and messages. 关于users、permissions和messages的更多内容请参考第14章。 翻译
114#翻译 django.core.context_processors.debug django.core.context_processors.debug 翻译
116#翻译 This processor pushes debugging information down to the template layer. 这个处理器把调试信息发送到模板层。 翻译
117#翻译 If <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> contains this processor, every <literal>RequestContext</literal> will contain these variables: 如果<literal>TEMPLATE_CONTEXT_PROCESSORS</literal>包含这个处理器,每一个<literal>RequestContext</literal>将包含这些变量: 翻译
119#翻译 <literal>debug</literal> : The value of your <literal>DEBUG</literal> setting (either <literal>True</literal> or <literal>False</literal> ). You can use this variable in templates to test whether you're in debug mode. <literal>debug</literal> :你设置的 <literal>DEBUG</literal> 的值( <literal>True</literal> 或 <literal>False</literal> )。你可以在模板里面用这个变量测试是否处在debug模式下。 翻译
121#翻译 <literal>sql_queries</literal> : A list of <literal>{'sql': <literal>sql_queries</literal> :包含类似于 <literal>{'sql': 翻译
122#翻译 ..., 'time': ..., 'time': 翻译
123#翻译 ...}</literal> dictionaries representing every SQL query that has happened so far during the request and how long it took. </literal> 的字典的一个列表, 记录了这个请求期间的每个SQL查询以及查询所耗费的时间。 翻译
124#翻译 The list is in the order in which the queries were issued. 这个列表是按照请求顺序进行排列的。 翻译
126#翻译 Because debugging information is sensitive, this context processor will only add variables to the context if both of the following conditions are true: 由于调试信息比较敏感,所以这个context处理器只有当同时满足下面两个条件的时候才有效: 翻译
128#翻译 The <literal>DEBUG</literal> setting is <literal>True</literal> . <literal>DEBUG</literal> 参数设置为 <literal>True</literal> 。 翻译
130#翻译 The request came from an IP address in the <literal>INTERNAL_IPS</literal> setting. 请求的ip应该包含在 <literal>INTERNAL_IPS</literal> 的设置里面。 翻译
132#翻译 Astute readers will notice that the <literal>debug</literal> template variable will never have the value <literal>False</literal> because, if <literal>DEBUG</literal> is <literal>False</literal> , then the <literal>debug</literal> template variable won't be populated in the first place. 细心的读者可能会注意到<literal>debug</literal>模板变量的值永远不可能为<literal>False</literal>,因为如果<literal>DEBUG</literal>是<literal>False</literal>,那么<literal>debug</literal>模板变量一开始就不会被RequestContext所包含。 翻译
134#翻译 django.core.context_processors.i18n django.core.context_processors.i18n 翻译
136#翻译 If this processor is enabled, every <literal>RequestContext</literal> will contain these variables: 如果这个处理器启用,每个 <literal>RequestContext</literal> 将包含下面的变量: 翻译
138#翻译 <literal>LANGUAGES</literal> : The value of the <literal>LANGUAGES</literal> setting. <literal>LANGUAGES</literal> : <literal>LANGUAGES</literal> 选项的值。 翻译
140#翻译 <literal>LANGUAGE_CODE</literal> : <literal>request.LANGUAGE_CODE</literal> if it exists; otherwise, the value of the <literal>LANGUAGE_CODE</literal> setting. <literal>LANGUAGE_CODE</literal> :如果 <literal>request.LANGUAGE_CODE</literal> 存在,就等于它;否则,等同于 <literal>LANGUAGE_CODE</literal> 设置。 翻译
142#翻译 Appendix D provides more information about these two settings. 附录E提供了有关这两个设置的更多的信息。 翻译
144#翻译 django.core.context_processors.request django.core.context_processors.request 翻译
146#翻译 If this processor is enabled, every <literal>RequestContext</literal> will contain a variable <literal>request</literal> , which is the current <literal>HttpRequest</literal> object. 如果启用这个处理器,每个 <literal>RequestContext</literal> 将包含变量 <literal>request</literal> , 也就是当前的 <literal>HttpRequest</literal> 对象。 翻译
147#翻译 Note that this processor is not enabled by default; you have to activate it. 注意这个处理器默认是不启用的,你需要激活它。 翻译
149#翻译 You might want to use this if you find your templates needing to access attributes of the current <literal>HttpRequest</literal> such as the IP address: 如果你发现你的模板需要访问当前的<literal>HttpRequest</literal>你就需要使用它: 翻译
152#翻译 Guidelines for Writing Your Own Context Processors 写Context处理器的一些建议 翻译
154#翻译 Here are a few tips for rolling your own: 编写处理器的一些建议: 翻译
156#翻译 Make each context processor responsible for the smallest subset of functionality possible. 使每个context处理器完成尽可能小的功能。 翻译
157#翻译 It's easy to use multiple processors, so you might as well split functionality into logical pieces for future reuse. 使用多个处理器是很容易的,所以你可以根据逻辑块来分解功能以便将来复用。 翻译
159#翻译 Keep in mind that any context processor in <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> will be available in <emphasis>every</emphasis> template powered by that settings file, so try to pick variable names that are unlikely to conflict with variable names your templates might be using independently. 要注意 <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> 里的context processor 将会在基于这个settings.py的<emphasis>每个</emphasis> 模板中有效,所以变量的命名不要和模板的变量冲突。 翻译
160#翻译 As variable names are case-sensitive, it's not a bad idea to use all caps for variables that a processor provides. 变量名是大小写敏感的,所以processor的变量全用大写是个不错的主意。 翻译
162#翻译 It doesn't matter where on the filesystem they live, as long as they're on your Python path so you can point to them from the <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> setting. 不论它们存放在哪个物理路径下,只要在你的Python搜索路径中,你就可以在 <literal>TEMPLATE_CONTEXT_PROCESSORS</literal> 设置里指向它们。 翻译
163#翻译 With that said, the convention is to save them in a file called <literal>context_processors.py</literal> within your app or project. 建议你把它们放在应用或者工程目录下名为 <literal>context_processors.py</literal> 的文件里。 翻译
165#翻译 Automatic HTML Escaping html自动转意 翻译
167#翻译 When generating HTML from templates, there's always a risk that a variable will include characters that affect the resulting HTML. 从模板生成html的时候,总是有一个风险——变量包了含会影响结果html的字符。 翻译
168#翻译 For example, consider this template fragment: 例如,考虑这个模板片段: 翻译
171#翻译 At first, this seems like a harmless way to display a user's name, but consider what would happen if the user entered his name as this: 一开始,这看起来是显示用户名的一个无害的途径,但是考虑如果用户输入如下的名字将会发生什么: 翻译
174#翻译 With this name value, the template would be rendered as: 用这个用户名,模板将被渲染成: 翻译
177#翻译 which means the browser would pop-up a JavaScript alert box! 这意味着浏览器将弹出JavaScript警告框! 翻译
179#翻译 Similarly, what if the name contained a <literal>'<'</literal> symbol, like this? 类似的,如果用户名包含<literal>小于</literal>符号,就像这样: 翻译
181#翻译 <b>username 用户名 翻译
183#翻译 That would result in a rendered template like this: 那样的话模板结果被翻译成这样: 翻译
186#翻译 which, in turn, would result in the remainder of the Web page being bolded! 页面的剩余部分变成了粗体! 翻译
188#翻译 Clearly, user-submitted data shouldn't be trusted blindly and inserted directly into your Web pages, because a malicious user could use this kind of hole to do potentially bad things. 显然,用户提交的数据不应该被盲目信任,直接插入到你的页面中。因为一个潜在的恶意的用户能够利用这类漏洞做坏事。 翻译
189#翻译 This type of security exploit is called a Cross Site Scripting (XSS) attack. 这类漏洞称为被跨域脚本 (XSS) 攻击。 翻译
190#翻译 (For more on security, see Chapter 20.) 关于安全的更多内容,请看20章 翻译
192#翻译 To avoid this problem, you have two options: 为了避免这个问题,你有两个选择: 翻译
194#翻译 One, you can make sure to run each untrusted variable through the <literal>escape</literal> filter, which converts potentially harmful HTML characters to unharmful ones. 一是你可以确保每一个不被信任的变量都被<literal>escape</literal>过滤器处理一遍,把潜在有害的html字符转换为无害的。 翻译
195#翻译 This was the default solution in Django for its first few years, but the problem is that it puts the onus on <emphasis>you</emphasis> , the developer / template author, to ensure you're escaping everything. 这是最初几年Django的默认方案,但是这样做的问题是它把责任推给<emphasis>你</emphasis>(开发者、模版作者)自己,来确保把所有东西转意。 翻译
196#翻译 It's easy to forget to escape data. 很容易就忘记转意数据。 翻译
198#翻译 Two, you can take advantage of Django's automatic HTML escaping. 二是,你可以利用Django的自动html转意。 翻译
199#翻译 The remainder of this section describes how auto-escaping works. 这一章的剩余部分描述自动转意是如何工作的。 翻译
201#翻译 By default in Django, every template automatically escapes the output of every variable tag. 在django里默认情况下,每一个模板自动转意每一个变量标签的输出。 翻译
202#翻译 Specifically, these five characters are escaped: 尤其是这五个字符。 翻译
204#翻译 <literal><</literal> is converted to <literal>&lt;</literal> <literal></literal><literal></literal> 翻译
206#翻译 <literal>></literal> is converted to <literal>&gt;</literal> > 被转换为> 翻译
208#翻译 <literal>'</literal> (single quote) is converted to <literal>&#39;</literal> <literal>'</literal>(单引号)被转换为<literal>'</literal> 翻译
210#翻译 <literal>&quot;</literal> (double quote) is converted to <literal>&quot;</literal> <literal>"</literal>(双引号)被转换为<literal>"</literal> 翻译
212#翻译 <literal>&</literal> is converted to <literal>&amp;</literal> 翻译 翻译
214#翻译 Again, we stress that this behavior is on by default. 另外,我强调一下这个行为默认是开启的。 翻译
215#翻译 If you're using Djangos template system, you're protected. 如果你正在使用django的模板系统,那么你是被保护的。 翻译
217#翻译 How to Turn it Off 如何关闭它 翻译
219#翻译 If you don't want data to be auto-escaped, on a per-site, per-template level or per-variable level, you can turn it off in several ways. 如果你不想数据被自动转意,在每一站点级别、每一模板级别或者每一变量级别你都有几种方法来关闭它。 翻译
221#翻译 Why would you want to turn it off? 为什么要关闭它? 翻译
222#翻译 Because sometimes, template variables contain data that you <emphasis>intend</emphasis> to be rendered as raw HTML, in which case you don't want their contents to be escaped. 因为有时候模板变量包含了一些原始html数据,在这种情况下我们不想它们的内容被转意。 翻译
223#翻译 For example, you might store a blob of trusted HTML in your database and want to embed that directly into your template. 例如,你可能在数据库里存储了一段被信任的html代码,并且你想直接把它嵌入到你的模板里。 翻译
224#翻译 Or, you might be using Django's template system to produce text that is <emphasis>not</emphasis> HTML like an e-mail message, for instance. 或者,你可能正在使用Django的模板系统生成非html文本,比如一封e-mail。 翻译
226#翻译 For Individual Variables 对于单独的变量 翻译
228#翻译 To disable auto-escaping for an individual variable, use the <literal>safe</literal> filter: 用safe过滤器为单独的变量关闭自动转意: 翻译
231#翻译 Think of <emphasis>safe</emphasis> as shorthand for <emphasis>safe from further escaping</emphasis> or <emphasis>can be safely interpreted as HTML</emphasis> . In this example, if <literal>data</literal> contains <literal>'<b>'</literal> , the output will be: 你可以把<emphasis>safe</emphasis>当做<emphasis>safe from further escaping</emphasis>的简写,或者<emphasis>当做可以被直接译成HTML的内容</emphasis>。在这个例子里,如果<literal>数据</literal>包含<literal>''</literal>,那么输出会变成: 翻译
234#翻译 For Template Blocks 对于模板块 翻译
236#翻译 To control auto-escaping for a template, wrap the template (or just a particular section of the template) in the <literal>autoescape</literal> tag, like so: 为了控制模板的自动转意,用标签autoescape来包装整个模板(或者模板中常用的部分),就像这样: 翻译
239#翻译 The <literal>autoescape</literal> tag takes either <literal>on</literal> or <literal>off</literal> as its argument. autoescape 标签有两个参数on和off 翻译
240#翻译 At times, you might want to force auto-escaping when it would otherwise be disabled. 有时,你可能想阻止一部分自动转意,对另一部分自动转意。 翻译
241#翻译 Here is an example template: 这是一个模板的例子: 翻译
244#翻译 The auto-escaping tag passes its effect on to templates that extend the current one as well as templates included via the <literal>include</literal> tag, just like all block tags. auto-escaping 标签的作用域不仅可以影响到当前模板还可以通过include标签作用到其他标签,就像block标签一样。 翻译
245#翻译 For example: 例如: 翻译
248#翻译 Because auto-escaping is turned off in the base template, it will also be turned off in the child template, resulting in the following rendered HTML when the <literal>greeting</literal> variable contains the string <literal><b>Hello!</b></literal> : 由于在base模板中自动转意被关闭,所以在child模板中自动转意也会关闭.因此,在下面一段HTML被提交时,变量greeting的值就为字符串Hello! 翻译
251#翻译 Notes 备注 翻译
253#翻译 Generally, template authors don't need to worry about auto-escaping very much. 通常,模板作者没必要为自动转意担心. 翻译
254#翻译 Developers on the Python side (people writing views and custom filters) need to think about the cases in which data shouldn't be escaped, and mark data appropriately, so things work in the template. 基于Pyhton的开发者(编写VIEWS视图和自定义过滤器)只需要考虑哪些数据不需要被转意,适时的标记数据,就可以让它们在模板中工作。 翻译
256#翻译 If you're creating a template that might be used in situations where you're not sure whether auto-escaping is enabled, then add an <literal>escape</literal> filter to any variable that needs escaping. 如果你正在编写一个模板而不知道是否要关闭自动转意,那就为所有需要转意的变量添加一个escape过滤器。 翻译
257#翻译 When auto-escaping is on, there's no danger of the <literal>escape</literal> filter <emphasis>double-escaping</emphasis> data the <literal>escape</literal> filter does not affect auto-escaped variables. 当自动转意开启时,使用escape过滤器似乎会两次转意数据,但其实没有任何危险。因为escape过滤器不作用于被转意过的变量。 翻译
259#翻译 Automatic Escaping of String Literals in Filter Arguments 过滤器参数里的字符串常量的自动转义 翻译
261#翻译 As we mentioned earlier, filter arguments can be strings: 就像我们前面提到的,过滤器也可以是字符串. 翻译
264#翻译 All string literals are inserted <emphasis>without</emphasis> any automatic escaping into the template they act as if they were all passed through the <literal>safe</literal> filter. 所有字符常量没有经过转义就被插入模板,就如同它们都经过了safe过滤。 翻译
265#翻译 The reasoning behind this is that the template author is in control of what goes into the string literal, so they can make sure the text is correctly escaped when the template is written. 这是由于字符常量完全由模板作者决定,因此编写模板的时候他们会确保文本的正确性。 翻译
267#翻译 This means you would write 这意味着你必须这样写 翻译
270#翻译 rather than 而不是这样 翻译
273#翻译 This doesn't affect what happens to data coming from the variable itself. 这点对来自变量本身的数据不起作用。 翻译
274#翻译 The variable's contents are still automatically escaped, if necessary, because they're beyond the control of the template author. 如果必要,变量内容会自动转义,因为它们不在模板作者的控制下。 翻译
276#翻译 Inside Template Loading 模板加载的内幕 翻译
278#翻译 Generally, you'll store templates in files on your filesystem, but you can use custom <emphasis>template loaders</emphasis> to load templates from other sources. 一般说来,你会把模板以文件的方式存储在文件系统中,但是你也可以使用自定义的 <emphasis>template loaders</emphasis> 从其他来源加载模板。 翻译
280#翻译 Django has two ways to load templates: Django有两种方法加载模板 翻译
282#翻译 <literal>django.template.loader.get_template(template_name)</literal> : <literal>get_template</literal> returns the compiled template (a <literal>Template</literal> object) for the template with the given name. <literal>django.template.loader.get_template(template_name)</literal> : <literal>get_template</literal> 根据给定的模板名称返回一个已编译的模板(一个 <literal>Template</literal> 对象)。 翻译
283#翻译 If the template doesn't exist, a <literal>TemplateDoesNotExist</literal> exception will be raised. 如果模板不存在,就触发 <literal>TemplateDoesNotExist</literal> 的异常。 翻译
285#翻译 <literal>django.template.loader.select_template(template_name_list)</literal> : <literal>select_template</literal> is just like <literal>get_template</literal> , except it takes a list of template names. <literal>django.template.loader.select_template(template_name_list)</literal> : <literal>select_template</literal> 很像 <literal>get_template</literal> ,不过它是以模板名称的列表作为参数的。 翻译
286#翻译 Of the list, it returns the first template that exists. 它会返回列表中存在的第一个模板。 翻译
287#翻译 If none of the templates exist, a <literal>TemplateDoesNotExist</literal> exception will be raised. 如果模板都不存在,将会触发<literal>TemplateDoesNotExist</literal>异常。 翻译
289#翻译 As covered in Chapter 4, each of these functions by default uses your <literal>TEMPLATE_DIRS</literal> setting to load templates. 正如在第四章中所提到的,默认情况下这些函数使用 <literal>TEMPLATE_DIRS</literal> 的设置来载入模板。 翻译
290#翻译 Internally, however, these functions actually delegate to a template loader for the heavy lifting. 但是,在内部这些函数可以指定一个模板加载器来完成这些繁重的任务。 翻译
292#翻译 Some of loaders are disabled by default, but you can activate them by editing the <literal>TEMPLATE_LOADERS</literal> setting. 一些加载器默认被禁用,但是你可以通过编辑 <literal>TEMPLATE_LOADERS</literal> 设置来激活它们。 翻译
293#翻译 <literal>TEMPLATE_LOADERS</literal> should be a tuple of strings, where each string represents a template loader. <literal>TEMPLATE_LOADERS</literal> 应当是一个字符串的元组,其中每个字符串都表示一个模板加载器。 翻译
294#翻译 These template loaders ship with Django: 这些模板加载器随Django一起发布。 翻译
296#翻译 <literal>django.template.loaders.filesystem.load_template_source</literal> : This loader loads templates from the filesystem, according to <literal>TEMPLATE_DIRS</literal> . It is enabled by default. <literal>django.template.loaders.filesystem.load_template_source</literal> : 这个加载器根据 <literal>TEMPLATE_DIRS</literal> 的设置从文件系统加载模板。它默认是可用的。 翻译
298#翻译 <literal>django.template.loaders.app_directories.load_template_source</literal> : This loader loads templates from Django applications on the filesystem. <literal>django.template.loaders.app_directories.load_template_source</literal> : 这个加 载器从文件系统上的Django应用中加载模板。 翻译
299#翻译 For each application in <literal>INSTALLED_APPS</literal> , the loader looks for a <literal>templates</literal> subdirectory. 对 <literal>INSTALLED_APPS</literal> 中的每个应用,这个加载器会查找<literal>templates</literal> 子目录。 翻译
300#翻译 If the directory exists, Django looks for templates there. 如果这个目录存在,Django就在那里寻找模板。 翻译
302#翻译 This means you can store templates with your individual applications, making it easy to distribute Django applications with default templates. 这意味着你可以把模板和你的应用一起保存,从而使得Django应用更容易和默认模板一起发布。 翻译
303#翻译 For example, if <literal>INSTALLED_APPS</literal> contains <literal>('myproject.polls', 'myproject.music')</literal> , then <literal>get_template('foo.html')</literal> will look for templates in this order: 例如,如果 <literal>INSTALLED_APPS</literal> 包含 <literal>('myproject.polls','myproject.music')</literal> ,那么 <literal>get_template('foo.html')</literal> 会按这个顺序查找模板: 翻译
305#翻译 <literal>/path/to/myproject/polls/templates/foo.html</literal> <literal>/path/to/myproject/polls/templates/foo.html</literal> 翻译
307#翻译 <literal>/path/to/myproject/music/templates/foo.html</literal> <literal>/path/to/myproject/music/templates/foo.html</literal> 翻译
309#翻译 Note that the loader performs an optimization when it is first imported: 请注意加载器在首次被导入的时候会执行一个优化: 翻译
310#翻译 it caches a list of which <literal>INSTALLED_APPS</literal> packages have a <literal>templates</literal> subdirectory. 它会缓存一个列表,这个列表包含了 <literal>INSTALLED_APPS</literal> 中带有 <literal>templates</literal> 子目录的包。 翻译
312#翻译 This loader is enabled by default. 这个加载器默认启用。 翻译
314#翻译 <literal>django.template.loaders.eggs.load_template_source</literal> : This loader is just like <literal>app_directories</literal> , except it loads templates from Python eggs rather than from the filesystem. <literal>django.template.loaders.eggs.load_template_source</literal> : 这个加载器类似 <literal>app_directories</literal> ,只不过它从Python eggs而不是文件系统中加载模板。 翻译
315#翻译 This loader is disabled by default; you'll need to enable it if youre using eggs to distribute your application. 这个加载器默认被禁用;如果你使用eggs来发布你的应用,那么你就需要启用它。 翻译
316#翻译 (Python eggs are a way of compressing Python code into a single file.) Python eggs可以将Python代码压缩到一个文件中。 翻译
318#翻译 Django uses the template loaders in order according to the <literal>TEMPLATE_LOADERS</literal> setting. Django按照 <literal>TEMPLATE_LOADERS</literal> 设置中的顺序使用模板加载器。 翻译
319#翻译 It uses each loader until a loader finds a match. 它逐个使用每个加载器直至找到一个匹配的模板。 翻译
321#翻译 Extending the Template System 扩展模板系统 翻译
323#翻译 Now that you understand a bit more about the internals of the template system, let's look at how to extend the system with custom code. 既然你已经对模板系统的内幕多了一些了解,让我们来看看如何使用自定义的代码来扩展这个系统吧。 翻译
325#翻译 Most template customization comes in the form of custom template tags and/or filters. 绝大部分的模板定制是以自定义标签/过滤器的方式来完成的。 翻译
326#翻译 Although the Django template language comes with many built-in tags and filters, you'll probably assemble your own libraries of tags and filters that fit your own needs. 尽管Django模板语言自带了许多内建标签和过滤器,但是你可能还是需要组建你自己的标签和过滤器库来满足你的需要。 翻译
327#翻译 Fortunately, it's quite easy to define your own functionality. 幸运的是,定义你自己的功能非常容易。 翻译
329#翻译 Creating a Template Library 创建一个模板库 翻译
331#翻译 Whether you're writing custom tags or filters, the first thing to do is to create a <strong>template library</strong> a small bit of infrastructure Django can hook into. 不管是写自定义标签还是过滤器,第一件要做的事是创建<strong>模板库</strong>(Django能够导入的基本结构)。 翻译
333#翻译 Creating a template library is a two-step process: 创建一个模板库分两步走: 翻译
335#翻译 First, decide which Django application should house the template library. 第一,决定模板库应该放在哪个Django应用下。 翻译
336#翻译 If you've created an app via <literal>manage.py startapp</literal> , you can put it in there, or you can create another app solely for the template library. 如果你通过 <literal>manage.py startapp</literal> 创建了一个应用,你可以把它放在那里,或者你可以为模板库单独创建一个应用。 翻译
337#翻译 We'd recommend the latter, because your filters might be useful to you in future projects. 我们更推荐使用后者,因为你的filter可能在后来的工程中有用。 翻译
339#翻译 Whichever route you take, make sure to add the app to your <literal>INSTALLED_APPS</literal> setting. 无论你采用何种方式,请确保把你的应用添加到 <literal>INSTALLED_APPS</literal> 中。 翻译
340#翻译 We'll explain this shortly. 我们稍后会解释这一点。 翻译
342#翻译 Second, create a <literal>templatetags</literal> directory in the appropriate Django application's package. 第二,在适当的Django应用包里创建一个 <literal>templatetags</literal> 目录。 翻译
343#翻译 It should be on the same level as <literal>models.py</literal> , <literal>views.py</literal> , and so forth. 这个目录应当和 <literal>models.py</literal> 、 <literal>views.py</literal> 等处于同一层次。 翻译
344#翻译 For example: 例如: 翻译
347#翻译 Create two empty files in the <literal>templatetags</literal> directory: 在 <literal>templatetags</literal> 中创建两个空文件: 翻译
348#翻译 an <literal>__init__.py</literal> file (to indicate to Python that this is a package containing Python code) and a file that will contain your custom tag/filter definitions. 一个 <literal>__init__.py</literal> (告诉Python这是 一个包含了Python代码的包)和一个用来存放你自定义的标签/过滤器定义的文件。 翻译
349#翻译 The name of the latter file is what you'll use to load the tags later. 第二个文件的名字稍后将用来加载标签。 翻译
350#翻译 For example, if your custom tags/filters are in a file called <literal>poll_extras.py</literal> , you'd write the following in a template: 例如,如果你的自定义标签/过滤器在一个叫作 <literal>poll_extras.py</literal> 的文件中,你需要在模板中写入如下内容: 翻译
353#翻译 The <literal>{% load %}</literal> tag looks at your <literal>INSTALLED_APPS</literal> setting and only allows the loading of template libraries within installed Django applications. <literal>{% load %}</literal> 标签检查 <literal>INSTALLED_APPS</literal> 中的设置,仅允许加载已安装的Django应用程序中的模板库。 翻译
354#翻译 This is a security feature; it allows you to host Python code for many template libraries on a single computer without enabling access to all of them for every Django installation. 这是一个安全特性;它可以让你在一台电脑上部署很多的模板库的代码,而又不用把它们暴露给每一个Django安装。 翻译
356#翻译 If you write a template library that isn't tied to any particular models/views, its valid and quite normal to have a Django application package that contains only a <literal>templatetags</literal> package. 如果你写了一个不和任何特定模型/视图关联的模板库,那么得到一个仅包含 <literal>templatetags</literal> 包的Django应用程序包是完全正常的。 翻译
357#翻译 There's no limit on how many modules you put in the <literal>templatetags</literal> package. 对于在 <literal>templatetags</literal> 包中放置多少个模块没有做任何的限制。 翻译
358#翻译 Just keep in mind that a <literal>{% load %}</literal> statement will load tags/filters for the given Python module name, not the name of the application. 需要了解的是:<literal>{%load%}</literal>语句是通过指定的Python模块名而不是应用名来加载标签/过滤器的。 翻译
360#翻译 Once you've created that Python module, you'll just have to write a bit of Python code, depending on whether you're writing filters or tags. 一旦创建了Python模块,你只需根据是要编写过滤器还是标签来相应的编写一些Python代码。 翻译
362#翻译 To be a valid tag library, the module must contain a module-level variable named <literal>register</literal> that is an instance of <literal>template.Library</literal> . This is the data structure in which all the tags and filters are registered. 作为合法的标签库,模块需要包含一个名为<literal>register</literal>的模块级变量。这个变量是<literal>template.Library</literal>的实例,是所有注册标签和过滤器的数据结构。 翻译
363#翻译 So, near the top of your module, insert the following: 所以,请在你的模块的顶部插入如下语句: 翻译
366#翻译 Note 注意 翻译
368#翻译 For a fine selection of examples, read the source code for Django's default filters and tags. 请阅读Django默认的过滤器和标签的源码,那里有大量的例子。 翻译
369#翻译 Theyre in <literal>django/template/defaultfilters.py</literal> and <literal>django/template/defaulttags.py</literal> , respectively. 他们分别为: 翻译
370#翻译 Some applications in <literal>django.contrib</literal> also contain template libraries. <literal>django/template/defaultfilters.py</literal> 和 django/template/defaulttags.py 。django.contrib中的某些应用程序也包含模板库。 翻译
372#翻译 Once you've created this <literal>register</literal> variable, you'll use it to create template filters and tags. 创建 <literal>register</literal> 变量后,你就可以使用它来创建模板的过滤器和标签了。 翻译
374#翻译 Writing Custom Template Filters 自定义模板过滤器 翻译
376#翻译 Custom filters are just Python functions that take one or two arguments: 自定义过滤器就是有一个或两个参数的Python函数: 翻译
378#翻译 The value of the variable (input) (输入)变量的值 翻译
380#翻译 The value of the argument, which can have a default value or be left out altogether 参数的值, 可以是默认值或者完全留空 翻译
382#翻译 For example, in the filter <literal>{{ var|foo:&quot;bar&quot; }}</literal> , the filter <literal>foo</literal> would be passed the contents of the variable <literal>var</literal> and the argument <literal>&quot;bar&quot;</literal> . 例如,在过滤器 <literal>{{ var|foo:"bar" }}</literal> 中 ,过滤器 <literal>foo</literal> 会被传入变量 <literal>var</literal> 和默认参数 <literal>bar</literal>。 翻译
384#翻译 Filter functions should always return something. 过滤器函数应该总有返回值。 翻译
385#翻译 They shouldn't raise exceptions, and they should fail silently. 而且不能触发异常,它们都应该静静地失败。 翻译
386#翻译 If there's an error, they should return either the original input or an empty string, whichever makes more sense. 如果出现错误,应该返回一个原始输入或者空字符串,这会更有意义。 翻译
388#翻译 Here's an example filter definition: 这里是一些定义过滤器的例子: 翻译
391#翻译 And here's an example of how that filter would be used to cut spaces from a variable's value: 下面是一个可以用来去掉变量值空格的过滤器例子: 翻译
394#翻译 Most filters don't take arguments. 大多数过滤器并不需要参数。 翻译
395#翻译 In this case, just leave the argument out of your function: 下面的例子把参数从你的函数中拿掉了: 翻译
398#翻译 When you've written your filter definition, you need to register it with your <literal>Library</literal> instance, to make it available to Django's template language: 当你定义完过滤器后,你需要用 <literal>Library</literal> 实例来注册它,这样就能通过Django的模板语言来使用了: 翻译
401#翻译 The <literal>Library.filter()</literal> method takes two arguments: <literal>Library.filter()</literal> 方法需要两个参数: 翻译
403#翻译 The name of the filter (a string) 过滤器的名称(一个字串) 翻译
405#翻译 The filter function itself 过滤器函数本身 翻译
407#翻译 If you're using Python 2.4 or above, you can use <literal>register.filter()</literal> as a decorator instead: 如果你使用的是Python 2.4或者更新的版本,你可以使用装饰器<literal>register.filter()</literal>: 翻译
410#翻译 If you leave off the <literal>name</literal> argument, as in the second example, Django will use the function's name as the filter name. 如果你想第二个例子那样不使用 <literal>name</literal> 参数,那么Django会把函数名当作过滤器的名字。 翻译
412#翻译 Here, then, is a complete template library example, supplying the <literal>cut</literal> filter: 下面是一个完整的模板库的例子,它包含一个 <literal>cut</literal> 过滤器: 翻译
415#翻译 Writing Custom Template Tags 自定义模板标签 翻译
417#翻译 Tags are more complex than filters, because tags can do nearly anything. 标签要比过滤器复杂些,因为标签几乎能做任何事情。 翻译
419#翻译 Chapter 4 describes how the template system works in a two-step process: 第四章描述了模板系统的两步处理过程: 翻译
420#翻译 compiling and rendering. 编译和呈现。 翻译
421#翻译 To define a custom template tag, you need to tell Django how to manage <emphasis>both</emphasis> of these steps when it gets to your tag. 为了自定义一个模板标签,你需要告诉Django当遇到你的标签时怎样进行这个过程。 翻译
423#翻译 When Django compiles a template, it splits the raw template text into <emphasis>nodes</emphasis> . Each node is an instance of <literal>django.template.Node</literal> and has a <literal>render()</literal> method. 当Django编译一个模板时,它将原始模板分成一个个 <emphasis>节点</emphasis> 。每个节点都是 <literal>django.template.Node</literal> 的一个实例,并且具备 <literal>render()</literal> 方法。 翻译
424#翻译 Thus, a compiled template is simply a list of <literal>Node</literal> objects. 于是,一个已编译的模板就是 <literal>节点</literal> 对象的一个列表。 翻译
425#翻译 For example, consider this template: 例如,看看这个模板: 翻译
428#翻译 In compiled template form, this template is represented as this list of nodes: 被编译的模板表现为节点列表的形式: 翻译
430#翻译 Text node: 文本节点: 翻译
431#翻译 <literal>&quot;Hello, &quot;</literal> <literal>"Hello, "</literal> 翻译
433#翻译 Variable node: 变量节点: 翻译
434#翻译 <literal>person.name</literal> <literal>person.name</literal> 翻译
436#翻译 Text node: 文本节点: 翻译
437#翻译 <literal>&quot;.\n\n&quot;</literal> <literal>".\n\n"</literal> 翻译
439#翻译 IfEqual node: IfEqual节点: 翻译
440#翻译 <literal>name.birthday</literal> and <literal>today</literal> <literal>name.birthday</literal>和<literal>today</literal> 翻译
442#翻译 When you call <literal>render()</literal> on a compiled template, the template calls <literal>render()</literal> on each <literal>Node</literal> in its node list, with the given context. 当你调用一个已编译模板的 <literal>render()</literal> 方法时,模板就会用给定的context来调用每个在它的节点列表上的所有节点的 <literal>render()</literal> 方法。 翻译
443#翻译 The results are all concatenated together to form the output of the template. 这些渲染的结果合并起来,形成了模板的输出。 翻译
444#翻译 Thus, to define a custom template tag, you specify how the raw template tag is converted into a <literal>Node</literal> (the compilation function) and what the node's <literal>render()</literal> method does. 因此,要自定义模板标签,你需要指明原始模板标签如何转换成<literal>节点</literal>(编译函数)和节点的<literal>render()</literal>方法完成的功能 。 翻译
446#翻译 In the sections that follow, we cover all the steps in writing a custom tag. 在下面的章节中,我们将详细解说写一个自定义标签时的所有步骤。 翻译
448#翻译 Writing the Compilation Function 编写编译函数 翻译
450#翻译 For each template tag the parser encounters, it calls a Python function with the tag contents and the parser object itself. 当遇到一个模板标签(template tag)时,模板解析器就会把标签包含的内容,以及模板解析器自己作为参数调用一个python函数。 翻译
451#翻译 This function is responsible for returning a <literal>Node</literal> instance based on the contents of the tag. 这个函数负责返回一个和当前模板标签内容相对应的节点(Node)的实例。 翻译
453#翻译 For example, let's write a template tag, <literal>{% current_time %}</literal> , that displays the current date/time, formatted according to a parameter given in the tag, in <literal>strftime</literal> syntax (see <literal>http://www.djangoproject.com/r/python/strftime/</literal> ). It's a good idea to decide the tag syntax before anything else. 例如,写一个显示当前日期的模板标签:{% current_time %}。该标签会根据参数指定的 strftime 格式(参见:<literal>http://www.djangoproject.com/r/python/strftime/</literal>)显示当前时间。首先确定标签的语法是个好主意。 翻译
454#翻译 In our case, let's say the tag should be used like this: 在这个例子里,标签应该这样使用: 翻译
457#翻译 Note 注意 翻译
459#翻译 Yes, this template tag is redundantDjango's default <literal>{% now %}</literal> tag does the same task with simpler syntax. 没错, 这个模板标签是多余的,Django默认的 <literal>{% now %}</literal> 用更简单的语法完成了同样的工作。 翻译
460#翻译 This template tag is presented here just for example purposes. 这个模板标签在这里只是作为一个例子。 翻译
462#翻译 The parser for this function should grab the parameter and create a <literal>Node</literal> object: 这个函数的分析器会获取参数并创建一个 <literal>Node</literal> 对象: 翻译
465#翻译 There's a lot going here: 这里需要说明的地方很多: 翻译
467#翻译 Each template tag compilation function takes two arguments, <literal>parser</literal> and <literal>token</literal> . <literal>parser</literal> is the template parser object. 每个标签编译函数有两个参数,<literal>parser</literal>和<literal>token</literal>。<literal>parser</literal>是模板解析器对象。 翻译
468#翻译 We don't use it in this example. 我们在这个例子中并不使用它。 翻译
469#翻译 <literal>token</literal> is the token currently being parsed by the parser. <literal>token</literal>是正在被解析的语句。 翻译
471#翻译 <literal>token.contents</literal> is a string of the raw contents of the tag. <literal>token.contents</literal> 是包含有标签原始内容的字符串。 翻译
472#翻译 In our example, it's <literal>'current_time &quot;%Y-%m-%d %I:%M %p&quot;'</literal> . 在我们的例子中,它是 <literal>'current_time &quot;%Y-%m-%d %I:%M %p&quot;'</literal> 。 翻译
474#翻译 The <literal>token.split_contents()</literal> method separates the arguments on spaces while keeping quoted strings together. <literal>token.split_contents()</literal> 方法按空格拆分参数同时保证引号中的字符串不拆分。 翻译
475#翻译 Avoid using <literal>token.contents.split()</literal> (which just uses Python's standard string-splitting semantics). 应该避免使用 <literal>token.contents.split()</literal> (仅使用Python的标准字符串拆分)。 翻译
476#翻译 Its not as robust, as it naively splits on <emphasis>all</emphasis> spaces, including those within quoted strings. 它不够健壮,因为它只是简单的按照所有空格进行拆分,包括那些引号引起来的字符串中的空格。 翻译
478#翻译 This function is responsible for raising <literal>django.template.TemplateSyntaxError</literal> , with helpful messages, for any syntax error. 这个函数可以抛出 <literal>django.template.TemplateSyntaxError</literal> ,这个异常提供所有语法错误的有用信息。 翻译
480#翻译 Don't hard-code the tags name in your error messages, because that couples the tag's name to your function. 不要把标签名称硬编码在你的错误信息中,因为这样会把标签名称和你的函数耦合在一起。 翻译
481#翻译 <literal>token.split_contents()[0]</literal> will <emphasis>always</emphasis> be the name of your tag even when the tag has no arguments. <literal>token.split_contents()[0]</literal><emphasis>总是</emphasis>记录标签的名字,就算标签没有任何参数。 翻译
483#翻译 The function returns a <literal>CurrentTimeNode</literal> (which we'll create shortly) containing everything the node needs to know about this tag. 这个函数返回一个 <literal>CurrentTimeNode</literal> (稍后我们将创建它),它包含了节点需要知道的关于这个标签的全部信息。 翻译
484#翻译 In this case, it just passes the argument <literal>&quot;%Y-%m-%d %I:%M %p&quot;</literal> . The leading and trailing quotes from the template tag are removed with <literal>format_string[1:-1]</literal> . 在这个例子中,它只是传递了参数 <literal>&quot;%Y-%m-%d %I:%M %p&quot;</literal> 。模板标签开头和结尾的引号使用 <literal>format_string[1:-1]</literal> 除去。 翻译
486#翻译 Template tag compilation functions <emphasis>must</emphasis> return a <literal>Node</literal> subclass; any other return value is an error. 模板标签编译函数 <emphasis>必须</emphasis> 返回一个 <literal>Node</literal> 子类,返回其它值都是错的。 翻译
488#翻译 Writing the Template Node 编写模板节点 翻译
490#翻译 The second step in writing custom tags is to define a <literal>Node</literal> subclass that has a <literal>render()</literal> method. 编写自定义标签的第二步就是定义一个拥有 <literal>render()</literal> 方法的 <literal>Node</literal> 子类。 翻译
491#翻译 Continuing the preceding example, we need to define <literal>CurrentTimeNode</literal> : 继续前面的例子,我们需要定义 <literal>CurrentTimeNode</literal> : 翻译
494#翻译 These two functions (<literal>__init__()</literal> and <literal>render()</literal> ) map directly to the two steps in template processing (compilation and rendering). 这两个函数( <literal>__init__()</literal> 和 <literal>render()</literal> )与模板处理中的两步(编译与渲染)直接对应。 翻译
495#翻译 Thus, the initialization function only needs to store the format string for later use, and the <literal>render()</literal> function does the real work. 这样,初始化函数仅仅需要存储后面要用到的格式字符串,而 <literal>render()</literal> 函数才做真正的工作。 翻译
497#翻译 Like template filters, these rendering functions should fail silently instead of raising errors. 与模板过滤器一样,这些渲染函数应该静静地捕获错误,而不是抛出错误。 翻译
498#翻译 The only time that template tags are allowed to raise errors is at compilation time. 模板标签只允许在编译的时候抛出错误。 翻译
500#翻译 Registering the Tag 注册标签 翻译
502#翻译 Finally, you need to register the tag with your module's <literal>Library</literal> instance. 最后,你需要用你模块的<literal>Library</literal> 实例注册这个标签。 翻译
503#翻译 Registering custom tags is very similar to registering custom filters (as explained above). 注册自定义标签与注册自定义过滤器非常类似(如前文所述)。 翻译
504#翻译 Just instantiate a <literal>template.Library</literal> instance and call its <literal>tag()</literal> method. 只需实例化一个 <literal>template.Library</literal> 实例然后调用它的 <literal>tag()</literal> 方法。 翻译
505#翻译 For example: 例如: 翻译
508#翻译 The <literal>tag()</literal> method takes two arguments: <literal>tag()</literal> 方法需要两个参数: 翻译
510#翻译 The name of the template tag (string). 模板标签的名字(字符串)。 翻译
512#翻译 The compilation function. 编译函数。 翻译
514#翻译 As with filter registration, it is also possible to use <literal>register.tag</literal> as a decorator in Python 2.4 and above: 和注册过滤器类似,也可以在Python2.4及其以上版本中使用 <literal>register.tag</literal>装饰器: 翻译
517#翻译 If you leave off the <literal>name</literal> argument, as in the second example, Django will use the function's name as the tag name. 如果你像在第二个例子中那样忽略 <literal>name</literal> 参数的话,Django会使用函数名称作为标签名称。 翻译
519#翻译 Setting a Variable in the Context 在上下文中设置变量 翻译
521#翻译 The previous section's example simply returned a value. 前一节的例子只是简单的返回一个值。 翻译
522#翻译 Often it's useful to set template variables instead of returning values. 很多时候设置一个模板变量而非返回值也很有用。 翻译
523#翻译 That way, template authors can just use the variables that your template tags set. 那样,模板作者就只能使用你的模板标签所设置的变量。 翻译
525#翻译 To set a variable in the context, use dictionary assignment on the context object in the <literal>render()</literal> method. 要在上下文中设置变量,在 <literal>render()</literal> 函数的context对象上使用字典赋值。 翻译
526#翻译 Here's an updated version of <literal>CurrentTimeNode</literal> that sets a template variable, <literal>current_time</literal> , instead of returning it: 这里是一个修改过的 <literal>CurrentTimeNode</literal> ,其中设定了一个模板变量 <literal>current_time</literal> ,并没有返回它: 翻译
529#翻译 (We'll leave the creation of a <literal>do_current_time2</literal> function, plus the registration of that function to a <literal>current_time2</literal> template tag, as exercises for the reader.) (我们把创建函数<literal>do_current_time2</literal>和注册给<literal>current_time2</literal>模板标签的工作留作读者练习。) 翻译
531#翻译 Note that <literal>render()</literal> returns an empty string. 注意 <literal>render()</literal> 返回了一个空字符串。 翻译
532#翻译 <literal>render()</literal> should always return a string, so if all the template tag does is set a variable, <literal>render()</literal> should return an empty string. <literal>render()</literal> 应当总是返回一个字符串,所以如果模板标签只是要设置变量, <literal>render()</literal> 就应该返回一个空字符串。 翻译
534#翻译 Here's how youd use this new version of the tag: 你应该这样使用这个新版本的标签: 翻译
537#翻译 But there's a problem with <literal>CurrentTimeNode2</literal> : the variable name <literal>current_time</literal> is hard-coded. 但是 <literal>CurrentTimeNode2</literal> 有一个问题: 变量名 <literal>current_time</literal> 是硬编码的。 翻译
538#翻译 This means you'll need to make sure your template doesn't use <literal>{{ current_time }}</literal> anywhere else, because <literal>{% current_time2 %}</literal> will blindly overwrite that variable's value. 这意味着你必须确定你的模板在其它任何地方都不使用 <literal>{{ current_time }}</literal> ,因为 <literal>{% current_time2 %}</literal> 会盲目的覆盖该变量的值。 翻译
540#翻译 A cleaner solution is to make the template tag specify the name of the variable to be set, like so: 一种更简洁的方案是由模板标签来指定需要设定的变量的名称,就像这样: 翻译
543#翻译 To do so, you'll need to refactor both the compilation function and the <literal>Node</literal> class, as follows: 为此,你需要重构编译函数和 <literal>Node</literal> 类,如下所示: 翻译
546#翻译 Now <literal>do_current_time()</literal> passes the format string and the variable name to <literal>CurrentTimeNode3</literal> . 现在 <literal>do_current_time()</literal> 把格式字符串和变量名传递给 <literal>CurrentTimeNode3</literal> 。 翻译
548#翻译 Parsing Until Another Template Tag 分析直至另一个模板标签 翻译
550#翻译 Template tags can work as blocks containing other tags (like <literal>{% if %}</literal> , <literal>{% for %}</literal> , etc.). 模板标签可以像包含其它标签的块一样工作(想想 <literal>{% if %}</literal> 、 <literal>{% for %}</literal> 等)。 翻译
551#翻译 To create a template tag like this, use <literal>parser.parse()</literal> in your compilation function. 要创建一个这样的模板标签,在你的编译函数中使用 <literal>parser.parse()</literal> 。 翻译
553#翻译 Here's how the standard <literal>{% comment %}</literal> tag is implemented: 标准的 <literal>{% comment %}</literal> 标签是这样实现的: 翻译
556#翻译 <literal>parser.parse()</literal> takes a tuple of names of template tags to parse until. <literal>parser.parse()</literal> 接收一个包含了需要分析的模板标签名的元组作为参数。 翻译
557#翻译 It returns an instance of <literal>django.template.NodeList</literal> , which is a list of all <literal>Node</literal> objects that the parser encountered <emphasis>before</emphasis> it encountered any of the tags named in the tuple. 它返回一个<literal>django.template.NodeList</literal>实例,它是一个包含了所有<emphasis>Node</emphasis>对象的列表,这些对象是解析器在解析到任一元组中指定的标签之前遇到的内容. 翻译
559#翻译 So in the preceding example, <literal>nodelist</literal> is a list of all nodes between <literal>{% comment %}</literal> and <literal>{% endcomment %}</literal> , not counting <literal>{% comment %}</literal> and <literal>{% endcomment %}</literal> themselves. 因此在前面的例子中, <literal>nodelist</literal> 是在 <literal>{% comment %}</literal> 和 <literal>{% endcomment %}</literal> 之间所有节点的列表,不包括 <literal>{% comment %}</literal> 和 <literal>{% endcomment %}</literal> 自身。 翻译
561#翻译 After <literal>parser.parse()</literal> is called, the parser hasn't yet consumed the <literal>{% endcomment %}</literal> tag, so the code needs to explicitly call <literal>parser.delete_first_token()</literal> to prevent that tag from being processed twice. 在 <literal>parser.parse()</literal> 被调用之后,分析器还没有清除 <literal>{% endcomment %}</literal> 标签,因此代码需要显式地调用 <literal>parser.delete_first_token()</literal> 来防止该标签被处理两次。 翻译
563#翻译 Then <literal>CommentNode.render()</literal> simply returns an empty string. 之后 <literal>CommentNode.render()</literal> 只是简单地返回一个空字符串。 翻译
564#翻译 Anything between <literal>{% comment %}</literal> and <literal>{% endcomment %}</literal> is ignored. 在 <literal>{% comment %}</literal> 和 <literal>{% endcomment %}</literal> 之间的所有内容都被忽略。 翻译
566#翻译 Parsing Until Another Template Tag and Saving Contents 分析直至另外一个模板标签并保存内容 翻译
568#翻译 In the previous example, <literal>do_comment()</literal> discarded everything between <literal>{% comment %}</literal> and <literal>{% endcomment %}</literal> . It's also possible to do something with the code between template tags instead. 在前一个例子中, <literal>do_comment()</literal> 抛弃了<literal>{% comment %}</literal> 和 <literal>{% endcomment %}</literal> 之间的所有内容。当然也可以修改和利用下标签之间的这些内容。 翻译
570#翻译 For example, here's a custom template tag, <literal>{% upper %}</literal> , that capitalizes everything between itself and <literal>{% endupper %}</literal> : 例如,这个自定义模板标签<literal>{% upper %}</literal>,它会把它自己和<literal>{% endupper %}</literal>之间的内容变成大写: 翻译
573#翻译 As in the previous example, we'll use <literal>parser.parse()</literal> . This time, we pass the resulting <literal>nodelist</literal> to <literal>Node</literal> : 就像前面的例子一样,我们将使用 <literal>parser.parse()</literal> 。这次,我们将产生的 <literal>nodelist</literal> 传递给 <literal>Node</literal> : 翻译
576#翻译 The only new concept here is <literal>self.nodelist.render(context)</literal> in <literal>UpperNode.render()</literal> . This simply calls <literal>render()</literal> on each <literal>Node</literal> in the node list. 这里唯一的一个新概念是 <literal>UpperNode.render()</literal> 中的 <literal>self.nodelist.render(context)</literal> 。它对节点列表中的每个 <literal>Node</literal> 简单的调用 <literal>render()</literal> 。 翻译
578#翻译 For more examples of complex rendering, see the source code for <literal>{% if %}</literal> , <literal>{% for %}</literal> , <literal>{% ifequal %}</literal> , and <literal>{% ifchanged %}</literal> . They live in <literal>django/template/defaulttags.py</literal> . 更多的复杂渲染示例请查看 <literal>django/template/defaulttags.py</literal> 中的 <literal>{% if %}</literal> 、 <literal>{% for %}</literal> 、 <literal>{% ifequal %}</literal> 和 <literal>{% ifchanged %}</literal> 的代码。 翻译
580#翻译 Shortcut for Simple Tags 简单标签的快捷方式 翻译
582#翻译 Many template tags take a single argument a string or a template variable reference and return a string after doing some processing based solely on the input argument and some external information. 许多模板标签接收单一的字符串参数或者一个模板变量引用,然后独立地根据输入变量和一些其它外部信息进行处理并返回一个字符串。 翻译
583#翻译 For example, the <literal>current_time</literal> tag we wrote earlier is of this variety. 例如,我们先前写的<literal>current_time</literal>标签就是这样一个例子。 翻译
584#翻译 We give it a format string, and it returns the time as a string. 我们给定了一个格式化字符串,然后它返回一个字符串形式的时间。 翻译
586#翻译 To ease the creation of these types of tags, Django provides a helper function, <literal>simple_tag</literal> . This function, which is a method of <literal>django.template.Library</literal> , takes a function that accepts one argument, wraps it in a <literal>render</literal> function and the other necessary bits mentioned previously, and registers it with the template system. 为了简化这类标签,Django提供了一个帮助函数<literal>simple_tag</literal>。这个函数是<literal>django.template.Library</literal>的一个方法,它接受一个只有一个参数的函数作参数,把它包装在render函数和之前提及过的其他的必要单位中,然后通过模板系统注册标签。 翻译
588#翻译 Our earlier <literal>current_time</literal> function could thus be written like this: 我们之前的的 <literal>current_time</literal> 函数于是可以写成这样: 翻译
591#翻译 In Python 2.4, the decorator syntax also works: 在Python 2.4中,也可以使用装饰器语法: 翻译
594#翻译 Notice a couple of things to notice about the <literal>simple_tag</literal> helper function: 有关 <literal>simple_tag</literal> 辅助函数,需要注意下面一些事情: 翻译
596#翻译 Only the (single) argument is passed into our function. 传递给我们的函数的只有(单个)参数。 翻译
598#翻译 Checking for the required number of arguments has already been done by the time our function is called, so we don't need to do that. 在我们的函数被调用的时候,检查必需参数个数的工作已经完成了,所以我们不需要再做这个工作。 翻译
600#翻译 The quotes around the argument (if any) have already been stripped away, so we receive a plain Unicode string. 参数两边的引号(如果有的话)已经被截掉了,所以我们会接收到一个普通Unicode字符串。 翻译
602#翻译 Inclusion Tags 包含标签 翻译
604#翻译 Another common template tag is the type that displays some data by rendering <emphasis>another</emphasis> template. 另外一类常用的模板标签是通过渲染 <emphasis>其他</emphasis> 模板显示数据的。 翻译
605#翻译 For example, Django's admin interface uses custom template tags to display the buttons along the bottom of the add/change form pages. 比如说,Django的后台管理界面,它使用了自定义的模板标签来显示新增/编辑表单页面下部的按钮。 翻译
606#翻译 Those buttons always look the same, but the link targets change depending on the object being edited. 那些按钮看起来总是一样的,但是链接却随着所编辑的对象的不同而改变。 翻译
607#翻译 They're a perfect case for using a small template that is filled with details from the current object. 这就是一个使用小模板很好的例子,这些小模板就是当前对象的详细信息。 翻译
609#翻译 These sorts of tags are called <emphasis>inclusion tags</emphasis> . Writing inclusion tags is probably best demonstrated by example. 这些排序标签被称为 <emphasis>包含标签</emphasis> 。如何写包含标签最好通过举例来说明。 翻译
610#翻译 Let's write a tag that produces a list of books for a given <literal>Author</literal> object. 让我们来写一个能够产生指定<literal>作者</literal>对象的书籍清单的标签。 翻译
611#翻译 We'll use the tag like this: 我们将这样利用标签: 翻译
614#翻译 The result will be something like this: 结果将会像下面这样: 翻译
617#翻译 First, we define the function that takes the argument and produces a dictionary of data for the result. 首先,我们定义一个函数,通过给定的参数生成一个字典形式的结果。 翻译
618#翻译 Notice that we need to return only a dictionary, not anything more complex. 需要注意的是,我们只需要返回字典类型的结果就行了,不需要返回更复杂的东西。 翻译
619#翻译 This will be used as the context for the template fragment: 这将被用来作为模板片段的内容: 翻译
622#翻译 Next, we create the template used to render the tag's output. 接下来,我们创建用于渲染标签输出的模板。 翻译
623#翻译 Following our example, the template is very simple: 在我们的例子中,模板很简单: 翻译
626#翻译 Finally, we create and register the inclusion tag by calling the <literal>inclusion_tag()</literal> method on a <literal>Library</literal> object. 最后,我们通过对一个 <literal>Library</literal> 对象使用 <literal>inclusion_tag()</literal> 方法来创建并注册这个包含标签。 翻译
628#翻译 Following our example, if the preceding template is in a file called <literal>book_snippet.html</literal> , we register the tag like this: 在我们的例子中,如果先前的模板在 <literal>polls/result_snippet.html</literal> 文件中,那么我们这样注册标签: 翻译
631#翻译 Python 2.4 decorator syntax works as well, so we could have written this, instead: Python 2.4装饰器语法也能正常工作,所以我们可以这样写: 翻译
634#翻译 Sometimes, your inclusion tags need access to values from the parent template's context. 有时候,你的包含标签需要访问父模板的context。 翻译
635#翻译 To solve this, Django provides a <literal>takes_context</literal> option for inclusion tags. 为了解决这个问题,Django为包含标签提供了一个 <literal>takes_context</literal> 选项。 翻译
636#翻译 If you specify <literal>takes_context</literal> in creating an inclusion tag, the tag will have no required arguments, and the underlying Python function will have one argument: 如果你在创建模板标签时,指明了这个选项,这个标签就不需要参数,并且下面的Python函数会带一个参数: 翻译
637#翻译 the template context as of when the tag was called. 就是当这个标签被调用时的模板context。 翻译
639#翻译 For example, say you're writing an inclusion tag that will always be used in a context that contains <literal>home_link</literal> and <literal>home_title</literal> variables that point back to the main page. 例如,你正在写一个包含标签,该标签包含有指向主页的 <literal>home_link</literal> 和 <literal>home_title</literal> 变量。 翻译
640#翻译 Here's what the Python function would look like: Python函数会像这样: 翻译
643#翻译 (Note that the first parameter to the function <emphasis>must</emphasis> be called <literal>context</literal> .) (注意函数的第一个参数 <emphasis>必须</emphasis> 是 <literal>context</literal> 。) 翻译
645#翻译 The template <literal>link.html</literal> might contain the following: 模板 <literal>link.html</literal> 可能包含下面的东西: 翻译
648#翻译 Then, anytime you want to use that custom tag, load its library and call it without any arguments, like so: 然后您想使用自定义标签时,就可以加载它的库,然后不带参数地调用它,就像这样: 翻译
651#翻译 Writing Custom Template Loaders 编写自定义模板加载器 翻译
653#翻译 Django's built-in template loaders (described in the Inside Template Loading section above) will usually cover all your template-loading needs, but it's pretty easy to write your own if you need special loading logic. Djangos 内置的模板加载器(在先前的模板加载内幕章节有叙述)通常会满足你的所有的模板加载需求,但是如果你有特殊的加载需求的话,编写自己的模板加载器也会相当简单。 翻译
654#翻译 For example, you could load templates from a database, or directly from a Subversion repository using Subversion's Python bindings, or (as shown shortly) from a ZIP archive. 比如:你可以从数据库中,或者利用Python的绑定直接从Subversion库中,更或者从一个ZIP文档中加载模板。 翻译
656#翻译 A template loader that is, each entry in the <literal>TEMPLATE_LOADERS</literal> setting is expected to be a callable object with this interface: 模板加载器,也就是 <literal>TEMPLATE_LOADERS</literal> 中的每一项,都要能被下面这个接口调用: 翻译
659#翻译 The <literal>template_name</literal> argument is the name of the template to load (as passed to <literal>loader.get_template()</literal> or <literal>loader.select_template()</literal> ), and <literal>template_dirs</literal> is an optional list of directories to search instead of <literal>TEMPLATE_DIRS</literal> . 参数 <literal>template_name</literal> 是所加载模板的名称 (和传递给 <literal>loader.get_template()</literal> 或者 <literal>loader.select_template()</literal> 一样), 而 <literal>template_dirs</literal> 是一个可选的代替<literal>TEMPLATE_DIRS</literal>的搜索目录列表。 翻译
661#翻译 If a loader is able to successfully load a template, it should return a tuple: 如果加载器能够成功加载一个模板, 它应当返回一个元组: 翻译
662#翻译 <literal>(template_source, template_path)</literal> . Here, <literal>template_source</literal> is the template string that will be compiled by the template engine, and <literal>template_path</literal> is the path the template was loaded from. <literal>(template_source, template_path)</literal> 。在这里的 <literal>template_source</literal> 就是将被模板引擎编译的的模板字符串,而 <literal>template_path</literal> 是被加载的模板的路径。 翻译
663#翻译 That path might be shown to the user for debugging purposes, so it should quickly identify where the template was loaded from. 由于那个路径可能会出于调试目的显示给用户,因此它应当很快的指明模板从哪里加载。 翻译
665#翻译 If the loader is unable to load a template, it should raise <literal>django.template.TemplateDoesNotExist</literal> . 如果加载器加载模板失败,那么就会触发 <literal>django.template.TemplateDoesNotExist</literal> 异常。 翻译
667#翻译 Each loader function should also have an <literal>is_usable</literal> function attribute. 每个加载函数都应该有一个名为 <literal>is_usable</literal> 的函数属性。 翻译
668#翻译 This is a Boolean that informs the template engine whether this loader is available in the current Python installation. 这个属性是一个布尔值,用于告知模板引擎这个加载器是否在当前安装的Python中可用。 翻译
669#翻译 For example, the eggs loader (which is capable of loading templates from Python eggs) sets <literal>is_usable</literal> to <literal>False</literal> if the <literal>pkg_resources</literal> module isn't installed, because <literal>pkg_resources</literal> is necessary to read data from eggs. 例如,如果 <literal>pkg_resources</literal> 模块没有安装的话,eggs加载器(它能够从python eggs中加载模板)就应该把 <literal>is_usable</literal> 设为 <literal>False</literal> ,因为必须通过 <literal>pkg_resources</literal> 才能从eggs中读取数据。 翻译
671#翻译 An example should help clarify all of this. 一个例子可以清晰地阐明一切。 翻译
672#翻译 Here's a template loader function that can load templates from a ZIP file. 这儿是一个模板加载函数,它可以从ZIP文件中加载模板。 翻译
673#翻译 It uses a custom setting, <literal>TEMPLATE_ZIP_FILES</literal> , as a search path instead of <literal>TEMPLATE_DIRS</literal> , and it expects each item on that path to be a ZIP file containing templates: 它使用了自定义的设置 <literal>TEMPLATE_ZIP_FILES</literal> 来取代了 <literal>TEMPLATE_DIRS</literal> 用作查找路径,并且它假设在此路径上的每一个文件都是包含模板的ZIP文件: 翻译
676#翻译 The only step left if we want to use this loader is to add it to the <literal>TEMPLATE_LOADERS</literal> setting. 我们要想使用它,还差最后一步,就是把它加入到 <literal>TEMPLATE_LOADERS</literal> 。 翻译
677#翻译 If we put this code in a package called <literal>mysite.zip_loader</literal> , then we add <literal>mysite.zip_loader.load_template_source</literal> to <literal>TEMPLATE_LOADERS</literal> . 如果我们将这个代码放入一个叫mysite.zip_loader的包中,那么我们要把mysite.zip_loader.load_template_source加到TEMPLATE_LOADERS中。 翻译
679#翻译 Configuring the Template System in Standalone Mode 配置独立模式下的模板系统 翻译
681#翻译 Note 注意: 翻译
683#翻译 This section is only of interest to people trying to use the template system as an output component in another application. 这部分只针对于对在其他应用中使用模版系统作为输出组件感兴趣的人。 翻译
684#翻译 If you are using the template system as part of a Django application, the information presented here doesn't apply to you. 如果你是在Django应用中使用模版系统,请略过此部分。 翻译
686#翻译 Normally, Django loads all the configuration information it needs from its own default configuration file, combined with the settings in the module given in the <literal>DJANGO_SETTINGS_MODULE</literal> environment variable. 通常,Django会从它的默认配置文件和由 <literal>DJANGO_SETTINGS_MODULE</literal> 环境变量所指定的模块中加载它需要的所有配置信息。 翻译
687#翻译 (This was explained in A special Python prompt in Chapter 4.) But if you're using the template system independently of the rest of Django, the environment variable approach isn't very convenient, because you probably want to configure the template system in line with the rest of your application rather than dealing with settings files and pointing to them via environment variables. (这点在第四章的"特殊的Python命令提示行"一节解释过。)但是当你想在非Django应用中使用模版系统的时候,采用环境变量并不方便,因为你可能更想同其余的应用一起配置你的模板系统,而不是处理配置文件并通过环境变量指向他们。 翻译
689#翻译 To solve this problem, you need to use the manual configuration option described fully in Appendix D. In a nutshell, you need to import the appropriate pieces of the template system and then, <emphasis>before</emphasis> you call any of the template functions, call <literal>django.conf.settings.configure()</literal> with any settings you wish to specify. 为了解决这个问题,你需要使用附录D中所描述的手动配置选项。概括的说,你需要导入正确的模板中的片段,然后在你访问任一个模板函数之前,首先用你想指定的配置访问Django.conf.settings.configure()。 翻译
691#翻译 You might want to consider setting at least <literal>TEMPLATE_DIRS</literal> (if you are going to use template loaders), <literal>DEFAULT_CHARSET</literal> (although the default of <literal>utf-8</literal> is probably fine) and <literal>TEMPLATE_DEBUG</literal> . All available settings are described in Appendix D, and any setting starting with <literal>TEMPLATE_</literal> is of obvious interest. 你可能会考虑至少要设置 <literal>TEMPLATE_DIRS</literal> (如果你打算使用模板加载器), <literal>DEFAULT_CHARSET</literal> (尽管默认的 <literal>utf-8</literal> 编码相当好用),以及 <literal>TEMPLATE_DEBUG</literal> 。所有可用的选项在附录D中都有详细描述,所有以 <literal>TEMPLATE_</literal> 开头的选项都可能使你感兴趣。 翻译
693#翻译 What's Next 接下来做什么? 翻译
695#翻译 Continuing this section's theme of advanced topics, the <reference name="next chapter" refuri="../chapter10/">next chapter</reference> covers advanced usage of Django models. 延续本章的高级话题,<reference name="next chapter" refuri="../chapter10/">下一章</reference> 会继续讨论Django模版的高级用法。 翻译