From 1919dce3a902a13ee03d5f55c57cc4bbf868747e Mon Sep 17 00:00:00 2001 From: Lebaud Antoine Date: Tue, 19 Mar 2024 22:44:03 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB(views)=20rend?= =?UTF-8?q?er=20email's=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit THis feature is inspired by Joanie. Add two new urls to render Emails HTML and Text templates. Developpers can render the email template they are working on. When necessary, run make mails-build, and reload `_debug__/mail/hello_html`, it will re-render the updated email template. Also, I have copy/pasted one template extra tags from Joanie, which loads bas64 string from static images. This code is necessary to render the dummy template `hello.html`. --- src/backend/core/templatetags/__init__.py | 0 src/backend/core/templatetags/extra_tags.py | 58 +++++++++++++++++++++ src/backend/debug/urls.py | 21 ++++++++ src/backend/debug/views.py | 29 +++++++++++ src/backend/people/urls.py | 3 ++ src/mail/mjml/hello.mjml | 10 ++-- 6 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 src/backend/core/templatetags/__init__.py create mode 100644 src/backend/core/templatetags/extra_tags.py create mode 100644 src/backend/debug/urls.py create mode 100644 src/backend/debug/views.py diff --git a/src/backend/core/templatetags/__init__.py b/src/backend/core/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/backend/core/templatetags/extra_tags.py b/src/backend/core/templatetags/extra_tags.py new file mode 100644 index 0000000..109bd7b --- /dev/null +++ b/src/backend/core/templatetags/extra_tags.py @@ -0,0 +1,58 @@ +"""Custom template tags for the core application of People.""" + +import base64 + +from django import template +from django.contrib.staticfiles import finders + +from PIL import ImageFile as PillowImageFile + +register = template.Library() + + +def image_to_base64(file_or_path, close=False): + """ + Return the src string of the base64 encoding of an image represented by its path + or file opened or not. + + Inspired by Django's "get_image_dimensions" + """ + pil_parser = PillowImageFile.Parser() + if hasattr(file_or_path, "read"): + file = file_or_path + if file.closed and hasattr(file, "open"): + file_or_path.open() + file_pos = file.tell() + file.seek(0) + else: + try: + # pylint: disable=consider-using-with + file = open(file_or_path, "rb") + except OSError: + return "" + close = True + + try: + image_data = file.read() + if not image_data: + return "" + pil_parser.feed(image_data) + if pil_parser.image: + mime_type = pil_parser.image.get_format_mimetype() + encoded_string = base64.b64encode(image_data) + return f"data:{mime_type:s};base64, {encoded_string.decode('utf-8'):s}" + return "" + finally: + if close: + file.close() + else: + file.seek(file_pos) + + +@register.simple_tag +def base64_static(path): + """Return a static file into a base64.""" + full_path = finders.find(path) + if full_path: + return image_to_base64(full_path, True) + return "" diff --git a/src/backend/debug/urls.py b/src/backend/debug/urls.py new file mode 100644 index 0000000..2a470fb --- /dev/null +++ b/src/backend/debug/urls.py @@ -0,0 +1,21 @@ +"""Debug Urls to check the layout of emails""" + +from django.urls import path + +from .views import ( + DebugViewHtml, + DebugViewTxt, +) + +urlpatterns = [ + path( + "__debug__/mail/hello_html", + DebugViewHtml.as_view(), + name="debug.mail.hello_html", + ), + path( + "__debug__/mail/hello_txt", + DebugViewTxt.as_view(), + name="debug.mail.hello_txt", + ), +] diff --git a/src/backend/debug/views.py b/src/backend/debug/views.py new file mode 100644 index 0000000..bb00767 --- /dev/null +++ b/src/backend/debug/views.py @@ -0,0 +1,29 @@ +"""Debug Views to check the layout of emails""" + +from django.views.generic.base import TemplateView + + +class DebugBaseView(TemplateView): + """Debug View to check the layout of emails""" + + def get_context_data(self, **kwargs): + """Generates sample datas to have a valid debug email""" + + context = super().get_context_data(**kwargs) + context["title"] = "Development email preview" + context["email"] = "random@gmail.com" + context["fullname"] = "robert" + + return context + + +class DebugViewHtml(DebugBaseView): + """Debug View for HTML Email Layout""" + + template_name = "mail/html/hello.html" + + +class DebugViewTxt(DebugBaseView): + """Debug View for Text Email Layout""" + + template_name = "mail/text/hello.txt" diff --git a/src/backend/people/urls.py b/src/backend/people/urls.py index 1ae7967..1e6926b 100644 --- a/src/backend/people/urls.py +++ b/src/backend/people/urls.py @@ -12,6 +12,8 @@ from drf_spectacular.views import ( SpectacularSwaggerView, ) +from debug import urls as debug_urls + from . import api_urls API_VERSION = settings.API_VERSION @@ -25,6 +27,7 @@ if settings.DEBUG: urlpatterns + staticfiles_urlpatterns() + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + + debug_urls.urlpatterns ) if settings.USE_SWAGGER or settings.DEBUG: diff --git a/src/mail/mjml/hello.mjml b/src/mail/mjml/hello.mjml index 543c8f4..2763154 100644 --- a/src/mail/mjml/hello.mjml +++ b/src/mail/mjml/hello.mjml @@ -2,11 +2,11 @@ - - - - - + + + + +