1fromfunctoolsimportcached_property 2 3fromplain.assets.viewsimportAssetView 4fromplain.httpimportHttp404,ResponsePermanentRedirect,ResponseRedirect 5fromplain.viewsimportTemplateView,View 6 7from.exceptionsimportPageNotFoundError,RedirectPageError 8from.registryimportpages_registry 91011classPageViewMixin:12@cached_property13defpage(self):14url_name=self.request.resolver_match.url_name1516try:17returnpages_registry.get_page(url_name)18exceptPageNotFoundError:19raiseHttp404()202122classPageView(PageViewMixin,TemplateView):23template_name="page.html"2425defget_template_names(self)->list[str]:26"""27 Allow for more specific user templates like28 markdown.html or html.html29 """30iftemplate_name:=self.page.get_template_name():31return[template_name]3233returnsuper().get_template_names()3435defget_template_context(self):36context=super().get_template_context()37context["page"]=self.page38self.page.set_template_context(context)# Pass the standard context through39returncontext404142classPageRedirectView(PageViewMixin,View):43defget(self):44url=self.page.vars.get("url")4546ifnoturl:47raiseRedirectPageError("Redirect page is missing a url")4849ifself.page.vars.get("temporary",True):50returnResponseRedirect(url)51else:52returnResponsePermanentRedirect(url)535455classPageAssetView(PageViewMixin,AssetView):56defget_url_path(self):57returnself.page.get_url_path()5859defget_asset_path(self,path):60returnself.page.absolute_path6162defget_debug_asset_path(self,path):63returnself.page.absolute_path