diff --git a/djangocms_rest/serializers/menus.py b/djangocms_rest/serializers/menus.py index 14a809e..e4c7bf8 100644 --- a/djangocms_rest/serializers/menus.py +++ b/djangocms_rest/serializers/menus.py @@ -28,12 +28,19 @@ def get_children(self, obj: NavigationNode) -> list[dict]: def to_representation(self, obj: NavigationNode) -> dict: """Customize the base representation of the NavigationNode.""" + path = getattr(obj, "api_endpoint", "") + api_endpoint = get_absolute_frontend_url(self.request, path) if path else "" + if self.request._preview_mode: + if "?" in api_endpoint: + api_endpoint += "&preview=1" + else: + api_endpoint += "?preview=1" return { "namespace": getattr(obj, "namespace", None), "title": obj.title, "url": get_absolute_frontend_url(self.request, obj.url) or "", - "api_endpoint": get_absolute_frontend_url(self.request, getattr(obj, "api_endpoint", None)) or "", - "path": getattr(obj, "api_endpoint", ""), + "api_endpoint": api_endpoint, + "path": path, "visible": obj.visible, "selected": obj.selected or obj.attr.get("is_home", False) and getattr(self.request, "is_home", False), "attr": obj.attr, diff --git a/djangocms_rest/serializers/pages.py b/djangocms_rest/serializers/pages.py index 2b12e48..c7cb10d 100644 --- a/djangocms_rest/serializers/pages.py +++ b/djangocms_rest/serializers/pages.py @@ -1,6 +1,7 @@ from django.db import models from cms.models import PageContent +from cms.utils.placeholder import get_declared_placeholders_for_obj from rest_framework import serializers @@ -42,6 +43,11 @@ def get_base_representation(self, page_content: PageContent) -> dict: path = page_content.page.get_path(page_content.language) absolute_url = get_absolute_frontend_url(request, path) api_endpoint = get_absolute_frontend_url(request, page_content.page.get_api_endpoint(page_content.language)) + if self.is_preview: + if "?" in api_endpoint: + api_endpoint += "&preview=1" + else: + api_endpoint += "?preview=1" redirect = str(page_content.redirect or "") xframe_options = str(page_content.xframe_options or "") application_namespace = str(page_content.page.application_namespace or "") @@ -132,7 +138,7 @@ def __init__(self, *args, **kwargs): self.request = self.context.get("request") def to_representation(self, page_content: PageContent) -> dict: - declared_slots = [placeholder.slot for placeholder in page_content.page.get_declared_placeholders()] + declared_slots = [placeholder.slot for placeholder in get_declared_placeholders_for_obj(page_content)] placeholders = [ placeholder for placeholder in page_content.placeholders.all() if placeholder.slot in declared_slots ] diff --git a/djangocms_rest/serializers/placeholders.py b/djangocms_rest/serializers/placeholders.py index a031973..dde3f3c 100644 --- a/djangocms_rest/serializers/placeholders.py +++ b/djangocms_rest/serializers/placeholders.py @@ -11,9 +11,7 @@ class PlaceholderSerializer(serializers.Serializer): slot = serializers.CharField() label = serializers.CharField() language = serializers.CharField() - content = serializers.ListSerializer( - child=serializers.JSONField(), allow_empty=True, required=False - ) + content = serializers.ListSerializer(child=serializers.JSONField(), allow_empty=True, required=False) html = serializers.CharField(default="", required=False) def __init__(self, *args, **kwargs): @@ -64,7 +62,7 @@ def to_representation(self, instance): return super().to_representation(instance) def get_details(self, instance): - return get_absolute_frontend_url( + api_endpoint = get_absolute_frontend_url( self.request, reverse( "placeholder-detail", @@ -76,3 +74,9 @@ def get_details(self, instance): ], ), ) + if self.request._preview_mode: + if "?" in api_endpoint: + api_endpoint += "&preview=1" + else: + api_endpoint += "?preview=1" + return api_endpoint diff --git a/djangocms_rest/views.py b/djangocms_rest/views.py index 0a9a550..3e6c291 100644 --- a/djangocms_rest/views.py +++ b/djangocms_rest/views.py @@ -177,7 +177,7 @@ def get(self, request: Request, language: str, path: str = "") -> Response: try: page_content = getattr(page, self.content_getter)(language, fallback=True) - if page_content is None: + if not page_content: raise PageContent.DoesNotExist() serializer = self.serializer_class(page_content, read_only=True, context={"request": request}) return Response(serializer.data) diff --git a/djangocms_rest/views_base.py b/djangocms_rest/views_base.py index b29cb19..f9723a1 100644 --- a/djangocms_rest/views_base.py +++ b/djangocms_rest/views_base.py @@ -2,6 +2,9 @@ from django.contrib.sites.shortcuts import get_current_site from django.utils.functional import cached_property + +from cms.toolbar.toolbar import CMSToolbar + from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAdminUser from rest_framework.views import APIView @@ -65,12 +68,19 @@ def site(self): return site if site is not None else get_current_site(self.request) def _preview_requested(self): - preview_mode = "preview" in self.request.GET and self.request.GET.get("preview", "").lower() not in ( - "0", - "false", - ) - self.request.toolbar.preview_mode_active = preview_mode - return preview_mode + if not hasattr(self.request, "_preview_mode"): + # Cache to not re-generate toolbar object for preview requests + self.request._preview_mode = "preview" in self.request.GET and self.request.GET.get( + "preview", "" + ).lower() not in ( + "0", + "false", + ) + if self.request._preview_mode: + if not hasattr(self.request, "toolbar"): # Create toolbar if not present to mark preview mode + self.request.toolbar = CMSToolbar(self.request) + self.request.toolbar.preview_mode_active = True + return self.request._preview_mode @property def content_getter(self):