From 0d8546d6a42a6bc805907043af74060311c05e66 Mon Sep 17 00:00:00 2001 From: Thomas Schneider <thomas@fsmpi.rwth-aachen.de> Date: Thu, 5 Sep 2024 15:21:17 +0200 Subject: [PATCH] helpers: Add get_template_attribute() --- schilder2000/helpers.py | 45 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/schilder2000/helpers.py b/schilder2000/helpers.py index b7be661..1a6a575 100644 --- a/schilder2000/helpers.py +++ b/schilder2000/helpers.py @@ -1,6 +1,11 @@ import typing as t -from flask import Flask as _Flask, Blueprint as FlaskBlueprint, render_template +from flask import ( + Flask as _Flask, + Blueprint as FlaskBlueprint, + current_app, + render_template, +) from jinja2 import BaseLoader, ChoiceLoader, PrefixLoader, Template @@ -43,3 +48,41 @@ class Flask(_Flask): self.jinja_env.loader.loaders[0].mapping[blueprint.name] = ( blueprint.jinja_loader ) + + +_sentinel = object() + + +def get_template_attribute( + template_name: str, + attribute: str, + default: t.Any = _sentinel, + vars: t.Dict[str, t.Any] | None = None, + shared: bool = False, + locals: t.Mapping[str, t.Any] | None = None, +) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + mod = current_app.jinja_env.get_template(template_name).make_module( + vars, shared, locals + ) + if default is _sentinel: + return getattr(mod, attribute) + else: + return getattr(mod, attribute, default) -- GitLab