This repository has been archived by the owner on Oct 12, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathJinja
123 lines (93 loc) · 4.36 KB
/
Jinja
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
Here's a basic CherryPy Tool for using [http://jinja.pocoo.org/ Jinja] templates:
{{{
#!python
"""A Jinja Handler and tool. This code is in the public domain.
Usage:
@cherrypy.expose
@cherrypy.tools.jinja(filename='index.html')
def controller(**kwargs):
return {
} # This dict is the template context
"""
import os
thisdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
import cherrypy
import jinja
from jinja.datastructure import ComplainingUndefined, SilentUndefinedType
from jinja.datastructure import make_undefined
class JinjaHandler(cherrypy.dispatch.LateParamPageHandler):
"""Callable which sets response.body."""
def __init__(self, env, template_name, next_handler):
self.env = env
self.template_name = template_name
self.next_handler = next_handler
def __call__(self):
context = {}
try:
r = self.next_handler()
context.update(r)
except ValueError, e:
cherrypy.log('%s (handler for "%s" returned "%s")\n' % (
e, self.template_name, repr(r)), traceback=True)
# We wait until this point to do any tasks related to template
# loading or context building, as it may not be necessary if
# the first handler causes a response and we never render
# the template. (Minor Optimization)
if cherrypy.config.get('template.show_errors', False):
self.env.undefined_singleton = ComplainingUndefined
context.update({
'request': cherrypy.request,
'app_url': cherrypy.request.app.script_name,
})
cherrypy.request.template = tmpl = self.env.get_template(self.template_name)
output = tmpl.render(**context)
return output
class LoggingUndefinedType(SilentUndefinedType):
# object calling
def __reduce__(self):
return 'LoggingUndefined'
def __unicode__(self):
"At this point we're being rendered in a template, so we should log it."
cherrypy.log("Coercing undefined object to unicode @%s" %
"".join(traceback.format_stack()),
severity=logging.ERROR)
return u""
LoggingUndefined = make_undefined(LoggingUndefinedType)
class JinjaLoader(object):
"""A CherryPy 3 Tool for loading Jinja templates."""
def __init__(self):
self.template_dir_list = []
self.env = jinja.Environment(loader=jinja.ChoiceLoader(self.template_dir_list),
default_filters=[],
undefined_singleton=LoggingUndefined,
friendly_traceback=False)
self.add_template_dir(os.path.join(thisdir, 'templates'))
def __call__(self, filename):
cherrypy.request.handler = JinjaHandler(self.env, filename, cherrypy.request.handler)
def add_template_dir(self, directory):
"""Used to add a template directory to the jinja source path."""
# Note, this is not using memcacheD. It is using an in-process
# memory cache. Jinja's terminology is a little confusing.
ldr = jinja.FileSystemLoader(searchpath=directory,
use_memcache=True,
memcache_size=sys.maxint,
auto_reload=True)
self.template_dir_list.insert(0, ldr)
self.env.loader = jinja.ChoiceLoader(self.template_dir_list)
def add_filter(self, func):
"""Decorator which adds the given function to jinja's filters."""
self.env.filters[func.__name__] = func
return func
def add_global(self, func):
"""Decorator which adds the given function to jinja's globals."""
self.env.globals[func.__name__] = func
return func
return func
# FIXME: if templates grow more settings, we should consider using a namespace
cherrypy._cpconfig.environments['production']['template.show_errors'] = False
cherrypy._cpconfig.environments['staging']['template.show_errors'] = False
cherrypy._cpconfig.environments['development']['template.show_errors'] = True
cherrypy._cpconfig.environments['test_suite']['template.show_errors'] = False
loader = JinjaLoader()
cherrypy.tools.jinja = cherrypy.Tool('before_handler', loader, priority=70)
}}}