Plain is headed towards 1.0! Subscribe for development updates →

 1from plain.csrf.middleware import get_token
 2from plain.exceptions import ImproperlyConfigured
 3from plain.runtime import settings
 4from plain.templates import Template, TemplateFileMissing
 5from plain.utils.functional import lazy
 6from plain.utils.html import format_html
 7from plain.utils.safestring import SafeString
 8
 9from .base import View
10
11
12def csrf_input(request):
13    return format_html(
14        '<input type="hidden" name="{}" value="{}">',
15        settings.CSRF_FIELD_NAME,
16        get_token(request),
17    )
18
19
20csrf_input_lazy = lazy(csrf_input, SafeString, str)
21csrf_token_lazy = lazy(get_token, str)
22
23
24class TemplateView(View):
25    """
26    Render a template.
27    """
28
29    template_name: str | None = None
30
31    def __init__(self, template_name=None):
32        # Allow template_name to be passed in as_view()
33        self.template_name = template_name or self.template_name
34
35    def get_template_context(self) -> dict:
36        return {
37            "request": self.request,
38            "template_names": self.get_template_names(),
39            "csrf_input": csrf_input_lazy(self.request),
40            "csrf_token": csrf_token_lazy(self.request),
41            "DEBUG": settings.DEBUG,
42        }
43
44    def get_template_names(self) -> list[str]:
45        """
46        Return a list of template names to be used for the request.
47        """
48        if self.template_name:
49            return [self.template_name]
50
51        return []
52
53    def get_template(self) -> Template:
54        template_names = self.get_template_names()
55
56        if not template_names:
57            raise ImproperlyConfigured(
58                f"{self.__class__.__name__} requires a template_name or get_template_names()."
59            )
60
61        for template_name in template_names:
62            try:
63                return Template(template_name)
64            except TemplateFileMissing:
65                pass
66
67        raise TemplateFileMissing(template_names)
68
69    def render_template(self) -> str:
70        return self.get_template().render(self.get_template_context())
71
72    def get(self):
73        return self.render_template()