+++ /dev/null
-# -*- coding: utf-8 -*-\r
-"""\r
- jinja.contrib._djangosupport\r
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
-\r
- Django suport layer. This module is a metamodule, do never import it\r
- directly or access any of the functions defined here.\r
-\r
- The public interface is `jinja.contrib.djangosupport` and\r
- `django.contrib.jinja`. See the docstring of `jinja.contrib.djangosupport`\r
- for more details.\r
-\r
- :copyright: 2007-2008 by Armin Ronacher, Bryan McLemore, David Cramer.\r
- :license: BSD, see LICENSE for more details.\r
-"""\r
-import sys\r
-import warnings\r
-import new\r
-from django.conf import settings\r
-from django.template.context import get_standard_processors\r
-from django.http import HttpResponse\r
-from django import contrib\r
-\r
-from jinja import Environment, FileSystemLoader, ChoiceLoader\r
-from jinja.loaders import MemcachedFileSystemLoader\r
-\r
-\r
-exported = ['render_to_response', 'render_to_string', 'convert_django_filter']\r
-\r
-\r
-#: used environment\r
-env = None\r
-\r
-\r
-#: default filters\r
-DEFAULT_FILTERS = (\r
- 'django.template.defaultfilters.date',\r
- 'django.template.defaultfilters.timesince',\r
- 'django.template.defaultfilters.linebreaks',\r
- 'django.contrib.humanize.templatetags.humanize.intcomma'\r
-)\r
-\r
-def configure(convert_filters=DEFAULT_FILTERS, loader=None, **options):\r
- """\r
- Initialize the system.\r
- """\r
- global env\r
-\r
- if env:\r
- warnings.warn("Jinja already initialized.")\r
- return\r
-\r
- # setup environment\r
- if loader is None:\r
- loaders = tuple(FileSystemLoader(l) for l in settings.TEMPLATE_DIRS)\r
- if not loaders:\r
- loader = None\r
- elif len(loaders) == 1:\r
- loader = loaders[0]\r
- else:\r
- loader = ChoiceLoader(loaders)\r
- env = Environment(loader=loader, **options)\r
-\r
- # convert requested filters\r
- for name in convert_filters:\r
- env.filters[name] = convert_django_filter(name)\r
-\r
- # import templatetags of installed apps\r
- for app in settings.INSTALLED_APPS:\r
- try:\r
- __import__(app + '.templatetags')\r
- except ImportError:\r
- pass\r
-\r
- # setup the django.contrib.jinja module\r
- setup_django_module()\r
-\r
-\r
-def setup_django_module():\r
- """\r
- create a new Jinja module for django.\r
- """\r
- from jinja.contrib import djangosupport\r
- module = contrib.jinja = sys.modules['django.contrib.jinja'] = \\r
- new.module('django.contrib.jinja')\r
- module.env = env\r
- module.__doc__ = djangosupport.__doc__\r
- module.register = Library\r
- public_names = module.__all__ = ['register', 'env']\r
- get_name = globals().get\r
- for name in exported:\r
- setattr(module, name, get_name(name))\r
- public_names.append(name)\r
-\r
-\r
-def render_to_response(template, context={}, request=None,\r
- mimetype=None):\r
- """This function will take a few variables and spit out a full webpage."""\r
- content = render_to_string(template, context, request)\r
- if mimetype is None:\r
- mimetype = settings.DEFAULT_CONTENT_TYPE\r
- return HttpResponse(content, mimetype)\r
-\r
-\r
-def render_to_string(template, context={}, request=None):\r
- """Render a template to a string."""\r
- assert env is not None, 'Jinja not configured for django'\r
- if request is not None:\r
- context['request'] = request\r
- for processor in get_standard_processors():\r
- context.update(processor(request))\r
- template = env.get_template(template)\r
- return template.render(context)\r
-\r
-\r
-def convert_django_filter(f):\r
- """Convert a django filter into a Jinja filter."""\r
- if isinstance(f, str):\r
- p = f.split('.')\r
- f = getattr(__import__('.'.join(p[:-1]), None, None, ['']), p[-1])\r
- def filter_factory(*args):\r
- def wrapped(env, ctx, value):\r
- return f(value, *args)\r
- return wrapped\r
- filter_factory.__name__ = f.__name__\r
- filter_factory.__doc__ = getattr(f, '__doc__', None)\r
- return filter_factory\r
-\r
-\r
-class Library(object):\r
- """\r
- Continues a general feel of wrapping all the registration\r
- methods for easy importing.\r
-\r
- This is available in `django.contrib.jinja` as `register`.\r
-\r
- For more details see the docstring of the `django.contrib.jinja` module.\r
- """\r
- def object(func, name=None):\r
- """Register a new global."""\r
- if name is None:\r
- name = getattr(func, '__name__')\r
- env.globals[name] = func\r
- return func\r
- object = staticmethod(object)\r
-\r
- def filter(func, name=None):\r
- """Register a new filter function."""\r
- if name is None:\r
- name = func.__name__\r
- env.filters[name] = func\r
- return func\r
- filter = staticmethod(filter)\r
-\r
- def test(func, name):\r
- """Register a new test function."""\r
- if name is None:\r
- name = func.__name__\r
- env.tests[name] = func\r
- return func\r
- test = staticmethod(test)\r
-\r
- def context_inclusion(func, template, name=None):\r
- """\r
- Similar to the inclusion tag from django this one expects func to be a\r
- function with a similar argument list to func(context, *args, **kwargs)\r
-\r
- It passed in the current context allowing the function to edit it or read\r
- from it. the function must return a dict with which to pass into the\r
- renderer. Normally expected is an altered dictionary.\r
-\r
- Note processors are NOT ran on this context.\r
- """\r
- def wrapper(env, context, *args, **kwargs):\r
- context = func(context.to_dict(), *args, **kwargs)\r
- return render_to_string(template, context)\r
- wrapper.jinja_context_callable = True\r
- if name is None:\r
- name = func.__name__\r
- try:\r
- wrapper.__name__ = func.__name__\r
- wrapper.__doc__ = func.__doc__\r
- except:\r
- pass\r
- env.globals[name] = wrapper\r
- context_inclusion = staticmethod(context_inclusion)\r
-\r
- def clean_inclusion(func, template, name=None, run_processors=False):\r
- """\r
- Similar to above however it won't pass the context into func().\r
- Also the returned context will have the context processors run upon it.\r
- """\r
- def wrapper(env, context, *args, **kwargs):\r
- if run_processors:\r
- request = context['request']\r
- else:\r
- request = None\r
- context = func({}, *args, **kwargs)\r
- return render_to_string(template, context, request)\r
- wrapper.jinja_context_callable = True\r
- if name is None:\r
- name = func.__name__\r
- try:\r
- wrapper.__name__ = func.__name__\r
- wrapper.__doc__ = func.__doc__\r
- except:\r
- pass\r
- env.globals[name] = wrapper\r
- clean_inclusion = staticmethod(clean_inclusion)\r
+++ /dev/null
-# -*- coding: utf-8 -*-
-"""
- jinja.contrib.djangosupport
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Support for the django framework. This module is quite magical because it
- just exports one single function, the `configure` function which is used
- to create a new Jinja environment and setup a special module called
- `django.contrib.jinja` which exports a couple of functions useful for Jinja.
-
- Quickstart
- ==========
-
- To get started execute the following code at the bottom of your settings.py
- or in some general application file such as urls.py or a central module. The
- only thing that matters is that it's executed right *after* the settings
- were set up and *before* `django.contrib.jinja` is imported::
-
- from jinja.contrib import djangosupport
- djangosupport.configure()
-
- What this does is setting up a Jinja environment for this django instance
- with loaders for `TEMPLATE_DIRS` etc. It also converts a couple of default
- django filters such as `date` and `timesince` which are not available in
- Jinja per default. If you want to change the list you can provide others
- by passing a list with filter import names as `convert_filters` keyword
- argument.
-
- All other keyword arguments are forwarded to the environment. If you want
- to provide a loader yourself pass it a loader keyword argument.
-
- Rendering Templates
- ===================
-
- To render a template you can use the functions `render_to_string` or
- `render_to_response` from the `django.contrib.jinja` module::
-
- from django.contrib.jinja import render_to_response
- resp = render_to_response('Hello {{ username }}!', {
- 'username': req.session['username']
- }, req)
-
- `render_to_string` and `render_to_response` take at least the name of
- the template as argument, then the optional dict which will become the
- context. If you also provide a request object as third argument the
- context processors will be applied.
-
- `render_to_response` also takes a forth parameter which can be the
- content type which defaults to `DEFAULT_CONTENT_TYPE`.
-
- Converting Filters
- ==================
-
- One of the useful objects provided by `django.contrib.jinja` is the
- `register` object which can be used to register filters, tests and
- global objects. You can also convert any filter django provides in
- a Jinja filter using `convert_django_filter`::
-
- from django.contrib.jinja import register, convert_django_filter
- from django.template.defaultfilters import floatformat
-
- register.filter(convert_django_filter(floatformat), 'floatformat')
-
- Available methods on the `register` object:
-
- ``object (obj[, name])``
- Register a new global as name or with the object's name.
- Returns the function object unchanged so that you can use
- it as decorator if no name is provided.
-
- ``filter (func[, name])``
- Register a function as filter with the name provided or
- the object's name as filtername.
- Returns the function object unchanged so that you can use
- it as decorator if no name is provided.
-
- ``test (func[, name])``
- Register a function as test with the name provided or the
- object's name as testname.
- Returns the function object unchanged so that you can use
- it as decorator if no name is provided.
-
- ``context_inclusion (func, template[, name])``
- Register a function with a name provided or the func object's
- name in the global namespace that acts as subrender function.
-
- func is called with the callers context as dict and the
- arguments and keywords argument of the inclusion function.
- The function should then process the context and return a
- new context or the same context object. Afterwards the
- template is rendered with this context.
-
- Example::
-
- def add_author(context, author=None):
- if author is not None:
- author = Author.objects.get(name=author)
- context['author'] = author
- return context
-
- register.context_inclusion(add_author, 'author_details.html',
- 'render_author_details')
-
- You can use it in the template like this then::
-
- {{ render_author_details('John Doe') }}
-
- ``clean_inclusion (func, template[, name[, run_processors]]) ``
- Works like `context_inclusion` but doesn't use the calles
- context but an empty context. If `run_processors` is `True`
- it will lookup the context for a `request` object and pass
- it to the render function to apply context processors.
-
- :copyright: 2007 by Armin Ronacher, Bryan McLemore.
- :license: BSD, see LICENSE for more details.
-"""
-try:
- __import__('django')
-except ImportError:
- raise ImportError('installed django required for djangosupport')
-else:
- from jinja.contrib._djangosupport import configure
-
-__all__ = ['configure']