Plain is headed towards 1.0! Subscribe for development updates →

 1from plain.assets.urls import get_asset_url
 2from plain.http import ResponseRedirect
 3from plain.runtime import settings
 4from plain.utils.module_loading import import_string
 5from plain.views import FormView, View
 6from plain.views.csrf import CsrfExemptViewMixin
 7
 8
 9class SupportFormView(FormView):
10    template_name = "support/page.html"
11
12    def get_form(self):
13        form_slug = self.url_kwargs["form_slug"]
14        form_class = import_string(settings.SUPPORT_FORMS[form_slug])
15        return form_class(**self.get_form_kwargs())
16
17    def get_template_context(self):
18        context = super().get_template_context()
19        form_slug = self.url_kwargs["form_slug"]
20        context["form_action"] = self.request.build_absolute_uri()
21        context["form_template_name"] = f"support/forms/{form_slug}.html"
22        context["success_template_name"] = f"support/success/{form_slug}.html"
23        context["success"] = self.request.query_params.get("success") == "true"
24        return context
25
26    def get_form_kwargs(self):
27        kwargs = super().get_form_kwargs()
28        kwargs["user"] = self.request.user
29        kwargs["form_slug"] = self.url_kwargs["form_slug"]
30        return kwargs
31
32    def form_valid(self, form):
33        entry = form.save()
34        form.notify(entry)
35        return super().form_valid(form)
36
37    def get_success_url(self, form):
38        # Redirect to the same view and template so we
39        # don't have to create two additional views for iframe and non-iframe.
40        return "?success=true"
41
42
43class SupportIFrameView(CsrfExemptViewMixin, SupportFormView):
44    template_name = "support/iframe.html"
45
46    def get_response(self):
47        response = super().get_response()
48
49        # X-Frame-Options are typically in DEFAULT_RESPONSE_HEADERS,
50        # which will know to drop the header completely if an empty string.
51        # We can't del/pop it because DEFAULT_RESPONSE_HEADERS may add it back.
52        response.headers["X-Frame-Options"] = ""
53
54        return response
55
56
57class SupportFormJSView(View):
58    def get(self):
59        return ResponseRedirect(get_asset_url("support/embed.js"))