Skip to content

Instantly share code, notes, and snippets.

@juancarlospaco
Last active April 6, 2018 19:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juancarlospaco/97a6a09d64b190a630ad to your computer and use it in GitHub Desktop.
Save juancarlospaco/97a6a09d64b190a630ad to your computer and use it in GitHub Desktop.
Templar is a tiny Template Engine that Render and Runs native Python 3. Optionally it can Minify the rendered output, or load from a file or file-like object.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Templar is a tiny Template Engine that Render and Runs native Python."""
import re
class Templar(str):
"""Templar is a tiny Template Engine that Render and Runs native Python."""
def __init__(self, template):
"""Init the Template class."""
self.tokens = self.compile(template.strip())
@classmethod
def from_file(cls, fl):
"""Load template from file.A str/file-like object supporting read()."""
return cls(str(open(fl).read() if isinstance(fl, str) else fl.read()))
def compile(self, t):
"""Parse and Compile all Tokens found on the template string t."""
tokens = []
for i, p in enumerate(re.compile("\{\%(.*?)\%\}", re.DOTALL).split(t)):
if not p or not p.strip():
continue
elif i % 2 == 0:
tokens.append((False, p.replace("{\\%", "{%")))
else:
lines = tuple(p.replace("%\\}", "%}").replace(
"{{", "spit(").replace("}}", "); ") .splitlines())
mar = min(len(_) - len(_.lstrip()) for _ in lines if _.strip())
al = "\n".join(line_of_code[mar:] for line_of_code in lines)
tokens.append((True, compile(al, "<t {}>".format(al), "exec")))
return tokens
def render(__self, __namespace={}, mini=False, **kw):
"""Render template from __namespace dict + **kw added to namespace."""
html = []
__namespace.update(kw, **globals())
def spit(*args, **kwargs):
for _ in args:
html.append(str(_))
if kwargs:
for _ in tuple(kwargs.items()):
html.append(str(_))
__namespace["spit"] = spit
for is_code, value in __self.tokens:
eval(value, __namespace) if is_code else html.append(value)
return re.sub('>\s+<', '> <', "".join(html)) if mini else "".join(html)
__call__ = render # shorthand
if __name__ in '__main__':
demo = """<html><body>
{%
def say_hello(arg):
{{"<tr> hello ", arg, " </tr>"}}
%}
<table>
{% [say_hello(i) for i in range(9) if i % 2] %}
</table>
{% {{ in_your_face }} {{ __doc__.title() }} %}
{% # this is a python comment %} </body></html>"""
templar_template = Templar(demo)
print(templar_template(in_your_face=9, mini=True))
print(templar_template(in_your_face=2))
print(isinstance(templar_template, str))
@juancarlospaco
Copy link
Author

  • Start a code block with {%, end a code block with %}, just like Django or Jinja2.
  • Render a variable or code with {{ and }} eg. {{foo}}, just like Django and Mustache.
  • Things on globals() are available so stuff like __doc__ and __name__ wil work.
  • Optional simple HTML / SVG Minification with mini Boolean argument (Off by Default).
python3 templar.py

Output with Minification = True:

<html><body><table><tr> hello 1 </tr><tr> hello 3 </tr><tr> hello 5 </tr><tr> hello 7 </tr> </table> 2 Templar is a tiny Template Engine that Render and Runs native Python.</body></html>

Output with Minification = False:

<html>
<body>

    <table>
        <tr> hello 1 </tr>
        <tr> hello 3 </tr>
        <tr> hello 5 </tr>
        <tr> hello 7 </tr>
    </table>

    2 Templar is a tiny Template Engine that Render and Runs native Python.
</body>
</html>

😸

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment