Skip to content

Commit

Permalink
Hook up preview (#1580)
Browse files Browse the repository at this point in the history
* fetch draft pages if query param is passed

* hook up preview in admin for flexpages

* 👕
  • Loading branch information
TomWoodward authored Aug 21, 2024
1 parent e1d0121 commit 0c5587c
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 4 deletions.
83 changes: 80 additions & 3 deletions openstax/api.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from django.core.exceptions import MultipleObjectsReturned
from django.shortcuts import redirect
from django.urls import reverse, path
from django.conf import settings

from rest_framework.response import Response

from wagtail.models import Page, PageViewRestriction, Site
from wagtail.api.v2.router import WagtailAPIRouter
from wagtail.api.v2.views import PagesAPIViewSet, BaseAPIViewSet
from wagtail.images.api.v2.views import ImagesAPIViewSet
from wagtail.documents.api.v2.views import DocumentsAPIViewSet



class OpenstaxPagesAPIEndpoint(PagesAPIViewSet):
"""
OpenStax custom Pages API endpoint that allows finding pages and books by pk or slug
Expand All @@ -20,7 +22,13 @@ def detail_view(self, request, pk=None, slug=None):
self.lookup_field = 'slug'
param = slug
try:
return super().detail_view(request, param)
instance = self.get_object()

if request.GET.get('draft'):
instance = instance.get_latest_revision_as_object()

serializer = self.get_serializer(instance)
return Response(serializer.data)
except MultipleObjectsReturned:
# Redirect to the listing view, filtered by the relevant slug
# The router is registered with the `wagtailapi` namespace,
Expand All @@ -41,6 +49,75 @@ def get_urlpatterns(cls):
path('find/', cls.as_view({'get': 'find_view'}), name='find'),
]

def get_base_queryset(self):
"""
this method copied from https://github.com/wagtail/wagtail/blob/main/wagtail/api/v2/views.py#L491
so that we can change the line that says:
queryset = Page.objects.all().live()
to:
queryset = Page.objects.all()
when viewing draft content is enabled
"""

request = self.request

if request.GET.get('draft'):
# Get all pages including drafts
queryset = Page.objects.all()
else:
# Get all live pages
queryset = Page.objects.all().live()

# Exclude pages that the user doesn't have access to
restricted_pages = [
restriction.page
for restriction in PageViewRestriction.objects.all().select_related("page")
if not restriction.accept_request(self.request)
]

# Exclude the restricted pages and their descendants from the queryset
for restricted_page in restricted_pages:
queryset = queryset.not_descendant_of(restricted_page, inclusive=True)

# Check if we have a specific site to look for
if "site" in request.GET:
# Optionally allow querying by port
if ":" in request.GET["site"]:
(hostname, port) = request.GET["site"].split(":", 1)
query = {
"hostname": hostname,
"port": port,
}
else:
query = {
"hostname": request.GET["site"],
}
try:
site = Site.objects.get(**query)
except Site.MultipleObjectsReturned:
raise BadRequestError(
"Your query returned multiple sites. Try adding a port number to your site filter."
)
else:
# Otherwise, find the site from the request
site = Site.find_for_request(self.request)

if site:
base_queryset = queryset
queryset = base_queryset.descendant_of(site.root_page, inclusive=True)

# If internationalisation is enabled, include pages from other language trees
if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
for translation in site.root_page.get_translations():
queryset |= base_queryset.descendant_of(translation, inclusive=True)

else:
# No sites configured
queryset = queryset.none()

return queryset


class OpenStaxImagesAPIViewSet(ImagesAPIViewSet):
meta_fields = BaseAPIViewSet.meta_fields + ['tags', 'download_url', 'height', 'width']
Expand Down
13 changes: 12 additions & 1 deletion pages/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django import forms
from django.db import models
from django.shortcuts import render

from modelcluster.fields import ParentalKey
from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel, TitleFieldPanel
Expand Down Expand Up @@ -205,7 +206,6 @@ class RootPage(Page):
]

template = 'page.html'
preview_modes = []
max_count = 1
# TODO: we are allowing this to be built as a child of the homepage. Not ideal.
# Once the home page is released, use something to migrate homepage children to root page and remove this parent type.
Expand All @@ -223,8 +223,19 @@ def get_url_parts(self, *args, **kwargs):

# note that we ignore the slug and hardcode this url to / for the root page
site_id, site_root_url, page_url_relative_to_site_root = url_parts

return (site_id, site_root_url, '/')

def serve_preview(self, request, mode_name):
site_id, site_root, relative_page_url = self.get_url_parts(request)
preview_url = '{}{}/?preview={}'.format(site_root, relative_page_url, mode_name)

return render(
request,
"preview.html",
{"preview_url": preview_url},
)

# subclass of RootPage with a few overrides for subpages
class FlexPage(RootPage):
parent_page_types = ['pages.RootPage', 'pages.FlexPage']
Expand Down
6 changes: 6 additions & 0 deletions pages/templates/preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<style>
body, html {
margin: 0; padding: 0; height: 100%; overflow: hidden;
}
</style>
<iframe src="{{ preview_url }}" width="100%" height="100%" style="border: none;"></iframe>

0 comments on commit 0c5587c

Please sign in to comment.