~tieong/notjinja2

701c6f82cd2daadff2f7dfa959124c7519ed5565 — Thomas Ieong 1 year, 5 months ago 17d547b
Added support for dict access
3 files changed, 58 insertions(+), 3 deletions(-)

M README.org
M notjinja2.py
M tests/test_templates.py
M README.org => README.org +9 -0
@@ 48,6 48,15 @@ tel que {{ x.calc_price() }} par exemple.
  {% endfor %}
#+end_src

Ici a et b sont des dicts et b contient une liste.

#+begin_src python
  {% for product in product_list.a.b %}
     <li>{{ product.name }}: {{ product.price|format_price }}</li>
  {% endfor %}
#+end_src


Commentaires :

#+begin_src python

M notjinja2.py => notjinja2.py +22 -3
@@ 12,7 12,6 @@ from keyword import iskeyword

TOKENS = re.compile(r"(?s)({%.*?%}|{#.*?#}|{{.*?}})")


class Template:
    INDENT = 0



@@ 67,7 66,9 @@ class Template:

        if "|" in token:
            split_token = token.split("|")
            name = self.globs[split_token[1]].__qualname__
            name = ""
            if len(split_token[1]) > 1:
                name = self.globs[split_token[1]].__qualname__
            dot_split = token.split(".")
            data = "{}".format(dot_split[0])
            # Handle if this is an object accessins it's attributes


@@ 89,8 90,26 @@ class Template:
                    data = "data['{func}']({d})".format(func=function, d=data)
        elif "." in token:
            split_token = token.split(".")
            if split_token[0] in self.globs:
            if len(split_token) == 1 and split_token[0] in self.globs:
                data = "data['{}'].{}".format(split_token[0], split_token[1])
            elif len(split_token) > 1 and split_token[0] in self.globs:
                data = "data['{}']".format(split_token[0])
                data_dict = data
                for d in split_token[1:]:
                    data_dict = "{}['{}']".format(data_dict, d)
                d_path = data_dict.split("['{}']".format(split_token[0]))[1]
                try:
                    eval("self.globs[split_token[0]]" + d_path)
                except (KeyError, TypeError):
                    pass
                    # Not a dict
                else:
                    data = data_dict
                    return data
                for d in split_token[1:]:
                    data = "{}.{}".format(data, d)
                dot_path = data.split("['{}']".format(split_token[0]))[1]
                eval("self.globs[split_token[0]]" + dot_path)
            else:
                data = token
        elif token.isidentifier():

M tests/test_templates.py => tests/test_templates.py +27 -0
@@ 108,6 108,33 @@ class TestTemplates(unittest.TestCase):
            "<li>foo: 150</li>                          <li>boo: 250</li>",
        )

    def test_template5(self):
        class User:
            def __init__(self, is_logged_in, name):
                self.is_logged_in = is_logged_in
                self.name = name
                self.a = []

        template = Template(
            """{% for product in product_list.a.b %}
                 <li>{{ product.name }}: {{ product.price|format_price }}</li>
                 {% endfor %}
                 """,
            {
                "user": User(True, "Donald"),
                "product_list": {"a": {"b": [Product("jk", 10), Product("jk", 20)]}},
                "format_price": Product.format_price,
                "priority": "HIGH",
                "priority_low": "LOW",
                "data": {"HIGH": 1, "MID": 2, "LOW": 3},
            },
           )
        result = template.render()
        self.assertEqual(
            result.strip(),
            "<li>jk: 100</li>                                  <li>jk: 200</li>",
        )


if __name__ == "__main__":
    unittest.main()