笨鸟编程-零基础入门Pyhton教程

 找回密码
 立即注册

扩展

发布者: 笨鸟自学网



示例扩展

下面的例子用 Werkzeug 的缓存 contrib 模块为 Jinja2 实现了一个 cache 标签:

from jinja2 import nodes
from jinja2.ext import Extension


class FragmentCacheExtension(Extension):
    # a set of names that trigger the extension.
    tags = set(['cache'])

    def __init__(self, environment):
        super(FragmentCacheExtension, self).__init__(environment)

        # add the defaults to the environment
        environment.extend(
            fragment_cache_prefix='',
            fragment_cache=None
        )

    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'cache'`` so this will be a name token with
        # `cache` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = parser.stream.next().lineno

        # now we parse a single expression that is used as cache key.
        args = [parser.parse_expression()]

        # if there is a comma, the user provided a timeout.  If not use
        # None as second parameter.
        if parser.stream.skip_if('comma'):
            args.append(parser.parse_expression())
        else:
            args.append(nodes.Const(None))

        # now we parse the body of the cache block up to `endcache` and
        # drop the needle (which would always be `endcache` in that case)
        body = parser.parse_statements(['name:endcache'], drop_needle=True)

        # now return a `CallBlock` node that calls our _cache_support
        # helper method on this extension.
        return nodes.CallBlock(self.call_method('_cache_support', args),
                               [], [], body).set_lineno(lineno)

    def _cache_support(self, name, timeout, caller):
        """Helper callback."""
        key = self.environment.fragment_cache_prefix + name

        # try to load the block from the cache
        # if there is no fragment in the cache, render it and store
        # it in the cache.
        rv = self.environment.fragment_cache.get(key)
        if rv is not None:
            return rv
        rv = caller()
        self.environment.fragment_cache.add(key, rv, timeout)
        return rv

而这是你在环境中使用它的方式:

from jinja2 import Environment
from werkzeug.contrib.cache import SimpleCache

env = Environment(extensions=[FragmentCacheExtension])
env.fragment_cache = SimpleCache()

之后,在模板中可以标记块为可缓存的。下面的例子缓存一个边栏 300 秒:

{% cache 'sidebar', 300 %}
<div class="sidebar">
    ...
</div>
{% endcache %}

扩展 API

扩展总是继承 jinja2.ext.Extension 类:

classjinja2.ext.Extension(environment)

Extensions can be used to add extra functionality to the Jinja template system at the parser level. Custom extensions are bound to an environment but may not store environment specific data on self. The reason for this is that an extension can be bound to another environment (for overlays) by creating a copy and reassigning the environment attribute.

As extensions are created by the environment they cannot accept any arguments for configuration. One may want to work around that by using a factory function, but that is not possible as extensions are identified by their import name. The correct way to configure the extension is storing the configuration values on the environment. Because this way the environment ends up acting as central configuration storage the attributes may clash which is why extensions have to ensure that the names they choose for configuration are not too generic. prefix for example is a terrible name, fragment_cache_prefix on the other hand is a good name as includes the name of the extension (fragment cache).

identifier

扩展的标识符。这始终是扩展类的真实导入名,不能被修改。

tags

如果扩展实现自定义标签,这是扩展监听的标签名的集合。

attr(namelineno=None)

Return an attribute node for the current extension. This is useful to pass constants on extensions to generated template code.

self.attr('_my_attribute', lineno=lineno)
call_method(nameargs=Nonekwargs=Nonedyn_args=Nonedyn_kwargs=Nonelineno=None)

Call a method of the extension. This is a shortcut for attr() jinja2.nodes.Call.

filter_stream(stream)

It’s passed a TokenStream that can be used to filter tokens returned. This method has to return an iterable of Tokens, but it doesn’t have to return a TokenStream.

In the ext folder of the Jinja2 source distribution there is a file called inlinegettext.py which implements a filter that utilizes this method.

parse(parser)

If any of the tags matched this method is called with the parser as first argument. The token the parser stream is pointing at is the name token that matched. This method has to return one or a list of multiple nodes.

preprocess(sourcenamefilename=None)

This method is called before the actual lexing and can be used to preprocess the source. The filename is optional. The return value must be the preprocessed source.


上一篇:模板设计者文档下一篇:集成

Archiver|手机版|笨鸟自学网 ( 粤ICP备20019910号 )

GMT+8, 2024-10-18 19:30 , Processed in 0.071166 second(s), 26 queries .

© 2001-2020

返回顶部