diff --git a/template_engine/nodes.py b/template_engine/nodes.py index 38bf6bf..fc945c7 100644 --- a/template_engine/nodes.py +++ b/template_engine/nodes.py @@ -1,4 +1,8 @@ import html +class TemplateRuntimeException(Exception): + pass + + def head(string, n): return string[:n] if len(string) >= n else string @@ -29,7 +33,7 @@ def render(self, context): class ForNode(Node): def __init__(self, iterator, iterable): - self._iterator = iterator + self._iterators = iterator.split(',') # a list of the iterators self._iterable = iterable self._child = None @@ -40,16 +44,29 @@ def set_child(self, child): self._child = child def __repr__(self): - return "" + return "" def render(self, context): # Evaluate the iterable so we know what to iterate over iterable = eval(self._iterable, {}, context) rendered_children = [] for i in iterable: - # Create a new context to include our variable - new_context = dict(context) - new_context[self._iterator] = i + # i may be a unzipped tuple: + if len(self._iterators) > 1: + if not (len(self._iterators) == len(i)): + raise ValueError("not enough values to unpack (expected %d, got %d)" % (len(self._iterators), len(i))) + # check that the unpacked item's length is equal to the number of iterators suppled + + # Create a new context to include our variable(s) + new_context = dict(context) + for upto, variable in enumerate(self._iterators): + new_context[variable] = i[upto] + else: + # there is only one iterator, set it to i + new_context = dict(context) + new_context[self._iterators[0]] = i + + # Render the child with our special context rendered = self._child.render(new_context) if rendered.strip(): diff --git a/template_engine/parser.py b/template_engine/parser.py index 665d3b4..0920d2b 100644 --- a/template_engine/parser.py +++ b/template_engine/parser.py @@ -151,8 +151,11 @@ def identify_token(token): elif ' '.join(term_list) == 'end if': return create_token('end_if', None) elif keyword == 'for': + print(term_list) # The contents is a dictionary which contains the iterator and the iterable - return create_token('for', {'iterator': term_list[1], 'iterable': ' '.join(term_list[3:])}) + in_loc = term_list.index('in') + # get the location of the in to split the query into iterator and iterable + return create_token('for', {'iterator': "".join(term_list[1:in_loc]), 'iterable': ' '.join(term_list[in_loc+1:])}) elif ' '.join(term_list) == 'end for': return create_token('end_for', None) elif keyword == 'comment': diff --git a/templates/index.html b/templates/index.html index 0db43ce..f80abcf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -10,15 +10,15 @@
{% for post in posts %} -
- - {{ post['question'] }} -
-
- {{ post['question'] }} -
-
-
+
+
+ {{ post['question'] }} +
+ {{ post['question'] }} +
+
+
+ {% end for %}
diff --git a/templates/test.html b/templates/test.html index 27cbf6d..07341e3 100644 --- a/templates/test.html +++ b/templates/test.html @@ -6,6 +6,7 @@

Hello there

-

{{ fname }} {{ lname }} {{ food }}

+ {% for i, z in enumerate(test) %} +

{{ i }} : {{ z }} : works!

diff --git a/testing.py b/testing.py new file mode 100644 index 0000000..16a2392 --- /dev/null +++ b/testing.py @@ -0,0 +1,9 @@ +from template_engine.parser import render +from tornado.ncss import Server, ncssbook_log +def handler(request): + request.write(render("test.html", {'test': enumerate(range(10))})) + +server = Server() +server.register(r'/test', handler) + +server.run()