Skip to content

Reworked errors in template syntax and overall more validation, caching by default #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e50ce6b
Moved to offset based teplate processing logic, Token class, function…
michalpokusa Mar 7, 2024
36ae07f
Added TemplateSyntaxError and moved underlining function to error cla…
michalpokusa Mar 9, 2024
386a359
Fix: Considering single skipped line in message, moved to separate me…
michalpokusa Mar 9, 2024
da7f54a
Changed Missing to No Matching in error messages
michalpokusa Mar 9, 2024
4922aeb
Checking for additional error in templates and some minor code refactor
michalpokusa Mar 9, 2024
16c5160
Checking for circular extends and tokens between blocks
michalpokusa Mar 10, 2024
4f43652
Refactor: Moved _find function to top
michalpokusa Mar 10, 2024
a51ab4f
Added error for missing template file in FileTemplate
michalpokusa Mar 10, 2024
fc59b94
Added TemplateNotFoundError and docstring to TemplateSyntaxError
michalpokusa Mar 11, 2024
60e4615
CI fixes and slight change in TemplateSyntaxError
michalpokusa Mar 11, 2024
407430f
Addded caching for render_... functions
michalpokusa Mar 12, 2024
089ccdf
Updated docs and example for reusing templates
michalpokusa Mar 12, 2024
5ce56d1
Removed support for Markdown and XML
michalpokusa Mar 12, 2024
8870ff6
Added info about caching behaviour to docstrings
michalpokusa Mar 13, 2024
2c79edb
Checking for anything between blocks, not only tokens
michalpokusa Mar 14, 2024
01a2a34
Removed dry_run parameter
michalpokusa Mar 29, 2024
e117e3e
Refactor of indenting template function parts
michalpokusa Mar 29, 2024
90b3d33
Preventing situations where a function does not yield even once
michalpokusa Apr 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading