]> Devi Nivas Git - chevron.git/commitdiff
implement #27 -- Lambdas
authorKay-Uwe (Kiwi) Lorenz <kiwi@franka.dyndns.org>
Sat, 28 Jul 2018 06:36:06 +0000 (08:36 +0200)
committerKay-Uwe (Kiwi) Lorenz <kiwi@franka.dyndns.org>
Sat, 28 Jul 2018 06:47:30 +0000 (08:47 +0200)
chevron/renderer.py
test_spec.py

index 4286f5bd5c1768430882d870f5f31942ead35d1c..2f933676a7c3f9d35a1304b3eb42f20344cca393 100644 (file)
@@ -92,7 +92,6 @@ def _get_partial(name, partials_dict, partials_path, partials_ext):
             # Alright I give up on you
             return ''
 
-
 #
 # The main rendering function
 #
@@ -149,6 +148,8 @@ def render(template='', data={}, partials_path='.', partials_ext='mustache',
     A string containing the rendered template.
     """
 
+    function = type(render)
+
     # If the template is a list
     if type(template) is list:
         # Then we don't need to tokenize it
@@ -213,8 +214,51 @@ def render(template='', data={}, partials_path='.', partials_ext='mustache',
             # Get the sections scope
             scope = _get_key(key, scopes)
 
+            # If the scope is a callable (as described in https://mustache.github.io/mustache.5.html)
+            if type(scope) is function:
+
+                # Gather up all the tags inside the section and generate a template text
+                tags = []
+
+                text = unicode('', 'utf-8')
+                for tag in tokens:
+                    if tag == ('end', key):
+                        break
+
+                    tag_type, tag_key = tag
+                    if tag_type == 'literal':
+                        text += tag_key
+                    elif tag_type == 'no escape':
+                        text += "%s& %s %s" % (def_ldel, tag_key, def_rdel)
+                    else:
+                        text += "%s%s %s%s" % (def_ldel,{
+                                'commment': '!',
+                                'section': '#',
+                                'inverted section': '^',
+                                'end': '/',
+                                'partial': '>',
+                                'set delimiter': '=',
+                                'no escape': '&'
+                            }[tag_type], tag_key, def_rdel)
+
+                    tags.append(tag)
+
+                rend = scope(text, lambda template, data=None: render(template,
+                        data={},
+                        partials_path=partials_path,
+                        partials_ext=partials_ext,
+                        partials_dict=partials_dict,
+                        padding=padding,
+                        def_ldel=def_ldel, def_rdel=def_rdel,
+                        scopes=data and [data]+scopes or scopes))
+
+                if python3:
+                    output += rend
+                else:  # python 2
+                    output += rend.decode('utf-8')
+
             # If the scope is a list
-            if type(scope) is list:
+            elif type(scope) is list:
                 # Then we need to do some looping
 
                 # Gather up all the tags inside the section
index 250f5478df2faacf72a4e0fc7d93c046ee6df2d9..14e8eeeea87425c08d07d98d4d0118e7f8a46da4 100755 (executable)
@@ -6,9 +6,14 @@ import os
 import json
 
 import chevron
+from textwrap import dedent
 
 SPECS_PATH = os.path.join('spec', 'specs')
-SPECS = [path for path in os.listdir(SPECS_PATH) if path.endswith('.json')]
+if os.path.exists(SPECS_PATH):
+    SPECS = [path for path in os.listdir(SPECS_PATH) if path.endswith('.json')]
+else:
+    SPECS = []
+
 STACHE = chevron.render
 
 
@@ -228,6 +233,81 @@ class ExpandedCoverage(unittest.TestCase):
                                         'Looks like it was not opened.\n'
                                         'line 2')
 
+    # https://github.com/noahmorrison/chevron/issues/17
+    def test_callable_1(self):
+        args_passed = {}
+        def first(content, render):
+            args_passed['content'] = content
+            args_passed['render'] = render
+
+            return "not implemented"
+
+        args = {
+            'template': '{{{postcode}}} {{#first}} {{{city}}} || {{{town}}} || {{{village}}} || {{{state}}} {{/first}}',
+            'data': {
+                "postcode": "1234",
+                "city": "Mustache City",
+                "state": "Nowhere",
+                "first": first,
+            }
+
+        }
+
+        result = chevron.render(**args)
+        expected = '1234 not implemented'
+        template_content = " {{& city }} || {{& town }} || {{& village }} || {{& state }} "
+
+        self.assertEqual(result, expected)
+        self.assertEqual(args_passed['content'], template_content)
+
+    def test_callable_2(self):
+        args_passed = {}
+        def first(content, render):
+            result = render(content)
+            result = [ x.strip() for x in result.split(" || ") if x.strip() ]
+            return result[0]
+
+        args = {
+            'template': '{{{postcode}}} {{#first}} {{{city}}} || {{{town}}} || {{{village}}} || {{{state}}} {{/first}}',
+            'data': {
+                "postcode": "1234",
+                "town": "Mustache Town",
+                "state": "Nowhere",
+                "first": first,
+            }
+        }
+
+        result = chevron.render(**args)
+        expected = '1234 Mustache Town'
+        template_content = " {{& city }} || {{& town }} || {{& village }} || {{& state }} "
+
+        self.assertEqual(result, expected)
+
+    def test_callable_3(self):
+        '''Test generating some data within the function
+        '''
+        args_passed = {}
+        def first(content, render):
+            result = render(content, {'city': "Injected City"})
+            result = [ x.strip() for x in result.split(" || ") if x.strip() ]
+            return result[0]
+
+        args = {
+            'template': '{{{postcode}}} {{#first}} {{{city}}} || {{{town}}} || {{{village}}} || {{{state}}} {{/first}}',
+            'data': {
+                "postcode": "1234",
+                "town": "Mustache Town",
+                "state": "Nowhere",
+                "first": first,
+            }
+        }
+
+        result = chevron.render(**args)
+        expected = '1234 Injected City'
+        template_content = " {{& city }} || {{& town }} || {{& village }} || {{& state }} "
+
+        self.assertEqual(result, expected)
+
 
 # Run unit tests from command line
 if __name__ == "__main__":