def tag(self, name_or_node=None, compile_function=None, environment={}): """Register a Django template tag (1) or Jinja 2 extension (2). For (1), supports the same invocation syntax as the original Django version, including use as a decorator. For (2), since Jinja 2 extensions are classes (which can't be decorated), and have the tag name effectively built in, only the following syntax is supported: register.tag(MyJinjaExtensionNode) If your extension needs to be configured by setting environment attributes, you can can pass key-value pairs via ``environment``. """ if isinstance(name_or_node, type) and issubclass(name_or_node, Jinja2Extension): if compile_function: raise InvalidTemplateLibrary('"compile_function" argument not supported for Jinja2 extensions') self.jinja2_extensions.append(name_or_node) self.jinja2_environment_attrs.update(environment) return name_or_node else: if environment: raise InvalidTemplateLibrary('"environment" argument not supported for Django tags') return super(Library, self).tag(name_or_node, compile_function)
def object(self, name=None, func=None): def inner(f): name = getattr(f, "_decorated_function", f).__name__ self.jinja2_globals[name] = f return f if name == None and func == None: # @register.object() return inner elif func == None: if (callable(name)): # register.object() return inner(name) else: # @register.object('somename') or @register.object(name='somename') def dec(func): return self.object(name, func) return dec elif name != None and func != None: # register.object('somename', somefunc) self.jinja2_globals[name] = func return func else: raise InvalidTemplateLibrary( "Unsupported arguments to " "Library.object: (%r, %r)", (name, func))
def filter(self, name=None, filter_func=None, type=None, jinja2_only=None): """Register a filter with both the Django and Jinja2 template engines, if possible - or only Jinja2, if ``jinja2_only`` is specified. ``jinja2_only`` does not affect conversion of the filter if neccessary. Implements a compatibility layer to handle the different auto-escaping approaches transparently. Extended Jinja2 filter features like environment- and contextfilters are however not supported in Django. Such filters will only be registered with Jinja. If you know which template language the filter was written for, you may want to specify type="django" or type="jinja2", to disable the interop layer which in some cases might not be able to operate entirely opaque. For example, Jinja 2 filters may not receive a "Undefined" value if the interop layer is applied. Supports the same invocation syntax as the original Django version, including use as a decorator. If the function is supposed to return the registered filter (by example of the superclass implementation), but has registered multiple filters, a tuple of all filters is returned. """ def filter_function(f): return self._register_filter(getattr(f, "_decorated_function", f).__name__, f, type=type, jinja2_only=jinja2_only) if name == None and filter_func == None: # @register.filter() return filter_function elif filter_func == None: if (callable(name)): # @register.filter return filter_function(name) else: # @register.filter('somename') or @register.filter(name='somename') def dec(func): return self.filter(name, func, type=type, jinja2_only=jinja2_only) return dec elif name != None and filter_func != None: # register.filter('somename', somefunc) return self._register_filter(name, filter_func, type=type, jinja2_only=jinja2_only) else: raise InvalidTemplateLibrary( "Unsupported arguments to " "Library.filter: (%r, %r)", (name, filter_func))
def get_library(library_name, app_name=None): """ (Forked from django.template.get_library) Load the template library module with the given name. If library is not already loaded loop over all templatetags modules to locate it. {% load somelib %} and {% load someotherlib %} loops twice. """ #TODO: add in caching. (removed when forked from django.template.get_library). templatetags_modules = get_templatetags_modules() tried_modules = [] best_match_lib = None last_found_lib = None app_name_parts = 0 if app_name: app_name_parts = app_name.count('.') for module in templatetags_modules: taglib_module = '%s.%s' % (module, library_name) tried_modules.append(taglib_module) lib = import_library(taglib_module) if not lib: continue last_found_lib = lib if not app_name: continue module_list = module.split('.') module_list.pop() # remove the last part 'templetags' current_app = '.'.join(module_list) if current_app == app_name: break start = len(module_list) - app_name_parts - 1 if start < 0: continue partial_app = '.'.join(module_list[start:]) if partial_app == app_name: best_match_lib = lib if best_match_lib: last_found_lib = best_match_lib if not last_found_lib: raise InvalidTemplateLibrary( "Template library %s not found, tried %s" % (library_name, ','.join(tried_modules))) return last_found_lib
def load_django_filters(filters, library_names, use_default_filters): from django.template import get_library, import_library if use_default_filters: library = import_library('django.template.defaultfilters') if not library: raise InvalidTemplateLibrary( 'Couldn\'t load django.template.defaultfilters') # Update the dict for filters that don't already exist, i.e # jinja2's built-in filters. filters.update( dict((name, value) for (name, value) in library.filters.iteritems() if name not in filters)) for name in library_names: filters.update(get_library(name).filters)
def import_library(taglib_module): """Load a template tag library module. Verifies that the library contains a 'register' attribute, and returns that attribute as the representation of the library """ app_path, taglib = taglib_module.rsplit('.', 1) app_module = import_module(app_path) try: mod = import_module(taglib_module) except ImportError, e: # If the ImportError is because the taglib submodule does not exist, that's not # an error that should be raised. If the submodule exists and raised an ImportError # on the attempt to load it, that we want to raise. if not module_has_submodule(app_module, taglib): return None else: raise InvalidTemplateLibrary("ImportError raised loading %s: %s" % (taglib_module, e))
def tag(self, name_or_node=None, compile_function=None): """Register a Django template tag (1) or Jinja 2 extension (2). For (1), supports the same invocation syntax as the original Django version, including use as a decorator. For (2), since Jinja 2 extensions are classes (which can't be decorated), and have the tag name effectively built in, only the following syntax is supported: register.tag(MyJinjaExtensionNode) """ if isinstance(name_or_node, Jinja2Extension): if compile_function: raise InvalidTemplateLibrary( '"compile_function" argument not supported for Jinja2 extensions' ) self.jinja2_extensions.append(name_or_node) return name_or_node else: return super(Library, self).tag(name_or_node, compile_function)
app_path, taglib = taglib_module.rsplit('.', 1) app_module = import_module(app_path) try: mod = import_module(taglib_module) except ImportError, e: # If the ImportError is because the taglib submodule does not exist, that's not # an error that should be raised. If the submodule exists and raised an ImportError # on the attempt to load it, that we want to raise. if not module_has_submodule(app_module, taglib): return None else: raise InvalidTemplateLibrary("ImportError raised loading %s: %s" % (taglib_module, e)) try: return mod.register except AttributeError: raise InvalidTemplateLibrary( "Template library %s does not have a variable named 'register'" % taglib_module) def add_to_builtins(module): m = import_library(module) builtins.append(m) #import djinja.template.defaultfunctions add_to_builtins('djinja.template.defaultfunctions') add_to_builtins('djinja.template.defaultextensions') add_to_builtins('djinja.template.defaultfilters') #env = get_env()