Skip to content

Commit 346bd63

Browse files
committed
Add autolinks
1 parent ea97287 commit 346bd63

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

djangocms_rest/plugin_rendering.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from typing import Any, Iterable, Optional, TypeVar
33

44
from django.contrib.sites.shortcuts import get_current_site
5+
from django.core.exceptions import ValidationError
6+
from django.core.validators import URLValidator
57
from django.db import models
68
from django.utils.html import escape, mark_safe
79

@@ -88,14 +90,27 @@ def escapestr(s: str) -> str:
8890
return escape(json.dumps(s)[1:-1]) # Remove quotes added by json.dumps
8991

9092

93+
def is_valid_url(url):
94+
validator = URLValidator()
95+
try:
96+
validator(url)
97+
return True
98+
except ValidationError:
99+
return False
100+
101+
91102
def highlight_data(json_data: Any, drop_frame: bool = False) -> str:
92103
"""
93104
Highlight single JSON data element.
94105
"""
95106
if isinstance(json_data, str):
107+
classes = "str"
96108
if len(json_data) > 60:
97-
return f'<span class="str">"<span class="ellipsis">{escapestr(json_data)}</span>"</span>'
98-
return f'<span class="str">"{escapestr(json_data)}"</span>'
109+
classes = "str ellipsis"
110+
111+
if is_valid_url(json_data):
112+
return f'<span class="{ classes }">"<a href="{ json_data }">{escapestr(json_data)}</a>"</span>'
113+
return f'<span class="{ classes }">"{escapestr(json_data)}"</span>'
99114
if isinstance(json_data, bool):
100115
return f'<span class="bool">{str(json_data).lower()}</span>'
101116
if isinstance(json_data, (int, float)):

djangocms_rest/serializers/pages.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ def to_representation(self, page_content: PageContent) -> dict:
166166
data = self.get_base_representation(page_content)
167167
data["placeholders"] = PlaceholderRelationSerializer(
168168
placeholders_data,
169+
language=page_content.language,
169170
many=True,
171+
context={"request": self.request},
170172
).data
171173
return data
172174

@@ -193,6 +195,8 @@ def to_representation(self, page_content: PageContent) -> dict:
193195
data = self.get_base_representation(page_content)
194196
data["placeholders"] = PlaceholderRelationSerializer(
195197
placeholders_data,
198+
language=page_content.language,
199+
context={"request": self.request},
196200
many=True,
197201
).data
198202
return data

djangocms_rest/serializers/placeholders.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from django.template import Context
2+
from django.urls import reverse
23

34
from rest_framework import serializers
45

56
from djangocms_rest.serializers.utils.render import render_html
7+
from djangocms_rest.utils import get_absolute_frontend_url
68

79

810
class PlaceholderSerializer(serializers.Serializer):
@@ -49,7 +51,28 @@ class PlaceholderRelationSerializer(serializers.Serializer):
4951
content_type_id = serializers.IntegerField()
5052
object_id = serializers.IntegerField()
5153
slot = serializers.CharField()
54+
details = serializers.URLField()
5255

5356
def __init__(self, *args, **kwargs):
57+
language = kwargs.pop("language", None)
5458
super().__init__(*args, **kwargs)
5559
self.request = self.context.get("request")
60+
self.language = language
61+
62+
def to_representation(self, instance):
63+
instance["details"] = self.get_details(instance)
64+
return super().to_representation(instance)
65+
66+
def get_details(self, instance):
67+
return get_absolute_frontend_url(
68+
self.request,
69+
reverse(
70+
"placeholder-detail",
71+
args=[
72+
self.language,
73+
instance.get("content_type_id"),
74+
instance.get("object_id"),
75+
instance.get("slot"),
76+
],
77+
),
78+
)

djangocms_rest/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.contrib.sites.shortcuts import get_current_site
2+
from django.utils.functional import lazy
23

34
from cms.models import Page, PageContent, Placeholder
45
from cms.utils.conf import get_languages
@@ -22,7 +23,6 @@
2223
from djangocms_rest.serializers.plugins import PluginDefinitionSerializer
2324
from djangocms_rest.utils import get_object, get_site_filtered_queryset
2425
from djangocms_rest.views_base import BaseAPIView, BaseListAPIView
25-
from django.utils.functional import lazy
2626

2727

2828
try:
@@ -225,6 +225,7 @@ class PluginDefinitionView(BaseAPIView):
225225
"""
226226

227227
serializer_class = PluginDefinitionSerializer
228+
queryset = Page.objects.none() # Dummy queryset to satisfy DRF
228229

229230
def get(self, request: Request) -> Response:
230231
"""Get all plugin definitions"""

tests/test_plugin_renderer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def test_edit_endpoint(self):
184184
# Test image plugin resolves image URL
185185
self.assertContains(
186186
response,
187-
f'"filer_image"</span>: <span class="str">"<span class="ellipsis">http://testserver{self.image_plugin.filer_image.url}</span>"</span>',
187+
f'"filer_image"</span>: <span class="str ellipsis">"http://testserver{self.image_plugin.filer_image.url}"</span>',
188188
)
189189

190190
# Test for rendering of numbers

0 commit comments

Comments
 (0)