more updates on the extension API
--HG--
branch : trunk
diff --git a/jinja2/ext.py b/jinja2/ext.py
index 22adf82..f60b85a 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -40,6 +40,17 @@
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).
"""
__metaclass__ = ExtensionRegistry
@@ -74,49 +85,40 @@
return nodes.ExtensionAttribute(self.identifier, name, lineno=lineno)
-class CacheExtension(Extension):
- """An example extension that adds cacheable blocks."""
- tags = set(['cache'])
-
- def __init__(self, environment):
- Extension.__init__(self, environment)
- environment.globals['__cache_ext_support'] = self.cache_support
-
- def cache_support(self, name, timeout, caller):
- """Helper for the cache_fragment function."""
- if not hasattr(environment, 'cache_support'):
- return caller()
- args = [name]
- if timeout is not None:
- args.append(timeout)
- return self.environment.cache_support(generate=caller, *args)
-
- def parse(self, parser):
- lineno = parser.stream.next().lineno
- args = [parser.parse_expression()]
- if parser.stream.current.type is 'comma':
- parser.stream.next()
- args.append(parser.parse_expression())
- else:
- args.append(nodes.Const(None, lineno=lineno))
- body = parser.parse_statements(('name:endcache',), drop_needle=True)
- return nodes.CallBlock(
- nodes.Call(nodes.Name('__cache_ext_support', 'load', lineno=lineno),
- args, [], None, None), [], [], body, lineno=lineno
- )
-
-
class InternationalizationExtension(Extension):
- """This extension adds gettext support to Jinja."""
+ """This extension adds gettext support to Jinja2."""
tags = set(['trans'])
def __init__(self, environment):
Extension.__init__(self, environment)
- environment.globals.update({
- '_': contextfunction(lambda c, x: c['gettext'](x)),
- 'gettext': lambda x: x,
- 'ngettext': lambda s, p, n: (s, p)[n != 1]
- })
+ environment.globals['_'] = contextfunction(lambda c, x: c['gettext'](x))
+ environment.extend(
+ install_gettext_translations=self._install,
+ install_null_translations=self._install_null,
+ uninstall_gettext_translations=self._uninstall,
+ extract_translations=self._extract
+ )
+
+ def _install(self, translations):
+ self.environment.globals.update(
+ gettext=translations.ugettext,
+ ngettext=translations.ungettext
+ )
+
+ def _install_null(self):
+ self.environment.globals.update(
+ gettext=lambda x: x,
+ ngettext=lambda s, p, n: (n != 1 and (p,) or (s,))[0]
+ )
+
+ def _uninstall(self, translations):
+ for key in 'gettext', 'ngettext':
+ self.environment.globals.pop(key, None)
+
+ def _extract(self, source, gettext_functions=GETTEXT_FUNCTIONS):
+ if isinstance(source, basestring):
+ source = self.environment.parse(source)
+ return extract_from_ast(source, gettext_functions)
def parse(self, parser):
"""Parse a translatable tag."""
@@ -132,7 +134,7 @@
parser.stream.expect('comma')
# skip colon for python compatibility
- if parser.ignore_colon():
+ if parser.skip_colon():
break
name = parser.stream.expect('name')