Login

integrated jinja2 which could use generic view ,my djangojinja2.py

Author:
jasongreen
Posted:
December 29, 2009
Language:
Python
Version:
1.1
Score:
0 (after 0 ratings)

I tried a few snippets of integrated jinja2 in django, which provided ?.render_to_string and ?.render_to_response in the way of jinja2. But those snippets could not use the generic view, because of the generic views is use default django template. so i write this snippet which could use generic view, and use the basic django.shortcuts.render_to_string, django.shortcuts.render_to_string.

in yourproject/urls.py :

install default environment is very simple

djangojinja2.install()

install environment of specified Environment class

from jinja2.sandbox import SandboxedEnvironment
djangojinja2.install(SandboxedEnvironment)

alternative you can install sepcified environment

env=Environment(...)
...
djangojinja2.install(env)

something could be set in settings.py

TEMPLATE_DIRS = (path.join(path.dirname(__file__),"templates"),)
JINJA_GLOBALS=['myapp.myutil.foo',]
JINJA_FILTERS=['django.template.defaultfilters.date',]
JINJA_TESTS=('foo.mytest',)
JINJA_EXTS=['jinja2.ext.i18n']

there is no change need for app.views

from django.shortcuts import render_to_response
def foo(request):
    return render_to_response('/myjinja2.html',{'request':request})

test in django development version of r12026 , jinja2 2.2.1, python 2.5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# coding:utf-8
'''
Created on 2009-12-30

@author: Jason Green
@author-email: [email protected]
'''
from jinja2 import Environment
from django.conf import settings

def _new_env(env_class):
    from jinja2 import PackageLoader, ChoiceLoader, FileSystemLoader
    loader_array = []
    for pth in getattr(settings, 'TEMPLATE_DIRS', ()):
        loader_array.append(FileSystemLoader(pth))
    
    for app in settings.INSTALLED_APPS:
        loader_array.append(PackageLoader(app))
    
    # Setup environment
    global_exts = getattr(settings, 'JINJA_EXTS', ())
    env = object.__new__(env_class)
    env_class.__init__(env,extensions=global_exts, loader=ChoiceLoader(loader_array))
    return env
    
def _init_env(env):
    from django.core.urlresolvers import get_callable
    from django.utils import translation
    global_exts = getattr(settings, 'JINJA_EXTS', ())
    if 'jinja2.ext.i18n' in global_exts:
        env.install_gettext_translations(translation)
    
    # Add user Globals, Filters, Tests
    global_imports = getattr(settings, 'JINJA_GLOBALS', ())
    for imp in global_imports:
        method = get_callable(imp)
        method_name = getattr(method,'jinja_name',None)
        if not method_name == None:
            env.globals[method_name] = method
        else:
            env.globals[method.__name__] = method
    env.globals['settings'] = settings
    env.globals['get_language'] = translation.get_language
    env.globals['get_language_bidi'] = translation.get_language_bidi
    
    import datetime
    env.globals['datetime'] = datetime
    
    global_filters = getattr(settings, 'JINJA_FILTERS', ())
    for imp in global_filters:
        method = get_callable(imp)
        method_name = getattr(method,'jinja_name',None)
        if not method_name == None:
            env.filters[method_name] = method
        else:
            env.filters[method.__name__] = method
    
    global_tests = getattr(settings, 'JINJA_TESTS', ())
    for imp in global_tests:
        method = get_callable(imp)
        method_name = getattr(method,'jinja_name',None)
        if not method_name == None:
            env.tests[method_name] = method
        else:
            env.tests[method.__name__] = method
    

def install(env=Environment):
    if(isinstance(env,type) and (env==Environment or issubclass(env,Environment))):
        env = _new_env(env)
    _init_env(env)
    
    #override jinja2.Template.render
    from jinja2 import Template
    from django.template.context import Context
    _raw_render = Template.render 
    def _new_render(self, *args, **kwargs):
        if(len(args)>0 and isinstance(args[0],Context)):
            c = {}
            for d in args[0].dicts:
                c.update(d)
            return _raw_render(self,c)
        return _raw_render(self, *args, **kwargs)
    Template.render = _new_render
    
    #override djloader.get_template
    import django.template.loader as djloader
    from django.template.loader import get_template as _original_get_template
    def get_template(template_name):
        for skip_path in getattr(settings, 'KEEP_DJANGO_TEMPLATES', ()):
            if template_name.startswith(skip_path):
                return _original_get_template(template_name)
        return env.get_template(template_name)

    djloader.get_template = get_template

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.