11from cms .models import Page
22from cms .plugin_base import CMSPluginBase , PluginMenuItem
33from cms .plugin_pool import plugin_pool
4- from cms .toolbar .utils import get_object_edit_url
4+ from cms .toolbar .utils import get_object_edit_url , get_plugin_toolbar_info , get_plugin_tree
55from cms .utils import get_language_from_request
66from cms .utils .permissions import (
77 get_model_permission_codename ,
@@ -43,6 +43,13 @@ def get_render_template(self, context, instance, placeholder):
4343 return "djangocms_alias/alias_recursive.html"
4444 return f"djangocms_alias/{ instance .template } /alias.html"
4545
46+ @classmethod
47+ def _get_allowed_root_plugins (cls ):
48+ if not hasattr (cls , "_cached_allowed_root_plugins" ):
49+ cls ._cached_allowed_root_plugins = set (plugin_pool .get_all_plugins (root_plugin = True ))
50+ print ("==>" , cls ._cached_allowed_root_plugins )
51+ return cls ._cached_allowed_root_plugins
52+
4653 @classmethod
4754 def get_extra_plugin_menu_items (cls , request , plugin ):
4855 if plugin .plugin_type == cls .__name__ :
@@ -82,15 +89,19 @@ def get_extra_plugin_menu_items(cls, request, plugin):
8289 "plugin" : plugin .pk ,
8390 "language" : get_language_from_request (request ),
8491 }
85- endpoint = add_url_parameters (admin_reverse (CREATE_ALIAS_URL_NAME ), ** data )
86- return [
87- PluginMenuItem (
88- _ ("Create Alias" ),
89- endpoint ,
90- action = "modal" ,
91- attributes = {"cms-icon" : "alias" },
92- ),
93- ]
92+ # Check if the plugin can become root: Should be allowed as a root plugin (in the alias)
93+ can_become_alias = plugin .get_plugin_class () in cls ._get_allowed_root_plugins ()
94+ if can_become_alias :
95+ endpoint = add_url_parameters (admin_reverse (CREATE_ALIAS_URL_NAME ), ** data )
96+ return [
97+ PluginMenuItem (
98+ _ ("Create Alias" ),
99+ endpoint ,
100+ action = "modal" ,
101+ attributes = {"cms-icon" : "alias" },
102+ ),
103+ ]
104+ return []
94105
95106 @classmethod
96107 def get_extra_placeholder_menu_items (cls , request , placeholder ):
@@ -150,6 +161,7 @@ def detach_alias_plugin(cls, plugin, language):
150161 source_plugins = plugin .alias .get_plugins (language , show_draft_content = True ) # We're in edit mode
151162 target_placeholder = plugin .placeholder
152163 plugin_position = plugin .position
164+ plugin_parent = plugin .parent
153165 target_placeholder .delete_plugin (plugin )
154166 if source_plugins :
155167 if target_last_plugin := target_placeholder .get_last_plugin (plugin .language ):
@@ -163,6 +175,7 @@ def detach_alias_plugin(cls, plugin, language):
163175 source_plugins ,
164176 placeholder = target_placeholder ,
165177 language = language ,
178+ root_plugin = plugin_parent ,
166179 start_positions = {language : plugin_position },
167180 )
168181 return []
@@ -242,10 +255,13 @@ def create_alias_view(self, request):
242255 emit_content_change ([alias_content ])
243256
244257 if replace :
245- return self .render_close_frame (
258+ plugin = create_form .cleaned_data .get ("plugin" )
259+ placeholder = create_form .cleaned_data .get ("placeholder" )
260+ return self .render_replace_response (
246261 request ,
247- obj = alias_plugin ,
248- action = "reload" ,
262+ new_plugins = [alias_plugin ],
263+ source_placeholder = placeholder ,
264+ source_plugin = plugin ,
249265 )
250266 return TemplateResponse (request , "admin/cms/page/close_frame.html" )
251267
@@ -276,17 +292,54 @@ def detach_alias_plugin_view(self, request, plugin_pk):
276292 if not can_detach :
277293 raise PermissionDenied
278294
279- self .detach_alias_plugin (
295+ copied_plugins = self .detach_alias_plugin (
280296 plugin = instance ,
281297 language = language ,
282298 )
283299
300+ return self .render_replace_response (
301+ request ,
302+ new_plugins = copied_plugins ,
303+ source_plugin = instance ,
304+ )
305+
284306 return self .render_close_frame (
285307 request ,
286308 obj = instance ,
287309 action = "reload" ,
288310 )
289311
312+ def render_replace_response (self , request , new_plugins , source_placeholder = None , source_plugin = None ):
313+ move_plugins , add_plugins = [], []
314+ for plugin in new_plugins :
315+ root = plugin .parent .get_bound_plugin () if plugin .parent else plugin
316+
317+ plugins = [root ] + list (root .get_descendants ())
318+
319+ plugin_order = plugin .placeholder .get_plugin_tree_order (
320+ plugin .language ,
321+ parent_id = plugin .parent_id ,
322+ )
323+ plugin_tree = get_plugin_tree (request , plugins )
324+ move_data = get_plugin_toolbar_info (plugin )
325+ move_data ["plugin_order" ] = plugin_order
326+ move_data .update (plugin_tree )
327+ move_plugins .append (move_data )
328+ add_plugins .append ({** get_plugin_toolbar_info (plugin ), "structure" : plugin_tree })
329+ data = {
330+ "addedPlugins" : add_plugins ,
331+ "movedPlugins" : move_plugins ,
332+ "is_popup" : True ,
333+ }
334+ if source_plugin is not None :
335+ data ["replacedPlugin" ] = get_plugin_toolbar_info (source_plugin )
336+ if source_placeholder is not None :
337+ data ["replacedPlaceholder" ] = {
338+ "placeholder_id" : source_placeholder .pk ,
339+ "deleted" : True ,
340+ }
341+ return self .render_close_frame (request , obj = None , action = "ALIAS_REPLACE" , extra_data = data )
342+
290343 def alias_usage_view (self , request , pk ):
291344 if not request .user .is_staff :
292345 raise PermissionDenied
0 commit comments