def floatformat(value, arg=-1): """Builds on top of Django's own version, but adds strict error checking, staying with the philosophy. """ from django.template.defaultfilters import floatformat from django_cofingo.utils import django_filter_to_jinja2 arg = int(arg) # raise exception result = django_filter_to_jinja2(floatformat)(value, arg) if result == '': # django couldn't handle the value raise ValueError(value) return result
def floatformat(value, arg=-1): """Builds on top of Django's own version, but adds strict error checking, staying with the philosophy. """ from django.template.defaultfilters import floatformat from django_cofingo.utils import django_filter_to_jinja2 arg = int(arg) # raise exception result = django_filter_to_jinja2(floatformat)(value, arg) if result == "": # django couldn't handle the value raise ValueError(value) return result
def _get_options(self): """Generate a dictionary with the extensions, filters, globals, tests and attrs to be set on the Jinja2 environment. The options are added in the following order:: * Django builtin filters * Jinja2 builtin filters, tests, and globals * Cofingo builtin filters, and extensions * Libraries from Django's INSTALLED_APPS (helpers.py) * Filters, extensions, tests and globals from DJANGO_SETTINGS """ from django_cofingo import filters as cofingo_filters from django_cofingo import extensions as cofingo_extensions from django.conf import settings from django.template import builtins as django_builtins from django.core.urlresolvers import get_callable # Note that for extensions, the order in which we load the libraries # is not maintained: https://github.com/mitsuhiko/jinja2/issues#issue/3 # Extensions support priorities, which should be used instead. options = { 'extensions': ['jinja2.ext.with_'], 'filters': {}, 'globals': {}, 'tests': {}, 'attrs': {} } def update_options(library): options['extensions'].extend(library.extensions) options['filters'].update(library.filters) options['globals'].update(library.globals) options['tests'].update(library.tests) options['attrs'].update(library.attrs) # Start with Django's builtins; this give's us all of Django's # filters courtasy of our interop layer. for lib in django_builtins: for name, func in lib.filters.iteritems(): options['filters'][name] = django_filter_to_jinja2(func) # The stuff Jinja2 comes with by default should override Django. options['filters'].update(jinja2.defaults.DEFAULT_FILTERS) options['tests'].update(jinja2.defaults.DEFAULT_TESTS) options['globals'].update(jinja2.defaults.DEFAULT_NAMESPACE) # Our own set of builtins are next, overwriting Jinja2's. update_options(cofingo_filters.library) update_options(cofingo_extensions.library) # Optionally, include the i18n extension. if settings.USE_I18N: options['extensions'].append('jinja2.ext.i18n') # Next, add the globally defined extensions from the settings options['extensions'].extend( list(getattr(settings, 'JINJA2_EXTENSIONS', []))) # Finally, add extensions defined in application's templatetag # libraries for library in self._get_app_libraries(): update_options(library) def from_setting(setting): retval = {} setting = getattr(settings, setting, {}) if isinstance(setting, dict): for key, value in setting.iteritems(): retval[key] = callable(value) and value \ or get_callable(value) else: for value in setting: value = callable(value) and value or get_callable(value) retval[value.__name__] = value return retval options['filters'].update(from_setting('JINJA2_FILTERS')) options['globals'].update(from_setting('JINJA2_GLOBALS')) options['tests'].update(from_setting('JINJA2_TESTS')) for module_name in getattr(settings, 'COFINGO_HELPERS', []): module = import_module(module_name) update_options(module.library) return options