jinja2API五:异常、自定义过滤器、上下文、低层API
异常
- exception jinja2.TemplateError(message=None)
-
Baseclass for all template errors.
- exception jinja2.UndefinedError(message=None)
-
Raised if a template tries to operate on Undefined.
- exception jinja2.TemplateNotFound(name, message=None)
-
Raised if a template does not exist.
- exception jinja2.TemplatesNotFound(names=(), message=None)
-
Like TemplateNotFound but raised if multiple templates are selected. This is a subclass of TemplateNotFound exception, so just catching the base exception will catch both.
New in version 2.2.
- exception jinja2.TemplateSyntaxError(message, lineno, name=None, filename=None)
-
Raised to tell the user that there is a problem with the template.
- message
-
错误信息的 utf-8 字节串。
- lineno
-
发生错误的行号。
- name
-
模板的加载名的 unicode 字符串。
- filename
-
加载的模板的文件名字节串,以文件系统的编码(多是 utf-8 , Windows 是 mbcs )。
文件名和错误消息是字节串而不是 unicode 字符串的原因是,在 Python 2.x 中,不对异常和回溯使用 unicode ,编译器同样。这会在 Python 3 改变。
- exception jinja2.TemplateAssertionError(message, lineno, name=None, filename=None)
-
Like a template syntax error, but covers cases where something in the template caused an error at compile time that wasn’t necessarily caused by a syntax error. However it’s a direct subclass of TemplateSyntaxError and has the same attributes.
自定义过滤器
自定义过滤器只是常规的 Python 函数,过滤器左边作为第一个参数,其余的参数作 为额外的参数或关键字参数传递到过滤器。
例如在过滤器 {{ 42|myfilter(23) }} 中,函数被以 myfilter(42, 23) 调 用。这里给出一个简单的过滤器示例,可以应用到 datetime 对象来格式化它们:
def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
return value.strftime(format)
你可以更新环境上的 filters 字典来把它注册到模板环境上:
environment.filters['datetimeformat'] = datetimeformat
在模板中使用如下:
written on: {{ article.pub_date|datetimeformat }}
publication date: {{ article.pub_date|datetimeformat('%d-%m-%Y') }}
也可以传给过滤器当前模板上下文或环境。当过滤器要返回一个未定义值或检查当前的autoescape 设置时很有用。为此,有三个装饰器: environmentfilter() 、 contextfilter() 和 evalcontextfilter() 。
这里是一个小例子,过滤器把一个文本在 HTML 中换行或分段,并标记返回值为安全 的 HTML 字符串,因为自动转义是启用的:
import re
from jinja2 import evalcontextfilter, Markup, escape
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
@evalcontextfilter
def nl2br(eval_ctx, value):
result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
for p in _paragraph_re.split(escape(value)))
if eval_ctx.autoescape:
result = Markup(result)
return result
上下文过滤器工作方式相同,只是第一个参数是当前活动的 Context 而 不是环境。
求值上下文
求值上下文(缩写为 eval context 或 eval ctx )是 Jinja 2.4 中引入的新对象, 并可以在运行时激活/停用已编译的特性。
当前它只用于启用和禁用自动转义,但也可以用于扩展。
在之前的 Jinja 版本中,过滤器和函数被标记为环境可调用的来从环境中检查自动 转义的状态。在新版本中鼓励通过求值上下文来检查这个设定。
之前的版本:
@environmentfilter
def filter(env, value):
result = do_something(value)
if env.autoescape:
result = Markup(result)
return result
在新版本中,你可以用 contextfilter() 从实际的上下文中访问求值上下 文,或用 evalcontextfilter() 直接把求值上下文传递给函数:
@contextfilter
def filter(context, value):
result = do_something(value)
if context.eval_ctx.autoescape:
result = Markup(result)
return result
@evalcontextfilter
def filter(eval_ctx, value):
result = do_something(value)
if eval_ctx.autoescape:
result = Markup(result)
return result
求值上下文一定不能在运行时修改。修改只能在扩展中的 用 nodes.EvalContextModifier和 nodes.ScopedEvalContextModifier 发生,而不是通过求值上下文对 象本身。
- class jinja2.nodes.EvalContext(environment, template_name=None)
-
Holds evaluation time information. Custom attributes can be attached to it in extensions.
- autoescape
-
True 或 False 取决于自动转义是否激活。
- volatile
-
如果编译器不能在编译期求出某些表达式的值,为 True 。在运行时应该 始终为 False 。
自定义测试
测试像过滤器一样工作,只是测试不能访问环境或上下文,并且它们不能链式使用。 测试的返回值应该是 True 或 False 。测试的用途是让模板设计者运行类型和 一致性检查。
这里是一个简单的测试,检验一个变量是否是素数:
import math
def is_prime(n):
if n == 2:
return True
for i in xrange(2, int(math.ceil(math.sqrt(n))) + 1):
if n % i == 0:
return False
return True
你可以通过更新环境上的 tests 字典来注册它:
environment.tests['prime'] = is_prime
模板设计者可以在之后这样使用测试:
{% if 42 is prime %}
42 is a prime number
{% else %}
42 is not a prime number
{% endif %}
全局命名空间
Environment.globals 字典中的变量是特殊的,它们对导入的模板也是可用的, 即使它们不通过上下文导入。这是你可以放置始终可访问的变量和函数的地方。此外,Template.globals 是那些对特定模板可用的变量,即对所有的 render() 调用可用。
低层 API
低层 API 暴露的功能对理解一些实现细节、调试目的或高级 扩展 技巧是有用的。除非你准确地了解你在做什么,否则 不推荐使用这些 API 。
- Environment.lex(source, name=None, filename=None)
-
Lex the given sourcecode and return a generator that yields tokens as tuples in the form (lineno, token_type, value). This can be useful for extension developmentand debugging templates.
This does not perform preprocessing. If you want the preprocessing of the extensions to be applied you have to filter source through the preprocess() method.
- Environment.parse(source, name=None, filename=None)
-
Parse the sourcecode and return the abstract syntax tree. This tree of nodes is used by the compiler to convert the template into executable source- or bytecode. This is useful for debugging or to extract information from templates.
If you are developing Jinja2 extensions this gives you a good overview of the node tree generated.
- Environment.preprocess(source, name=None, filename=None)
-
Preprocesses the source with all extensions. This is automatically called for all parsing and compiling methods but not for lex() because there you usually only want the actual source tokenized.
- Template.new_context(vars=None, shared=False, locals=None)
-
Create a new Context for this template. The vars provided will be passed to the template. Per default the globals are added to the context. If shared is set to Truethe data is passed as it to the context without adding the globals.
locals can be a dict of local variables for internal usage.
- Template.root_render_func(context)
-
这是低层的渲染函数。它接受一个必须由相同模板或兼容的模板的 new_context() 创建的 Context 。这个渲染函数由编译器从 模板代码产生,并返回一个生产 unicode 字符串的生成器。
如果模板代码中发生了异常,模板引擎不会重写异常而是直接传递原始的异常。 事实上,这个函数只在 render() / generate() / stream() 的调用里被调用。
- Template.blocks
-
一个块渲染函数的字典。其中的每个函数与 root_render_func() 的工作 相同,并且有相同的限制。
- Template.is_up_to_date
-
如果有可用的新版本模板,这个属性是 False ,否则是 True 。
注意
低层 API 是易碎的。未来的 Jinja2 的版本将不会试图以不向后兼容的方式修改它, 而是在 Jinja2 核心的修改中表现出来。比如如果 Jinja2 在之后的版本中引入一 个新的 AST 节点,它会由 parse() 返回。
元 API
New in version 2.2.
元 API 返回一些关于抽象语法树的信息,这些信息能帮助应用实现更多的高级模板概 念。所有的元 API 函数操作一个 Environment.parse() 方法返回的抽象语法 树。
- jinja2.meta.find_undeclared_variables(ast)
-
Returns a set of all variables in the AST that will be looked up from the context at runtime. Because at compile time it’s not known which variables will be used depending on the path the execution takes at runtime, all variables are returned.
>>> from jinja2 import Environment, meta >>> env = Environment() >>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}') >>> meta.find_undeclared_variables(ast) set(['bar'])
Implementation
Internally the code generator is used for finding undeclared variables. This is good to know because the code generator might raise a TemplateAssertionError during compilation and as a matter of fact this function can currently raise that exception as well.
- jinja2.meta.find_referenced_templates(ast)
-
Finds all the referenced templates from the AST. This will return an iterator over all the hardcoded template extensions, inclusions and imports. If dynamic inheritance or inclusion is used, None will be yielded.
>>> from jinja2 import Environment, meta >>> env = Environment() >>> ast = env.parse('{% extends "layout.html" %}{% include helper %}') >>> list(meta.find_referenced_templates(ast)) ['layout.html', None]
This function is useful for dependency tracking. For example if you want to rebuild parts of the website after a layout template has changed.
posted on 2015-08-01 17:41 myworldworld 阅读(237) 评论(0) 收藏 举报