Install & Compatibility
Where this runs
tested against v25.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.042s · 18.9MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.8s · import 0.040s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
plugin_filters_hook
✓ from jinjanator_plugins import plugin_filters_hook
Decorator for registering custom Jinja2 filters.
plugin_tests_hook
✓ from jinjanator_plugins import plugin_tests_hook
Decorator for registering custom Jinja2 tests.
plugin_globals_hook
✓ from jinjanator_plugins import plugin_globals_hook
Decorator for registering custom global functions.
plugin_formats_hook
✓ from jinjanator_plugins import plugin_formats_hook
Decorator for registering custom data format parsers.
plugin_extensions_hook
✓ from jinjanator_plugins import plugin_extensions_hook
Decorator for registering Jinja2 extensions.
plugin_identities_hook
✓ from jinjanator_plugins import plugin_identities_hook
Decorator for identifying the plugin.
Format
✓ from jinjanator_plugins import Format
Protocol for defining custom format classes.
This example demonstrates how to create a minimal Jinjanator plugin that registers custom Jinja2 filters. It defines a `my_plugin.py` file using the `@plugin_filters_hook` decorator to expose 'scream' and 'reverse' filters. For Jinjanator to discover this plugin, it would typically be packaged as a Python project (e.g., using `pyproject.toml` with an entry-point) and installed into the same environment as `jinjanator`.
import os
from jinjanator_plugins import plugin_filters_hook
# my_plugin_example/pyproject.toml (illustrative, not run directly)
# [project]
# name = "jinjanator-my-plugin"
# version = "0.1.0"
# dependencies = [
# "jinjanator-plugins==25.1.*", # Pinning recommended
# ]
#
# [project.entry-points."jinjanator.plugins"]
# my_plugin = "my_plugin_example.my_plugin"
# my_plugin_example/my_plugin.py
@plugin_filters_hook
def plugin_filters():
"""Registers custom Jinja2 filters."""
def scream_filter(value):
return str(value).upper() + "!!!"
def reverse_filter(value):
return str(value)[::-1]
return {
"scream": scream_filter,
"reverse": reverse_filter,
}
# Example usage within a Jinjanator template (template.j2) and CLI
# Assuming `my_plugin_example` is installed as a package and discoverable by jinjanator:
#
# template.j2:
# Hello {{ name | scream }}
# Message: {{ 'dlrow olleh' | reverse }}
#
# CLI command:
# $ jinjanate --data-var name="World" template.j2
# Output:
# Hello WORLD!!!
# Message: hello world
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'jinjanator_plugins'
The `jinjanator-plugins` package is not installed in the active Python environment, or the environment where a custom plugin expects it is not correctly activated.
fixInstall the package using `pip install jinjanator-plugins` or ensure the correct virtual environment is activated and `jinjanator` (which has `jinjanator-plugins` as a dependency) is installed.
AttributeError: module 'jinjanator_plugins' has no attribute 'plugin_filters_hook'
A custom plugin's code is trying to access an API element (like `plugin_filters_hook`, `Format`, or other decorators/types) from `jinjanator-plugins` that either doesn't exist, has been renamed, or has been removed in the installed version of `jinjanator-plugins` due to backward-incompatible API changes.
fixUpdate the plugin code to use the current API of `jinjanator-plugins`. Alternatively, if the plugin is external, try pinning the `jinjanator-plugins` dependency in your project or plugin's `pyproject.toml` to a specific version known to be compatible with the plugin (e.g., `jinjanator-plugins = "==25.1.0"`).
jinja2.exceptions.UndefinedError: 'my_custom_filter' is undefined
A Jinja2 template is attempting to use a filter, test, or global function (e.g., `my_custom_filter`) that was expected to be provided by a `jinjanator-plugins`-based plugin, but the plugin either failed to load, did not correctly register its components, or the name used in the template is incorrect.
fixVerify the plugin is correctly installed alongside `jinjanator` and that its entry points are properly configured in `pyproject.toml`. Ensure the plugin's hook functions (e.g., `plugin_filters`) are correctly implemented and return the expected dictionary. Confirm the name used in the Jinja2 template exactly matches the name registered by the plugin.
Upgrade
Version history
25.1.0latest on PyPI · released Oct 18, 2025
Audit
Dependencies
setuptoolsoptionalBuild-time dependency for packages that implement plugins using this API.
typing-extensionsoptionalUsed for compatibility with older Python versions, though newer versions require Python 3.10+.