Templates¶
The core renders no template itself. It defines a protocol, and optional packages provide engines:
class TemplateRenderer(Protocol):
async def render(self, template: str, context: Mapping[str, object]) -> str: ...
Pass a renderer to the Mailer; mailables then name templates in template() and
text_template().
Jinja2¶
from goatnotify.jinja import JinjaRenderer
renderer = JinjaRenderer.from_directory("templates")
mailer = Mailer(transport, sender="noreply@example.com", renderer=renderer)
from_directory() builds an environment with:
- HTML autoescaping for
.html,.htmand.xmltemplates (plain-text templates are not escaped); StrictUndefined, so a missing variable is an error instead of an empty string;- async rendering.
To use your own environment, pass it directly: JinjaRenderer(environment). Synchronous
environments render in a worker thread.
Django templates¶
from goatnotify.django.templates import DjangoTemplateRenderer
renderer = DjangoTemplateRenderer() # or DjangoTemplateRenderer(using="jinja2")
It calls render_to_string() through sync_to_async, so it uses your TEMPLATES setting.
A custom renderer¶
Any object with a matching render coroutine works: