~tieong/notjinja2

b58cde849c7a2b926294ca76e7dfdfb08d4b0233 — Thomas Ieong 1 year, 7 months ago ea586f1
Added support for multiples filters
2 files changed, 50 insertions(+), 8 deletions(-)

M notjinja2.py
M tests/test_templates.py
M notjinja2.py => notjinja2.py +19 -7
@@ 64,12 64,25 @@ class Template:
            split_token = token.split("|")
            name = self.globs[split_token[1]].__qualname__
            dot_split = token.split(".")
            if len(name.split(".")) >= 1:
                data = "data['{}']({}, {})".format(
                    split_token[1], dot_split[0], split_token[0]
                )
            else:
                data = "data['{}']({})".format(split_token[1], split_token[0])
            data = "{}".format(dot_split[0])
            # Handle if this is an object accessins it's attributes
            if dot_split[1].split("|")[0] not in self.globs:
                data = data + "." + dot_split[1].split("|")[0]
            for function in split_token[1:]:
                if len(name.split(".")) > 1:
                    data = "data['{}']({}, {})".format(
                        split_token[1], dot_split[0], split_token[0]
                    )
                elif (
                    function in self.globs
                    and len(self.globs[function].__qualname__.split(".")) > 1
                ):
                    data = "data['{func}']({i}, {d})".format(
                        func=function, d=data, i=dot_split[0]
                    )
                else:
                    data = "data['{func}']({d})".format(func=function, d=data)
            data = "str({})".format(data)
        elif "." in token:
            split_token = token.split(".")
            if split_token[0] in self.globs:


@@ 125,4 138,3 @@ class Template:
    def render(self) -> str:
        exec(self.code)
        return eval("template_render")(self.globs)


M tests/test_templates.py => tests/test_templates.py +31 -1
@@ 9,6 9,14 @@ class User:
        self.name = name


def add_2(integer):
    return integer + 2


def add_3(integer):
    return integer + 3


class Product:
    def __init__(self, name, price):
        self.name = name


@@ 65,7 73,7 @@ class TestTemplates(unittest.TestCase):
                f.read(),
                {
                    "user": User(True, "Donald"),
                    "product_list": {"a":Product("foo", 10), "b": Product("boo", 20)},
                    "product_list": {"a": Product("foo", 10), "b": Product("boo", 20)},
                    "format_price": Product.format_price,
                    "priority": "HIGH",
                    "priority_low": "LOW",


@@ 78,6 86,28 @@ class TestTemplates(unittest.TestCase):
            "    <p>Welcome, Donald!</p><p>Products:</p><ul>        <li>a: foo</li>        <li>b: boo</li>    </ul>",
        )

    def test_template4(self):
        template = Template(
            """{% for product in product_list %}
             <li>{{ product.name }}: {{ product.price|add_3|add_2|format_price }}</li>
             {% endfor %}
             """,
            {
                "user": User(True, "Donald"),
                "product_list": [Product("foo", 10), Product("boo", 20)],
                "add_2": add_2,
                "add_3": add_3,
                "priority": "HIGH",
                 "format_price": Product.format_price,
                "data": {"HIGH": 1, "MID": 2, "LOW": 3},
            },
        )
        result = template.render()
        self.assertEqual(
            result.strip(),
            "<li>foo: 150</li>                          <li>boo: 250</li>",
        )


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