Commit 28e63d4f by Carl Whittaker

Adding template Loader class

parent 01dd06b3
from pystache.template import Template
from pystache.view import View
from pystache.loader import Loader
def render(template, context=None, **kwargs):
context = context and context.copy() or {}
......
import os
class Loader(object):
template_extension = 'mustache'
template_path = '.'
template_encoding = None
def load_template(self, template_name, template_dirs=None):
'''Returns the template string from a file or throws IOError if it non existent'''
if None == template_dirs:
template_dirs = self.template_path
file_name = template_name + '.' + self.template_extension
# Given a single directory we'll load from it
if isinstance(template_dirs, basestring):
file_path = os.path.join(template_dirs, file_name)
return self._load_template_file(file_path)
# Given a list of directories we'll check each for our file
for path in template_dirs:
file_path = os.path.join(path, file_name)
if os.path.exists(file_path):
return self._load_template_file(file_path)
raise IOError('"%s" not found in "%s"' % (template_name, ':'.join(template_dirs),))
def _load_template_file(self, file_path):
'''Loads and returns the template file from disk'''
f = open(file_path, 'r')
try:
template = f.read()
if self.template_encoding:
template = unicode(template, self.template_encoding)
finally:
f.close()
return template
\ No newline at end of file
import re
import cgi
import collections
import os
modifiers = {}
def modifier(symbol):
......@@ -107,6 +108,7 @@ class Template(object):
insides = []
for item in listing:
view = View(context=item)
view.template_path = self.view.template_path
view.parent = self.view
insides.append(Template(template, view).render())
......@@ -117,6 +119,12 @@ class Template(object):
raw = view.get(tag_name, '')
return cgi.escape(unicode(raw))
@modifier('>')
def _render_partial(self, template_name, view):
# mothereffin template loader goes here
template = view.get_template(template_name)
return Template(template, view).render()
def render(self):
template = self._render_sections(self.template, self.view)
......
......@@ -5,6 +5,10 @@ from types import *
class View(object):
template_name = None
template_path = None
template = None
def __init__(self, template=None, context=None, **kwargs):
self.template = template
self.context = context or {}
......@@ -22,4 +26,31 @@ class View(object):
if hasattr(self, 'parent'):
return self.parent.get(attr, default)
else:
return default
\ No newline at end of file
return default
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)
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 self.template_name:
return self.template_name
if not 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 render(self):
return Template(self.get_template(self.template_name), self).render()
\ No newline at end of file
import unittest
import pystache
class TestLoader(unittest.TestCase):
def test_template_is_loaded(self):
loader = pystache.Loader()
template = loader.load_template('simple', 'examples')
self.assertEqual(template, 'Hi {{thing}}!{{blank}}')
def test_using_list_of_paths(self):
loader = pystache.Loader()
template = loader.load_template('simple', ['doesnt_exist', 'examples'])
self.assertEqual(template, 'Hi {{thing}}!{{blank}}')
def test_non_existent_template_fails(self):
loader = pystache.Loader()
self.assertRaises(IOError, loader.load_template, 'simple', 'doesnt_exist')
\ No newline at end of file
......@@ -3,13 +3,12 @@ import pystache
from examples.nested_context import NestedContext
from examples.complex_view import ComplexView
from examples.lambdas import Lambdas
from examples.template_partial import TemplatePartial
class TestSimple(unittest.TestCase):
def test_simple_render(self):
tmpl = '{{derp}}'
self.assertEqual('herp', pystache.Template(tmpl, {'derp': 'herp'}).render())
self.assertEqual('herp', pystache.Template('{{derp}}', {'derp': 'herp'}).render())
def test_nested_context(self):
view = NestedContext()
......@@ -25,4 +24,10 @@ class TestSimple(unittest.TestCase):
def test_callables(self):
view = Lambdas()
self.assertEquals(pystache.Template('{{#replace_foo_with_bar}}foo != bar. oh, it does!{{/replace_foo_with_bar}}', view).render(), 'bar != bar. oh, it does!')
\ No newline at end of file
self.assertEquals(pystache.Template('{{#replace_foo_with_bar}}foo != bar. oh, it does!{{/replace_foo_with_bar}}', view).render(), 'bar != bar. oh, it does!')
def test_rendering_partial(self):
view = TemplatePartial()
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! ')
\ 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