Commit c859dfa2 by Carl Whittaker

Adding support for template encoding and support for comment and delimeter tags.

parent 28e63d4f
...@@ -6,11 +6,17 @@ class Loader(object): ...@@ -6,11 +6,17 @@ class Loader(object):
template_path = '.' template_path = '.'
template_encoding = None template_encoding = None
def load_template(self, template_name, template_dirs=None): def load_template(self, template_name, template_dirs=None, encoding=None, extension=None):
'''Returns the template string from a file or throws IOError if it non existent''' '''Returns the template string from a file or throws IOError if it non existent'''
if None == template_dirs: if None == template_dirs:
template_dirs = self.template_path template_dirs = self.template_path
if encoding is not None:
self.template_encoding = encoding
if extension is not None:
self.template_extension = extension
file_name = template_name + '.' + self.template_extension file_name = template_name + '.' + self.template_extension
# Given a single directory we'll load from it # Given a single directory we'll load from it
......
...@@ -109,6 +109,7 @@ class Template(object): ...@@ -109,6 +109,7 @@ class Template(object):
for item in listing: for item in listing:
view = View(context=item) view = View(context=item)
view.template_path = self.view.template_path view.template_path = self.view.template_path
view.template_encoding = self.view.template_encoding
view.parent = self.view view.parent = self.view
insides.append(Template(template, view).render()) insides.append(Template(template, view).render())
...@@ -118,16 +119,41 @@ class Template(object): ...@@ -118,16 +119,41 @@ class Template(object):
def _render_tag(self, tag_name, view): def _render_tag(self, tag_name, view):
raw = view.get(tag_name, '') raw = view.get(tag_name, '')
# For methods with no return value
if not raw and raw is not 0:
return ''
return cgi.escape(unicode(raw)) return cgi.escape(unicode(raw))
@modifier('!')
def _render_comment(self, tag_name, view):
return ''
@modifier('>') @modifier('>')
def _render_partial(self, template_name, view): def _render_partial(self, template_name, view):
# mothereffin template loader goes here from pystache import Loader
template = view.get_template(template_name) template = Loader().load_template(template_name, view.template_path, encoding=view.template_encoding)
return Template(template, view).render() return Template(template, view).render()
def render(self): @modifier('=')
def _change_delimiter(self, tag_name, view):
"""Changes the Mustache delimiter."""
self.otag, self.ctag = tag_name.split(' ')
self._compile_regexps()
return ''
@modifier('{')
@modifier('&')
def render_unescaped(self, tag_name, view):
"""Render a tag without escaping it."""
return unicode(view.get(tag_name, ''))
def render(self, encoding=None):
template = self._render_sections(self.template, self.view) template = self._render_sections(self.template, self.view)
result = self._render_tags(template, self.view) result = self._render_tags(template, self.view)
if encoding is not None:
result = result.encode(encoding)
return result return result
\ No newline at end of file
...@@ -8,6 +8,8 @@ class View(object): ...@@ -8,6 +8,8 @@ class View(object):
template_name = None template_name = None
template_path = None template_path = None
template = None template = None
template_encoding = None
template_extension = None
def __init__(self, template=None, context=None, **kwargs): def __init__(self, template=None, context=None, **kwargs):
self.template = template self.template = template
...@@ -16,7 +18,6 @@ class View(object): ...@@ -16,7 +18,6 @@ class View(object):
def get(self, attr, default=None): def get(self, attr, default=None):
attr = self.context.get(attr, getattr(self, attr, self._get_from_parent(attr, default))) attr = self.context.get(attr, getattr(self, attr, self._get_from_parent(attr, default)))
if hasattr(attr, '__call__') and type(attr) is UnboundMethodType: if hasattr(attr, '__call__') and type(attr) is UnboundMethodType:
return attr() return attr()
else: else:
...@@ -32,7 +33,7 @@ class View(object): ...@@ -32,7 +33,7 @@ class View(object):
if not self.template: if not self.template:
from pystache import Loader from pystache import Loader
template_name = self._get_template_name(template_name) template_name = self._get_template_name(template_name)
self.template = Loader().load_template(template_name, self.template_path) self.template = Loader().load_template(template_name, self.template_path, encoding=self.template_encoding, extension=self.template_extension)
return self.template return self.template
...@@ -41,10 +42,9 @@ class View(object): ...@@ -41,10 +42,9 @@ class View(object):
Takes a string but defaults to using the current class' name or Takes a string but defaults to using the current class' name or
the `template_name` attribute the `template_name` attribute
""" """
if self.template_name: if template_name:
return self.template_name return template_name
if not template_name:
template_name = self.__class__.__name__ template_name = self.__class__.__name__
def repl(match): def repl(match):
...@@ -52,5 +52,5 @@ class View(object): ...@@ -52,5 +52,5 @@ class View(object):
return re.sub('[A-Z]', repl, template_name)[1:] return re.sub('[A-Z]', repl, template_name)[1:]
def render(self): def render(self, encoding=None):
return Template(self.get_template(self.template_name), self).render() return Template(self.get_template(self.template_name), self).render(encoding=encoding)
\ No newline at end of file \ No newline at end of file
...@@ -4,6 +4,7 @@ from examples.nested_context import NestedContext ...@@ -4,6 +4,7 @@ from examples.nested_context import NestedContext
from examples.complex_view import ComplexView from examples.complex_view import ComplexView
from examples.lambdas import Lambdas from examples.lambdas import Lambdas
from examples.template_partial import TemplatePartial from examples.template_partial import TemplatePartial
from examples.simple import Simple
class TestSimple(unittest.TestCase): class TestSimple(unittest.TestCase):
...@@ -30,4 +31,19 @@ class TestSimple(unittest.TestCase): ...@@ -30,4 +31,19 @@ class TestSimple(unittest.TestCase):
view = TemplatePartial() view = TemplatePartial()
self.assertEquals(pystache.Template('{{>inner_partial}}', view).render(), 'Again, Welcome!') self.assertEquals(pystache.Template('{{>inner_partial}}', view).render(), 'Again, Welcome!')
self.assertEquals(pystache.Template('{{#looping}}{{>inner_partial}} {{/looping}}', view).render(), 'Again, Welcome! Again, Welcome! Again, Welcome! ') self.assertEquals(pystache.Template('{{#looping}}{{>inner_partial}} {{/looping}}', view).render(), '''Again, Welcome! Again, Welcome! Again, Welcome!''')
\ No newline at end of file
def test_non_existent_value_renders_blank(self):
view = Simple()
self.assertEquals(pystache.Template('{{not_set}} {{blank}}', view).render(), ' ')
def test_template_partial_extension(self):
view = TemplatePartial()
view.template_extension = 'txt'
self.assertEquals(view.render(), """Welcome
-------
Again, Welcome!
""")
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment