Skip to content

Commit

Permalink
Merge pull request #4 from michalpokusa/template-syntax-error-rework
Browse files Browse the repository at this point in the history
Reworked errors in template syntax and overall more validation, caching by default
  • Loading branch information
FoamyGuy authored Apr 15, 2024
2 parents 1258e2c + 90b3d33 commit d2278d7
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 281 deletions.
612 changes: 385 additions & 227 deletions adafruit_templateengine.py

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@
.. automodule:: adafruit_templateengine
:members:
:inherited-members:
35 changes: 12 additions & 23 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,28 @@ This example is printing a basic HTML page with with a dynamic paragraph.
:lines: 5-
:linenos:

Reusing templates
-----------------
Caching/Reusing templates
-------------------------

The are two main ways of rendering templates:
The are two ways of rendering templates:

- manually creating a ``Template`` or ``FileTemplate`` object and calling its method
- using one of ``render_...`` methods
- manually creating a ``Template`` object and calling its method

While the first method is simpler, it also compiles the template on every call.
The second method is more efficient when rendering the same template multiple times, as it allows
to reuse the compiled template, at the cost of more memory usage.

Both methods can be used interchangeably, as they both return the same result.
It is up to the user to decide which method is more suitable for a given use case.
By dafault, the ``render_...`` methods cache the template and reuse it on next calls.
This speeds up the rendering process, but also uses more memory.

**Generally, the first method will be sufficient for most use cases.**
If for some reason the caching is not desired, you can disable it by passing ``cache=False`` to
the ``render_...`` method. This will cause the template to be recreated on every call, which is slower,
but uses less memory. This might be useful when rendering a large number of different templates that
might not fit in the memory at the same time or are not used often enough to justify caching them.

It is also worth noting that compiling all used templates using the second method might not be possible,
depending on the project and board used, due to the limited amount of RAM.

.. literalinclude:: ../examples/templateengine_reusing.py
:caption: examples/templateengine_reusing.py
:lines: 5-
:emphasize-lines: 1,16,20
:emphasize-lines: 22,27,34
:linenos:

Expressions
Expand Down Expand Up @@ -234,29 +232,20 @@ Autoescaping unsafe characters
------------------------------

Token ``{% autoescape off %} ... {% endautoescape %}`` is used for marking a block of code that should
be not be autoescaped. Consequently using ``{% autoescape off %} ...`` does the opposite and turns
be not be autoescaped. Consequently using ``{% autoescape on %} ...`` does the opposite and turns
the autoescaping back on.

By default the template engine will escape all HTML-unsafe characters in expressions
(e.g. ``<`` will be replaced with ``&lt;``).

Content outside expressions is not escaped and is rendered as-is.

For escaping XML and Markdown, you can use the ``language=`` parameter, both in ``render_...`` methods
and in all ``Template`` constructors.

.. literalinclude:: ../examples/autoescape.html
:caption: examples/autoescape.html
:lines: 7-
:language: html
:linenos:

.. literalinclude:: ../examples/autoescape.md
:caption: examples/autoescape.md
:lines: 5-
:language: markdown
:linenos:

.. literalinclude:: ../examples/templateengine_autoescape.py
:caption: examples/templateengine_autoescape.py
:lines: 5-
Expand Down
2 changes: 1 addition & 1 deletion examples/autoescape.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This is a {{ "<b>bold text</b>" }}, because autoescaping is turned off in this block.

{% autoescape on %}
And againg, this is not a {{ "<b>bold text</b>" }},
And again, this is not a {{ "<b>bold text</b>" }},
because in this block autoescaping is turned on again.
{% endautoescape %}
{% endautoescape %}
Expand Down
17 changes: 0 additions & 17 deletions examples/autoescape.md

This file was deleted.

9 changes: 2 additions & 7 deletions examples/templateengine_autoescape.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
#
# SPDX-License-Identifier: Unlicense

from adafruit_templateengine import render_template, Language
from adafruit_templateengine import render_template

# By default autoescape is enabled for HTML
print("HTML autoescape:")
# By default autoescape is enabled for HTML entities
print(render_template("./examples/autoescape.html"))

# But XML and Markdown are also supported
print("Markdown autoescape:")
print(render_template("./examples/autoescape.md", language=Language.MARKDOWN))
28 changes: 24 additions & 4 deletions examples/templateengine_reusing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: Unlicense

from adafruit_templateengine import Template
from adafruit_templateengine import Template, render_string


template_string = r"""
Expand All @@ -17,8 +17,28 @@
</html>
"""

template = Template(template_string)
other_template_string = r"""
<footer>
<p>Goodbye, {{ context.get("name") or "Anonymous User" }}!</p>
</footer>
"""

# Manually create a Template object
template = Template(template_string) # Creates a template object
print(template.render({"name": "John"})) # Reuses the Template object
print(template.render({"name": "Alex"})) # Reuses the Template object

# Using the `render_string` function
print(
render_string(template_string, {"name": "John"})
) # Creates a new Template object and saves it
print(render_string(template_string, {"name": "Alex"})) # Reuses the Template object

context = {"name": ""} # Put your name here

print(template.render(context))
# Using the `render_string` function, but without caching
print(
render_string(other_template_string, {"name": "John"}, cache=False)
) # Creates a new Template object and does not save it
print(
render_string(other_template_string, {"name": "Alex"}, cache=False)
) # Creates a new Template object a second time and does not save it
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ keywords = [
"substitution",
"web",
"html",
"xml",
"escaping",
"syntax",
]
Expand Down

0 comments on commit d2278d7

Please sign in to comment.