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
|
from pystache import Template
import os.path
import re
from types import *
def get_or_attr(context_list, name, default=None):
if not context_list:
return default
for obj in context_list:
try:
return obj[name]
except KeyError:
pass
except:
try:
return getattr(obj, name)
except AttributeError:
pass
return default
class View(object):
template_name = None
template_path = None
template = None
template_encoding = None
template_extension = 'mustache'
def __init__(self, template=None, context=None, **kwargs):
self.template = template
context = context or {}
context.update(**kwargs)
self.context_list = [context]
def get(self, attr, default=None):
attr = get_or_attr(self.context_list, attr, getattr(self, attr, default))
if hasattr(attr, '__call__') and type(attr) is UnboundMethodType:
return attr()
else:
return attr
def get_template(self, template_name):
if not self.template:
from pystache import Loader
template_name = self._get_template_name(template_name)
self.template = Loader().load_template(template_name, self.template_path, encoding=self.template_encoding, extension=self.template_extension)
return self.template
def _get_template_name(self, template_name=None):
"""TemplatePartial => template_partial
Takes a string but defaults to using the current class' name or
the `template_name` attribute
"""
if template_name:
return template_name
template_name = self.__class__.__name__
def repl(match):
return '_' + match.group(0).lower()
return re.sub('[A-Z]', repl, template_name)[1:]
def _get_context(self):
context = {}
for item in self.context_list:
if hasattr(item, 'keys') and hasattr(item, '__getitem__'):
context.update(item)
return context
def render(self, encoding=None):
return Template(self.get_template(self.template_name), self).render(encoding=encoding)
def __contains__(self, needle):
return needle in self.context or hasattr(self, needle)
def __getitem__(self, attr):
val = self.get(attr, None)
if not val and val is not 0:
raise KeyError("Key '%s' does not exist in View" % attr)
return val
def __getattr__(self, attr):
if attr == 'context':
return self._get_context()
raise AttributeError("Attribute '%s' does not exist in View" % attr)
def __str__(self):
return self.render()
|