Jinja Macro Tags
Jinja Macro Tags introduces an HTML-like syntax to call Jinja macros, as well as a macro registry that automatically imports macros where they are used.
<{panel title="Hello"}>
<{button "click me" style="primary"}/>
</{panel}>
This is a maintained fork of
maximebf/jinja-macro-tags,
published on PyPI as jinja-macro-tags-pakal.
Installation
pip install jinja-macro-tags-pakal
Requires Python 3.11+ and Jinja2 2.11+ (Jinja 3.x is supported). Windows, Linux and macOS are supported.
The distribution name differs from the module name, which is
still jinja_macro_tags:
import jinja_macro_tags
Quick start
The simplest setup is configure_environment(), which enables both macro tags
and the macro registry:
from jinja2 import Environment, FileSystemLoader
from jinja_macro_tags import configure_environment
env = Environment(loader=FileSystemLoader("templates"))
configure_environment(env)
env.macros.register_file("macros.html")
print(env.get_template("form.html").render())
macros.html:
{% macro form(action) -%}
<form action="{{ action }}" method="post">
{{ caller() }}
</form>
{%- endmacro %}
{% macro form_input(name) -%}
<input type="text" name="{{ name }}">
{%- endmacro %}
templates/form.html:
<{form action="/" }>
<{form_input name="email" }/>
</{form}>
No {% import %} statement is needed: the registry knows where form and
form_input are defined and imports them automatically.
Macro tags
Macro tags let you call macros with a syntax similar to HTML tags. There are
two kinds of macro tags: inline and block. Inline tags are the equivalent of
calling the macro with {{ macro_name() }}; block tags are the equivalent of
the {% call %} directive.
Arguments are written like HTML attributes, but their values are Jinja
expressions, so string literals must be quoted (label="ok"), while
label=user.name passes a variable. Positional arguments are also
supported (<{button "ok"}/>).
Since arguments are separated by whitespace rather than commas, a couple of
expression forms are ambiguous and get rejected with a clear error instead
of being silently misinterpreted: adjacent string literals
(<{button "a" "b"}/>, which Jinja would otherwise concatenate into a
single "ab" argument — use ~ if that's what you want), and a bare
+/- at the start of an argument (<{button x -1}/>, which could be
x - 1 or two separate arguments x, -1 — wrap it in parentheses,
<{button (x - 1)}/>, to disambiguate).
Jinja-style tags
Inline tags are enclosed in <{ and }/>:
<{macro_name arg1=value1 arg2=value2 }/>
is equivalent to:
{{ macro_name(arg1=value1, arg2=value2) }}
Block tags start with an opening tag enclosed in <{ and }> and must be
closed with </{macro_name}> (the macro name is optional in the closing tag,
</{}> works too; when given, it must match the innermost open tag, or
you'll get a clear error instead of silently mismatched nesting):
<{macro_name arg1=value1 arg2=value2 }>
my macro content
</{macro_name}>
is equivalent to:
{% call macro_name(arg1=value1, arg2=value2) %}
my macro content
{% endcall %}
HTML-style tags
HTML-style tags use an m: namespace prefix instead. Dashes in macro names
are converted to underscores, so <m:form-input> calls form_input:
<m:panel title="test panel">
<m:form-input name="email" />
</m:panel>
Enabling macro tags manually
If you don't use configure_environment(), add the extensions yourself:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader(__name__, "templates"))
env.add_extension("jinja_macro_tags.LoadMacroExtension")
env.add_extension("jinja_macro_tags.CallMacroTagExtension")
env.add_extension("jinja_macro_tags.JinjaMacroTagsExtension") # <{...}/> tags
env.add_extension("jinja_macro_tags.HtmlMacroTagsExtension") # <m:.../> tags
When added this way, macros are not autoloaded and you still need your
{% import %} statements. Set env.autoload_macro_tags = True to let tags
autoload macros from the registry.
Macro registry
The macro registry lets you load macros by name. Macros can be registered from templates available through your loader, and also from any Jinja file that your loader can't reach.
Used together with macro tags, the registry means you don't even need to load macros: the tags use it to load them automatically.
The registry requires two things:
- wrapping your template loader in an instance of
jinja_macro_tags.MacroLoader - adding the
jinja_macro_tags.LoadMacroExtensionextension
configure_environment() does both for you:
configure_environment(
env,
wrap_loader=True, # wrap env.loader in a MacroLoader
with_jinja_tags=True, # enable <{...}/> tags
with_html_tags=False, # enable <m:.../> tags
)
To use the registry without macro tags:
configure_environment(env, with_jinja_tags=False)
Once configured, the registry is available through the macros attribute of
the environment.
Register macros from templates available through your loader:
register_from_template(template): register all macros defined in the templateregister(name, template): register the named macro, which is defined in the templateregister_from_environment(): register macros from every.htmltemplate that the loader can list
Register macros from files your environment loader can't reach:
register_file(filename, alias=None)register_directory(path, prefix=None)register_package(package_name, package_path="macros", prefix=None)register_loader(loader, prefix=None)
Files added with these methods can be reached from your environment under
the __macros__/ prefix.
All registration methods take a replace argument. By default, registering
a macro name twice raises an exception; pass replace=True to override the
previous definition.
Create macro aliases with alias(name, alias):
env.macros.alias("form_input", "input") # <{input name="email"}/>
The load_macro directive
To load registered macros explicitly, use the load_macro directive. It takes
a list of macro names:
{% load_macro form, form_input %}
You don't need it if you use macro tags with autoloading enabled.
Development
pip install -e ".[test]"
pytest --cov
To run the test suite against every supported Python version (3.11 to 3.14), with both Jinja 2.x and Jinja 3.x:
tox
Changelog
See CHANGELOG.md.
License
MIT, see LICENSE.
Metadata
Release files for jinja-macro-tags-pakal 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| jinja_macro_tags_pakal-1.0.0.tar.gz | 17.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jinja_macro_tags_pakal-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.1 kB
Security for jinja-macro-tags-pakal 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.