在Jinja2中,扩展如何添加自定义过滤器?

时间:2014-08-27 10:12:15

标签: python jinja2

我正在研究Jinja2提供的 jinja2.ext.InternationalizationExtension 的代码。

我知道可以通过标记属性添加标记;当其中一个字符串是{%%}块中的第一个标记时,Jinja2模板解析器将放弃控制并调用用户代码。

class InternationalizationExtension(Extension):
   """This extension adds gettext support to Jinja2."""
    tags = set(['trans'])

我从代码中了解到,扩展可以通过调用 Environment.extend ;向环境添加属性。对于 jinja2.ext.InternationalizationExtension ,这是在 __ init __ 方法中完成的:

def __init__(self, environment):
    Extension.__init__(self, environment)
    environment.globals['_'] = _gettext_alias
    environment.extend(
        install_gettext_translations=self._install,
        install_null_translations=self._install_null,
        install_gettext_callables=self._install_callables,
        uninstall_gettext_translations=self._uninstall,
        extract_translations=self._extract,
        newstyle_gettext=False
    )

我知道通过将功能注册到 Environment.filters 来添加自定义过滤器:

def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
    return value.strftime(format)
environment.filters['datetimeformat'] = datetimeformat

问题是:

  • 是否建议扩展程序添加新的过滤器,而不仅仅是环境中的标记和属性? (documentation表明这应该是常见做法)
  • 扩展子类中应该在哪里完成?在 __ init __ 中,可以使用对环境的引用,因此原则上上面的代码可以放在 __ init __ 方法中。
  • 在概念上可以在 __ init __ 中执行此类操作吗?我个人不喜欢从其他对象的构造函数中改变对象状态,但是在Jinja2中似乎是惯用的,足以使它成为官方扩展(我正在谈论改变 Environment.globals 并调用< strong> Environment.extend 来自 InternationalizationExtension .__ init __ )。

修改

至少包的模式很好地过滤到Python模块中。但是,无法从模板中调用此install函数(例如,通过使用扩展创建的自定义CallBlock),因为在模板实例化后不应编辑环境。

def greet(value):
    return "Hello %s!" % value

def curse(value):
    return "Curse you, %s!" % value

def ohno(value):
    return "Oh, No! %s!" % value

def install(env):
    env.filters['greet'] = greet
    env.filters['curse'] = curse
    env.filters['ohno'] = ohno

1 个答案:

答案 0 :(得分:0)

  

是否建议扩展程序添加新过滤器,而不仅仅是环境中的标记和属性?

只有你需要它们。否则,为什么要使代码过于复杂?过滤器是编写或扩展其他扩展的一个非常常见的用例,作者最有可能将其放在那里因为他们希望这种情况发生。

  

扩展子类中应该在哪里完成?

必须在通话时完成,所以如果你不直接把它放在 __ init __ 中,你需要把它放在一个通过 __ INIT __

  

__ init __ 中做这样的事情在概念上可以吗?

只要您的代码的其他用户能够理解其所做的事情,那就完美了。最简单的解决方案通常是最好的。