def _load_lib(lib): if not isinstance(lib, CoffinLibrary): # If this is only a standard Django library, # convert it. This will ensure that Django # filters in that library are converted and # made available in Jinja. lib = CoffinLibrary.from_django(lib) extensions.extend(getattr(lib, 'jinja2_extensions', [])) filters.update(getattr(lib, 'jinja2_filters', {})) globals.update(getattr(lib, 'jinja2_globals', {})) tests.update(getattr(lib, 'jinja2_tests', {})) attrs.update(getattr(lib, 'jinja2_environment_attrs', {}))
def _get_templatelibs(self): """Return an iterable of template ``Library`` instances. Since we cannot support the {% load %} tag in Jinja, we have to register all libraries globally. """ from django.conf import settings from django.template import get_library, InvalidTemplateLibrary libs = [] for a in settings.INSTALLED_APPS: try: path = __import__(a + '.templatetags', {}, {}, ['__file__']).__file__ path = os.path.dirname(path) # we now have the templatetags/ directory except ImportError: pass else: for f in os.listdir(path): if f == '__init__.py': continue if f.endswith('.py'): try: # TODO: will need updating when #6587 lands # libs.append(get_library( # "django.templatetags.%s" % os.path.splitext(f)[0])) l = get_library(os.path.splitext(f)[0]) if not isinstance(l, CoffinLibrary): # If this is only a standard Django library, # convert it. This will ensure that Django # filters in that library are converted and # made available in Jinja. l = CoffinLibrary.from_django(l) libs.append(l) except InvalidTemplateLibrary: pass return libs
import urllib import hashlib from django.conf import settings from django.contrib.sites.models import Site from django.utils.translation import get_language_from_request, ugettext if 'coffin' in settings.INSTALLED_APPS: from coffin.template import Library from jinja2 import Markup as mark_safe else: from django.template import Library from django.utils.safestring import mark_safe register = Library() if 'coffin' in settings.INSTALLED_APPS: register.simple_tag = register.object def current_site_url(): """Returns fully qualified URL (no trailing slash) for the current site.""" protocol = getattr(settings, 'MY_SITE_PROTOCOL', 'https') port = getattr(settings, 'MY_SITE_PORT', '') url = '%s://%s' % (protocol, settings.SITE_DOMAIN) if port: url += ':%s' % port return url @register.simple_tag
return "" @contextfilter def context(context, value): return "" def multiarg(value, arg1, arg2): return "" def jinja_forced(value): return "" def django_jinja_forced(value): # a django filter that returns a django-safestring. It will *only* # be added to jinja, and coffin will hopefully ensure the string # stays safe. from django.utils.safestring import mark_safe return mark_safe(value) from coffin.template import Library register = Library() register.filter('environment', environment) register.filter('context', context) register.filter('multiarg', multiarg) register.filter('jinja_forced', jinja_forced, jinja2_only=True) register.filter('django_jinja_forced', django_jinja_forced, jinja2_only=True)
from django import template as django_template from jinja2 import nodes, contextfunction, ext from coffin.template import Library, Template register = Library() class JinjaInclude(django_template.Node): def __init__(self, filename): self.filename = filename def render(self, context): from coffin import shortcuts return shortcuts.render_to_string(self.filename, context) class Jinja(django_template.Node): def __init__(self, template): self.template = template def render(self, context): return self.template.render(context) class DjangoNoop(django_template.Node): def render(self, context): return ''
from django.conf import settings if 'coffin' in settings.INSTALLED_APPS: from jinja2 import nodes, Markup from jinja2.ext import Extension from coffin.template import Library from guide.templatetags.guide_tags import AddGuide, render_guides as origin_render_guides register = Library() class AddGuideExtension(Extension): """ Jinja2-version of the ``render_guides`` tag. """ tags = set(['add_guide']) def parse(self, parser): lineno = parser.stream.next().lineno args = [] while not parser.stream.current.test('block_end'): args.append(parser.parse_expression()) parser.stream.skip_if('comma') return nodes.Output([ self.call_method('_render', [nodes.Name('request', 'load'), nodes.List(args)]), ]).set_lineno(lineno) def _render(self, request, args): if not hasattr(request, 'current_guide_name_list'): request.current_guide_name_list = list()
"""Coffin automatically makes Django's builtin filters available in Jinja2, through an interop-layer. However, Jinja 2 provides room to improve the syntax of some of the filters. Those can be overridden here. TODO: Most of the filters in here need to be updated for autoescaping. """ from coffin.template import Library from jinja2.runtime import Undefined # from jinja2 import Markup from jinja2 import filters register = Library() def url(view_name, *args, **kwargs): """This is an alternative to the {% url %} tag. It comes from a time before Coffin had a port of the tag. """ from coffin.template.defaulttags import url return url._reverse(view_name, args, kwargs) register.jinja2_filter(url, jinja2_only=True) register.object(url) @register.jinja2_filter(jinja2_only=True) def timesince(value, *arg): if value is None or isinstance(value, Undefined): return u'' from django.utils.timesince import timesince return timesince(value, *arg)
""" tags = set(['csrf_token']) def parse(self, parser): lineno = parser.stream.next().lineno return nodes.Output([ self.call_method('_render', [nodes.Name('csrf_token', 'load')]), ]).set_lineno(lineno) def _render(self, csrf_token): from django.template.defaulttags import CsrfTokenNode return Markup(CsrfTokenNode().render({'csrf_token': csrf_token})) # nicer import names load = LoadExtension url = URLExtension with_ = WithExtension cache = CacheExtension spaceless = SpacelessExtension csrf_token = CsrfTokenExtension register = Library() register.tag(load) register.tag(url) register.tag(with_) register.tag(cache) register.tag(spaceless) register.tag(csrf_token)
""" tags = ['spaceless'] def parse(self, parser): lineno = parser.stream.next().lineno body = parser.parse_statements(['name:endspaceless'], drop_needle=True) return nodes.CallBlock( self.call_method('_strip_spaces', [], [], None, None), [], [], body ).set_lineno(lineno) def _strip_spaces(self, caller=None): from django.utils.html import strip_spaces_between_tags return strip_spaces_between_tags(caller().strip()) # nicer import names load = LoadExtension url = URLExtension with_ = WithExtension cache = CacheExtension spaceless = SpacelessExtension register = Library() register.tag(load) register.tag(url) register.tag(with_) register.tag(cache) register.tag(spaceless)
from coffin.template import Library from django.template.loader import render_to_string from jinja2 import nodes from jinja2.ext import Extension register = Library() class MerchantExtension(Extension): tags = set(['render_integration']) def parse(self, parser): stream = parser.stream lineno = stream.next().lineno obj = parser.parse_expression() call_node = self.call_method('render_integration', args=[obj]) return nodes.Output([call_node]).set_lineno(lineno) @classmethod def render_integration(self, obj): form_str = render_to_string(obj.template, {'integration': obj}) return form_str register.tag(MerchantExtension)
"""Register a Django tag with a Coffin library object. """ from django.template import Node class FooNode(Node): def render(self, context): return u'{foo}' def do_foo(parser, token): return FooNode() from coffin.template import Library register = Library() register.tag('foo_coffin', do_foo)
# coding=utf8 from urlparse import urljoin from coffin.template import Library from jinja2.ext import Extension from jinja2 import nodes from django.utils.encoding import iri_to_uri from django.conf import settings from models import StaticFile register = Library() class PrefixExtension(Extension): def parse(self, parser): stream = parser.stream lineno = stream.next().lineno call_node = self.call_method('render') if stream.next_if('name:as'): var = nodes.Name(stream.expect('name').value, 'store') return nodes.Assign(var, call_node).set_lineno(lineno) else: return nodes.Output([call_node]).set_lineno(lineno) def render(self, name): raise NotImplementedError() @classmethod
"""Register a portable filter with a Coffin library object. """ def foo(value): return "{foo}" from coffin.template import Library register = Library() register.filter('foo', foo)
from coffin.template import Library from django_minify import minify from django_minify.conf import settings from django_minify.templatetags import combine from jinja2 import Markup, contextfunction, ext, nodes register = Library() class MinifyExtension(ext.Extension): tags = None template = None extension = None Minifier = None def __init__(self, *args, **kwargs): super(MinifyExtension, self).__init__(*args, **kwargs) assert self.tags, 'Extensions should be linked to one or more tags' assert self.template, ('MinifyExtensions require a template to ' 'render (even "%s" works)') assert self.extension, ('An extension for the output files is ' 'required') assert self.Minifier, 'The extension requires a minifying module' def parse(self, parser): lineno = parser.stream.next().lineno includes = parser.parse_statements(['name:%s' % self.tags[-1]], drop_needle=True) return nodes.CallBlock( self.call_method('_render', [], [], None, None),
from jinja2.ext import do as j2do from jinja2.ext import loopcontrols from jinja2.ext import with_ from coffin.template import Library register = Library() register.tag(j2do) register.tag(loopcontrols) register.tag(with_)
try: from urllib.parse import urljoin except ImportError: # Python 2 from urlparse import urljoin from coffin.template import Library from jinja2.ext import Extension from jinja2 import nodes from django.utils.encoding import iri_to_uri register = Library() class PrefixExtension(Extension): def parse(self, parser): stream = parser.stream lineno = stream.next().lineno call_node = self.call_method('render') if stream.next_if('name:as'): var = nodes.Name(stream.expect('name').value, 'store') return nodes.Assign(var, call_node).set_lineno(lineno) else: return nodes.Output([call_node]).set_lineno(lineno) def render(self, name): raise NotImplementedError()
"""Coffin automatically makes Django's builtin filters available in Jinja2, through an interop-layer. However, Jinja 2 provides room to improve the syntax of some of the filters. Those can be overridden here. TODO: Most of the filters in here need to be updated for autoescaping. """ from coffin.template import Library from jinja2.runtime import Undefined # from jinja2 import Markup from jinja2 import filters register = Library() def url(view_name, *args, **kwargs): """This is an alternative to the {% url %} tag. It comes from a time before Coffin had a port of the tag. """ from coffin.template.defaulttags import url return url._reverse(view_name, args, kwargs) register.jinja2_filter(url, jinja2_only=True) register.object(url) @register.jinja2_filter(jinja2_only=True) def timesince(value, *arg):
def jinja_safe_output(value): return Markup(value) def django_safe_output(value): return mark_safe(value) def unsafe_output(value): return unicode(value) def django_raw_output(value): return value def django_escape_output(value): # Make sure the value is converted to unicode first, because otherwise, # if it is already SafeData (for example, when coming from the template # code), then mark_for_escaping would do nothing. We want to guarantee # a EscapeData return value in this filter though. return mark_for_escaping(unicode(value)) from coffin.template import Library register = Library() register.filter('needing_autoescape', needing_autoescape) register.filter('jinja_safe_output', jinja_safe_output) register.filter('django_safe_output', django_safe_output) register.filter('django_raw_output', django_raw_output) register.filter('unsafe_output', unsafe_output) register.filter('django_escape_output', django_escape_output)
from coffin.template import Library from django.contrib.staticfiles.storage import staticfiles_storage from coffin.templatetags.static import StaticExtension as CoffinStaticExtension register = Library() class StaticExtension(CoffinStaticExtension): """Implements the {% static %} tag as provided by the ``staticfiles`` contrib module. Returns the URL to a file using staticfiles' storage backend. Usage:: {% static path [as varname] %} Examples:: {% static "myapp/css/base.css" %} {% static variable_with_path %} {% static "myapp/css/base.css" as admin_base_css %} {% static variable_with_path as varname %} """ @classmethod def get_static_url(cls, path): return super(StaticExtension, cls).get_static_url( staticfiles_storage.url(path))
"""Register a Jinja2 global object with a Coffin library object. """ def hello_func(name): return u"Hello %s" % name from coffin.template import Library register = Library() register.object('hello', hello_func)
"""Register a Jinja2 extension with a Coffin library object. """ from jinja2.ext import Extension from jinja2 import nodes class FooExtension(Extension): tags = set(['foo']) def parse(self, parser): parser.stream.next() return nodes.Const('{foo}') class FooWithConfigExtension(Extension): tags = set(['foo_ex']) def __init__(self, environment): Extension.__init__(self, environment) environment.extend( foo_custom_output='foo', ) def parse(self, parser): parser.stream.next() return nodes.Const('{%s}' % self.environment.foo_custom_output) from coffin.template import Library register = Library() register.tag(FooExtension) register.tag(FooWithConfigExtension, environment={'foo_custom_output': 'my_foo'})
"""Makes the template filters from the ``django.contrib.markup`` app available to both the Jinja2 and Django engines. In other words, adding ``coffin.contrib.markup`` to your INSTALLED_APPS setting will enable the markup filters not only through Coffin, but also through the default Django template system. """ from coffin.template import Library as CoffinLibrary from django.contrib.markup.templatetags.markup import register # Convert Django's Library into a Coffin Library object, which will # make sure the filters are correctly ported to Jinja2. register = CoffinLibrary.from_django(register)
from jinja2 import environmentfilter, contextfilter @environmentfilter def environment(environment, value): return "" @contextfilter def context(context, value): return "" def multiarg(value, arg1, arg2): return "" def jinja_forced(value): return "" def django_jinja_forced(value): # a django filter that returns a django-safestring. It will *only* # be added to jinja, and coffin will hopefully ensure the string # stays safe. from django.utils.safestring import mark_safe return mark_safe(value) from coffin.template import Library register = Library() register.filter('environment', environment) register.filter('context', context) register.filter('multiarg', multiarg) register.filter('jinja_forced', jinja_forced, jinja2_only=True) register.filter('django_jinja_forced', django_jinja_forced, jinja2_only=True)
tags = set(['csrf_token']) def parse(self, parser): lineno = parser.stream.next().lineno return nodes.Output([ self.call_method('_render', [nodes.Name('csrf_token', 'load')]), ]).set_lineno(lineno) def _render(self, csrf_token): from django.template.defaulttags import CsrfTokenNode return Markup(CsrfTokenNode().render({'csrf_token': csrf_token})) # nicer import names load = LoadExtension url = URLExtension with_ = WithExtension cache = CacheExtension spaceless = SpacelessExtension csrf_token = CsrfTokenExtension register = Library() register.tag(load) register.tag(url) register.tag(with_) register.tag(cache) register.tag(spaceless) register.tag(csrf_token)
return Markup(value) def django_safe_output(value): return mark_safe(value) def unsafe_output(value): return unicode(value) def django_raw_output(value): return value def django_escape_output(value): # Make sure the value is converted to unicode first, because otherwise, # if it is already SafeData (for example, when coming from the template # code), then mark_for_escaping would do nothing. We want to guarantee # a EscapeData return value in this filter though. return mark_for_escaping(unicode(value)) from coffin.template import Library register = Library() register.filter('needing_autoescape', needing_autoescape) register.filter('jinja_safe_output', jinja_safe_output) register.filter('django_safe_output', django_safe_output) register.filter('django_raw_output', django_raw_output) register.filter('unsafe_output', unsafe_output) register.filter('django_escape_output', django_escape_output)
"""Register a Jinja2 extension with a Coffin library object. """ from jinja2.ext import Extension from jinja2 import nodes class FooExtension(Extension): tags = set(['foo']) def parse(self, parser): parser.stream.next() return nodes.Const('{foo}') from coffin.template import Library register = Library() register.tag(FooExtension)
if self.use_pdb: pdb_with_context(context) else: setup_readline_history() run_shell(context) return '' @register.tag def repl(parser, token): use_pdb = False bits = token.contents.split() if len(bits) > 1: if bits[1] == 'pdb': use_pdb = True else: raise TemplateSyntaxError('The second argument to the "repl" tag, if present, must be "pdb".') return REPLNode(use_pdb) try: from coffin.template import Library as CoffinLibrary import coffin.common except ImportError: pass else: # We could simply create a Coffin library in the first place, # of course, but this allows us to more easily maintain this # change as a fork. from template_repl.jinja2_ext import REPLExtension register = CoffinLibrary.from_django(register) register.tag(REPLExtension)
filters = value warnings.warn('The "filter" option of the {% assets %} ' 'template tag has been renamed to ' '"filters" for consistency reasons.', ImminentDeprecationWarning) # positional arguments are source files elif name is None: files.append(value) else: raise template.TemplateSyntaxError('Unsupported keyword argument "%s"'%name) # capture until closing tag childnodes = parser.parse(("endassets",)) parser.delete_first_token() return AssetsNode(filters, output, files, childnodes) # If Coffin is installed, expose the Jinja2 extension try: from coffin.template import Library as CoffinLibrary except ImportError: register = template.Library() else: register = CoffinLibrary() from webassets.ext.jinja2 import AssetsExtension from django_assets.env import get_env register.tag(AssetsExtension, environment={'assets_environment': get_env()}) # expose the default Django tag register.tag('assets', assets)
# handle known keyword arguments if name == 'output': output = value elif name == 'filter': filter = value # positional arguments are source files elif name is None: files.append(value) else: raise template.TemplateSyntaxError('Unsupported keyword argument "%s"'%name) # capture until closing tag childnodes = parser.parse(("endassets",)) parser.delete_first_token() return AssetsNode(filter, output, files, childnodes) # if Coffin is installed, expose the Jinja2 extension try: from coffin.template import Library as CoffinLibrary except ImportError: register = template.Library() else: register = CoffinLibrary() from django_assets.jinja2.extension import AssetsExtension register.tag(AssetsExtension) # expose the default Django tag register.tag('assets', assets)
try: from urllib.parse import urljoin except ImportError: # Python 2 from urlparse import urljoin from coffin.template import Library from jinja2.ext import Extension from jinja2 import nodes from django.utils.encoding import iri_to_uri register = Library() class PrefixExtension(Extension): def parse(self, parser): stream = parser.stream lineno = stream.next().lineno call_node = self.call_method('render') if stream.next_if('name:as'): var = nodes.Name(stream.expect('name').value, 'store') return nodes.Assign(var, call_node).set_lineno(lineno) else: return nodes.Output([call_node]).set_lineno(lineno) def render(self, name): raise NotImplementedError() @classmethod def get_uri_setting(cls, name):
import math import urllib from coffin.template import Library register = Library() @register.object(name='widthratio') def widthratio(min=0, max=100, range=100): return int(math.ceil(float(float(min) / float(max) * int(range)))) @register.object(name='query') def query_string(**kwargs): query = urllib.urlencode(kwargs) return '?%s' % (query if kwargs else '') @register.filter(name='markdown') def parse_markdown(value, format="html5"): import markdown return markdown.markdown(value, safe_mode='escape', output_format=format)
from coffin.template import Library register = Library() register.object(ord) register.object(chr)
import urllib import hashlib from django.conf import settings from django.contrib.sites.models import Site from django.utils.translation import get_language_from_request, ugettext if 'coffin' in settings.INSTALLED_APPS: from coffin.template import Library from jinja2 import Markup as mark_safe else: from django.template import Library from django.utils.safestring import mark_safe register = Library() if 'coffin' in settings.INSTALLED_APPS: register.simple_tag = register.object def current_site_url(): """Returns fully qualified URL (no trailing slash) for the current site.""" protocol = getattr(settings, 'MY_SITE_PROTOCOL', 'https') port = getattr(settings, 'MY_SITE_PORT', '') url = '%s://%s' % (protocol, settings.SITE_DOMAIN) if port: url += ':%s' % port return url
ImminentDeprecationWarning) elif name == 'depends': depends = value # positional arguments are source files elif name is None: files.append(value) else: raise template.TemplateSyntaxError( 'Unsupported keyword argument "%s"' % name) # capture until closing tag childnodes = parser.parse(("endassets", )) parser.delete_first_token() return AssetsNode(filters, depends, output, debug, files, childnodes) # If Coffin is installed, expose the Jinja2 extension try: from coffin.template import Library as CoffinLibrary except ImportError: register = template.Library() else: register = CoffinLibrary() from webassets.ext.jinja2 import AssetsExtension from django_assets.env import get_env register.tag(AssetsExtension, environment={'assets_environment': get_env()}) # expose the default Django tag register.tag('assets', assets)
from coffin.template import Library from django_minify import minify from django_minify.conf import settings from django_minify.templatetags import combine from jinja2 import Markup, contextfunction, ext, nodes register = Library() def urljoin(*args): """ Joins given arguments into a url. Trailing but not leading slashes are stripped for each argument. """ return "/".join(map(lambda x: str(x).rstrip('/'), args)) class MinifyExtension(ext.Extension): tags = None template = None extension = None Minifier = None def __init__(self, *args, **kwargs): super(MinifyExtension, self).__init__(*args, **kwargs) assert self.tags, 'Extensions should be linked to one or more tags' assert self.template, ('MinifyExtensions require a template to ' 'render (even "%s" works)') assert self.extension, ('An extension for the output files is ' 'required') assert self.Minifier, 'The extension requires a minifying module'