From d75d4d911929a2fd5902ccb9d83eaebd8c001484 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Thu, 25 Jul 2024 20:03:06 +0200 Subject: [PATCH] Experimental Django template loader. --- conftest.py | 7 ++++++- htpy/django.py | 30 ++++++++++++++++++++++++++++++ tests/test_django.py | 30 ++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 htpy/django.py diff --git a/conftest.py b/conftest.py index 4b33e2a..a32418b 100644 --- a/conftest.py +++ b/conftest.py @@ -6,5 +6,10 @@ def django_env() -> None: import django from django.conf import settings - settings.configure(TEMPLATES=[{"BACKEND": "django.template.backends.django.DjangoTemplates"}]) + settings.configure( + TEMPLATES=[ + {"BACKEND": "django.template.backends.django.DjangoTemplates"}, + {"BACKEND": "htpy.django.HTPYTemplates", "NAME": "htpy"}, + ] + ) django.setup() diff --git a/htpy/django.py b/htpy/django.py new file mode 100644 index 0000000..707672d --- /dev/null +++ b/htpy/django.py @@ -0,0 +1,30 @@ +from collections.abc import Callable +from typing import Any + +from django.http import HttpRequest +from django.template import Context, TemplateDoesNotExist + +from . import Element, render_node + + +class _HTPYTemplate: + def __init__(self, func: Callable[[Context | None, HttpRequest | None], Element]) -> None: + self.func = func + + def render(self, context: Context | None, request: HttpRequest | None) -> str: + return render_node(self.func(context, request)) + + +class HTPYTemplates: + def __init__(self, config: Any): + pass + + def get_template(self, name: str) -> _HTPYTemplate: + from django.utils.module_loading import import_string + + try: + func = import_string(name) + except ImportError: + raise TemplateDoesNotExist(name) + + return _HTPYTemplate(func) diff --git a/tests/test_django.py b/tests/test_django.py index 93a2202..08327b2 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -1,10 +1,14 @@ +from typing import Any + import pytest from django.forms.utils import ErrorList -from django.template import Context, Template +from django.http import HttpRequest +from django.template import Context, Template, TemplateDoesNotExist +from django.template.loader import render_to_string from django.utils.html import escape from django.utils.safestring import SafeString -from htpy import div, li, ul +from htpy import Element, Node, div, li, ul pytestmark = pytest.mark.usefixtures("django_env") @@ -29,3 +33,25 @@ def test_explicit_escape() -> None: def test_errorlist() -> None: result = div[ErrorList(["my error"])] assert str(result) == """
""" + + +def my_template(context: dict[str, Any], request: HttpRequest | None) -> Element: + return div[f"hey {context['name']}"] + + +def my_template_fragment(context: dict[str, Any], request: HttpRequest | None) -> Node: + return [div[f"hey {context['name']}"]] + + +class Test_custom_template_loader: + def test_render(self) -> None: + result = render_to_string(__name__ + ".my_template", {"name": "andreas"}) + assert result == "
hey andreas
" + + def test_list_fragment(self) -> None: + result = render_to_string(__name__ + ".my_template_fragment", {"name": "andreas"}) + assert result == "
hey andreas
" + + def test_template_does_not_exist(self) -> None: + with pytest.raises(TemplateDoesNotExist): + render_to_string(__name__ + ".fooasdf", {})