Plain is headed towards 1.0! Subscribe for development updates →

 1from functools import cached_property
 2
 3from plain.assets.views import AssetView
 4from plain.http import Http404, ResponsePermanentRedirect, ResponseRedirect
 5from plain.views import TemplateView, View
 6
 7from .exceptions import PageNotFoundError, RedirectPageError
 8from .registry import pages_registry
 9
10
11class PageViewMixin:
12    @cached_property
13    def page(self):
14        url_name = self.request.resolver_match.url_name
15
16        try:
17            return pages_registry.get_page(url_name)
18        except PageNotFoundError:
19            raise Http404()
20
21
22class PageView(PageViewMixin, TemplateView):
23    template_name = "page.html"
24
25    def get_template_names(self) -> list[str]:
26        """
27        Allow for more specific user templates like
28        markdown.html or html.html
29        """
30        if template_name := self.page.get_template_name():
31            return [template_name]
32
33        return super().get_template_names()
34
35    def get_template_context(self):
36        context = super().get_template_context()
37        context["page"] = self.page
38        self.page.set_template_context(context)  # Pass the standard context through
39        return context
40
41
42class PageRedirectView(PageViewMixin, View):
43    def get(self):
44        url = self.page.vars.get("url")
45
46        if not url:
47            raise RedirectPageError("Redirect page is missing a url")
48
49        if self.page.vars.get("temporary", True):
50            return ResponseRedirect(url)
51        else:
52            return ResponsePermanentRedirect(url)
53
54
55class PageAssetView(PageViewMixin, AssetView):
56    def get_url_path(self):
57        return self.page.get_url_path()
58
59    def get_asset_path(self, path):
60        return self.page.absolute_path
61
62    def get_debug_asset_path(self, path):
63        return self.page.absolute_path