1
1
from typing import Any , Dict , Iterable , Optional , TypeVar
2
2
3
+ from django .contrib .sites .shortcuts import get_current_site
3
4
from django .db import models
4
- from django .utils .html import escape , escapejs , mark_safe
5
+ from django .utils .html import escape , mark_safe
5
6
7
+ from cms .models import Placeholder
6
8
from cms .plugin_rendering import ContentRenderer
7
- from rest_framework import serializers
9
+ from cms . utils . plugins import get_plugins
8
10
11
+ from rest_framework import serializers
9
12
from djangocms_rest .serializers .placeholders import PlaceholderSerializer
13
+ from djangocms_rest .serializers .utils .cache import get_placeholder_rest_cache , set_placeholder_rest_cache
10
14
11
15
12
16
base_exclude = {
@@ -49,7 +53,7 @@ def get_auto_model_serializer(model_class: type[ModelType]) -> type:
49
53
)
50
54
51
55
52
- def render_cms_plugin (
56
+ def serialize_cms_plugin (
53
57
instance : Optional [Any ], context : Dict [str , Any ]
54
58
) -> Optional [Dict [str , Any ]]:
55
59
if not instance or not hasattr (instance , "get_plugin_instance" ):
@@ -168,7 +172,7 @@ def highlight_list(json_data: list) -> dict[str, str]:
168
172
169
173
class RESTRenderer (ContentRenderer ):
170
174
"""
171
- A custom renderer that uses the render_cms_plugin function to render
175
+ A custom renderer that uses the serialize_cms_plugin function to render
172
176
CMS plugins in a RESTful way.
173
177
"""
174
178
placeholder_edit_template = "{content}{plugin_js}{placeholder_js}"
@@ -177,9 +181,9 @@ def render_plugin(
177
181
self , instance , context , placeholder = None , editable : bool = False
178
182
):
179
183
"""
180
- Render a CMS plugin instance using the render_cms_plugin function.
184
+ Render a CMS plugin instance using the serialize_cms_plugin function.
181
185
"""
182
- data = render_cms_plugin (instance , context ) or {}
186
+ data = serialize_cms_plugin (instance , context ) or {}
183
187
children = [
184
188
self .render_plugin (
185
189
child , context , placeholder = placeholder , editable = editable
@@ -234,3 +238,68 @@ def get_plugins_and_placeholder_lot(
234
238
placeholder , language , context , editable = editable , template = template
235
239
)
236
240
yield f'<div class="cms-placeholder cms-placeholder-{ placeholder .pk } "></div>'
241
+
242
+ def serialize_placeholder (self , placeholder , context , language , use_cache = True ):
243
+ context .update ({"request" : self .request })
244
+ if use_cache and placeholder .cache_placeholder :
245
+ use_cache = self .placeholder_cache_is_enabled ()
246
+ else :
247
+ use_cache = False
248
+
249
+ if use_cache :
250
+ cached_value = get_placeholder_rest_cache (
251
+ placeholder ,
252
+ lang = language ,
253
+ site_id = get_current_site (self .request ).pk ,
254
+ request = self .request ,
255
+ )
256
+ else :
257
+ cached_value = None
258
+
259
+ if cached_value is not None :
260
+ # User has opted to use the cache
261
+ # and there is something in the cache
262
+ return cached_value ["content" ]
263
+
264
+ plugin_content = self .serialize_plugins (
265
+ placeholder ,
266
+ language = language ,
267
+ context = context ,
268
+ )
269
+
270
+ if use_cache :
271
+ set_placeholder_rest_cache (
272
+ placeholder ,
273
+ lang = language ,
274
+ site_id = get_current_site (self .request ).pk ,
275
+ content = plugin_content ,
276
+ request = self .request ,
277
+ )
278
+
279
+ if placeholder .pk not in self ._rendered_placeholders :
280
+ # First time this placeholder is rendered
281
+ self ._rendered_placeholders [placeholder .pk ] = plugin_content
282
+
283
+ return plugin_content
284
+
285
+ def serialize_plugins (
286
+ self , placeholder : Placeholder , language : str , context : dict
287
+ ) -> list :
288
+ plugins = get_plugins (
289
+ self .request ,
290
+ placeholder = placeholder ,
291
+ lang = language ,
292
+ template = None ,
293
+ )
294
+
295
+ def serialize_children (child_plugins ):
296
+ for plugin in child_plugins :
297
+ plugin_content = serialize_cms_plugin (plugin , context )
298
+ if getattr (plugin , "child_plugin_instances" , None ):
299
+ plugin_content ["children" ] = serialize_children (
300
+ plugin .child_plugin_instances
301
+ )
302
+ if plugin_content :
303
+ yield plugin_content
304
+
305
+ return list (serialize_children (plugins ))
0 commit comments