from typing import Any, NamedTuple
from django.template.loader import get_template
from django.template import Template
import premailer
import os
[docs]
class EmailAddress(NamedTuple):
"""
Email address according to updated RFC 2822
- see https://tools.ietf.org/html/rfc5322#section-3.4.
"""
address: str
display_name: str | None = None
def __str__(self) -> str:
if self.display_name:
return f'{self.display_name} <{self.address}>'
return self.address
def __eq__(self, other):
if isinstance(other, EmailAddress):
return self.address.lower() == other.address.lower()
else:
return False
[docs]
def render_and_inline_template(
template_name: str, context: dict[str, Any], base_path_relative=None, base_url=None
) -> str:
"""
Renders a Django HTML template and inlines CSS rules using `Premailer <https://premailer.io/>`_.
:param template_name: Name of the Django HTML template to render.
:param context: Rendering context (= template variables).
:param base_path_relative: Path where the CSS referenced in the template are stored. This path can be relative
to the template file.
:param base_url: Base URL that will be used to convert relative links to absolute.
:return: Rendered HTML.
"""
template: Template = get_template(template_name)
html = template.render(context)
base_path = os.path.dirname(template.origin.name)
if base_path_relative:
base_path = os.path.abspath(os.path.join(base_path, base_path_relative))
return premailer.Premailer(
html=html,
capitalize_float_margin=True,
base_path=base_path,
base_url=base_url,
disable_validation=True,
allow_loading_external_files=True,
).transform(pretty_print=False)