Skip to content

Commit 49601d0

Browse files
committed
feat(jinja): add Jinja rendering support
1 parent 06e7357 commit 49601d0

7 files changed

Lines changed: 162 additions & 37 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ authors = [
99
]
1010
requires-python = ">=3.10"
1111
dependencies = [
12+
"jinja2>=3.1.6",
1213
"magic-filter>=1.0.12",
1314
]
1415
keywords = [
@@ -60,4 +61,4 @@ match = "main"
6061

6162
[tool.semantic_release.branches.dev]
6263
match = "dev"
63-
prerelease = true
64+
prerelease = true

textcompose/container/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from textcompose.container.group import Group
1+
__all__ = ["Group"]
22

3-
__all__ = [Group]
3+
from textcompose.container.group import Group

textcompose/content/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
__all__ = ["Format", "Jinja", "Text"]
2+
13
from textcompose.content.format import Format
4+
from textcompose.content.jinja import Jinja
25
from textcompose.content.text import Text
3-
4-
5-
__all__ = [Format, Text]

textcompose/content/content.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
from magic_filter import MagicFilter
55

6-
Value = Union[None, MagicFilter, str, Callable[[dict[str, Any]], str | None], "BaseContent"]
7-
Condition = Union[None, MagicFilter, Callable[[dict[str, Any]], bool], bool, "BaseContent"]
6+
Value = Union[MagicFilter, str, Callable[[dict[str, Any]], str | None], "BaseContent"]
7+
Condition = Union[MagicFilter, Callable[[dict[str, Any]], bool], bool, "BaseContent"]
88

99

1010
class BaseContent(ABC):

textcompose/content/jinja.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from jinja2 import Environment, BaseLoader, select_autoescape
2+
from textcompose.content.content import BaseContent, Value, Condition
3+
4+
TEXTCOMPOSE_JINJA_ENV_FIELD = "textcompose_jinja_env"
5+
6+
7+
class Jinja(BaseContent):
8+
def __init__(self, template: Value, when: Condition | None = None):
9+
self.template = template
10+
super().__init__(when=when)
11+
12+
def render(self, data: dict, **kwargs) -> str:
13+
if TEXTCOMPOSE_JINJA_ENV_FIELD in kwargs:
14+
env = kwargs[TEXTCOMPOSE_JINJA_ENV_FIELD]
15+
else:
16+
kwargs[TEXTCOMPOSE_JINJA_ENV_FIELD] = default_env
17+
env = default_env
18+
19+
template = env.get_template(self.template)
20+
21+
return template.render(data)
22+
23+
24+
class StubLoader(BaseLoader):
25+
def get_source(self, environment, template):
26+
del environment # unused
27+
return template, template, lambda: True
28+
29+
30+
def _create_env(*args, filters=None, **kwargs) -> Environment:
31+
env = Environment(loader=StubLoader(), autoescape=select_autoescape(["html", "xml"]), *args, **kwargs)
32+
33+
if filters:
34+
env.filters.update(filters)
35+
36+
return env
37+
38+
39+
default_env = _create_env()

textcompose/logic/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from textcompose.logic.if_then_else import If
2-
1+
__all__ = ["If"]
32

4-
__all__ = [If]
3+
from textcompose.logic.if_then_else import If

uv.lock

Lines changed: 112 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)