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 ,
@@ -38,11 +38,36 @@ class Alias(CMSPluginBase):
3838 model = AliasPlugin
3939 form = AliasPluginForm
4040
41+ create_alias_fieldset = (
42+ (
43+ None ,
44+ {
45+ "fields" : (
46+ "name" ,
47+ "site" ,
48+ "category" ,
49+ "replace" ,
50+ "plugin" ,
51+ "placeholder" ,
52+ "language" ,
53+ ),
54+ },
55+ ),
56+ )
57+
58+ autocomplete_fields = ["alias" ]
59+
4160 def get_render_template (self , context , instance , placeholder ):
4261 if isinstance (instance .placeholder .source , AliasContent ) and instance .is_recursive ():
4362 return "djangocms_alias/alias_recursive.html"
4463 return f"djangocms_alias/{ instance .template } /alias.html"
4564
65+ @classmethod
66+ def _get_allowed_root_plugins (cls ):
67+ if not hasattr (cls , "_cached_allowed_root_plugins" ):
68+ cls ._cached_allowed_root_plugins = set (plugin_pool .get_all_plugins (root_plugin = True ))
69+ return cls ._cached_allowed_root_plugins
70+
4671 @classmethod
4772 def get_extra_plugin_menu_items (cls , request , plugin ):
4873 if plugin .plugin_type == cls .__name__ :
@@ -82,15 +107,19 @@ def get_extra_plugin_menu_items(cls, request, plugin):
82107 "plugin" : plugin .pk ,
83108 "language" : get_language_from_request (request ),
84109 }
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- ]
110+ # Check if the plugin can become root: Should be allowed as a root plugin (in the alias)
111+ can_become_alias = plugin .get_plugin_class () in cls ._get_allowed_root_plugins ()
112+ if can_become_alias :
113+ endpoint = add_url_parameters (admin_reverse (CREATE_ALIAS_URL_NAME ), ** data )
114+ return [
115+ PluginMenuItem (
116+ _ ("Create Alias" ),
117+ endpoint ,
118+ action = "modal" ,
119+ attributes = {"cms-icon" : "alias" },
120+ ),
121+ ]
122+ return []
94123
95124 @classmethod
96125 def get_extra_placeholder_menu_items (cls , request , placeholder ):
@@ -150,6 +179,7 @@ def detach_alias_plugin(cls, plugin, language):
150179 source_plugins = plugin .alias .get_plugins (language , show_draft_content = True ) # We're in edit mode
151180 target_placeholder = plugin .placeholder
152181 plugin_position = plugin .position
182+ plugin_parent = plugin .parent
153183 target_placeholder .delete_plugin (plugin )
154184 if source_plugins :
155185 if target_last_plugin := target_placeholder .get_last_plugin (plugin .language ):
@@ -163,6 +193,7 @@ def detach_alias_plugin(cls, plugin, language):
163193 source_plugins ,
164194 placeholder = target_placeholder ,
165195 language = language ,
196+ root_plugin = plugin_parent ,
166197 start_positions = {language : plugin_position },
167198 )
168199 return []
@@ -215,17 +246,28 @@ def create_alias_view(self, request):
215246 )
216247
217248 if not create_form .is_valid ():
218- opts = self .model ._meta
249+ from django .contrib import admin
250+
251+ fieldsets = self .create_alias_fieldset
252+ admin_form = admin .helpers .AdminForm (create_form , fieldsets , {})
253+ self .opts = self .model ._meta
254+ self .admin_site = admin .site
219255 context = {
220- "form" : create_form ,
221- "has_change_permission" : True ,
222- "opts" : opts ,
223- "root_path" : admin_reverse ("index" ),
256+ "title" : _ ("Create Alias" ),
257+ "adminform" : admin_form ,
224258 "is_popup" : True ,
225- "app_label" : opts .app_label ,
226- "media" : (Alias ().media + create_form .media ),
259+ "media" : admin_form .media ,
260+ "errors" : create_form .errors ,
261+ "preserved_filters" : self .get_preserved_filters (request ),
262+ "inline_admin_formsets" : [],
227263 }
228- return TemplateResponse (request , "djangocms_alias/create_alias.html" , context )
264+ return self .render_change_form (
265+ request ,
266+ context ,
267+ add = True ,
268+ change = False ,
269+ obj = None ,
270+ )
229271
230272 plugins = create_form .get_plugins ()
231273
@@ -242,10 +284,13 @@ def create_alias_view(self, request):
242284 emit_content_change ([alias_content ])
243285
244286 if replace :
245- return self .render_close_frame (
287+ plugin = create_form .cleaned_data .get ("plugin" )
288+ placeholder = create_form .cleaned_data .get ("placeholder" )
289+ return self .render_replace_response (
246290 request ,
247- obj = alias_plugin ,
248- action = "reload" ,
291+ new_plugins = [alias_plugin ],
292+ source_placeholder = placeholder ,
293+ source_plugin = plugin ,
249294 )
250295 return TemplateResponse (request , "admin/cms/page/close_frame.html" )
251296
@@ -258,6 +303,7 @@ def detach_alias_plugin_view(self, request, plugin_pk):
258303 if request .method == "GET" :
259304 opts = self .model ._meta
260305 context = {
306+ "title" : _ ("Detach Alias" ),
261307 "has_change_permission" : True ,
262308 "opts" : opts ,
263309 "root_path" : admin_reverse ("index" ),
@@ -276,17 +322,48 @@ def detach_alias_plugin_view(self, request, plugin_pk):
276322 if not can_detach :
277323 raise PermissionDenied
278324
279- self .detach_alias_plugin (
325+ copied_plugins = self .detach_alias_plugin (
280326 plugin = instance ,
281327 language = language ,
282328 )
283329
284- return self .render_close_frame (
330+ return self .render_replace_response (
285331 request ,
286- obj = instance ,
287- action = "reload" ,
332+ new_plugins = copied_plugins ,
333+ source_plugin = instance ,
288334 )
289335
336+ def render_replace_response (self , request , new_plugins , source_placeholder = None , source_plugin = None ):
337+ move_plugins , add_plugins = [], []
338+ for plugin in new_plugins :
339+ root = plugin .parent .get_bound_plugin () if plugin .parent else plugin
340+
341+ plugins = [root ] + list (root .get_descendants ())
342+
343+ plugin_order = plugin .placeholder .get_plugin_tree_order (
344+ plugin .language ,
345+ parent_id = plugin .parent_id ,
346+ )
347+ plugin_tree = get_plugin_tree (request , plugins , target_plugin = root )
348+ move_data = get_plugin_toolbar_info (plugin )
349+ move_data ["plugin_order" ] = plugin_order
350+ move_data .update (plugin_tree )
351+ move_plugins .append (move_data )
352+ add_plugins .append ({** get_plugin_toolbar_info (plugin ), "structure" : plugin_tree })
353+ data = {
354+ "addedPlugins" : add_plugins ,
355+ "movedPlugins" : move_plugins ,
356+ "is_popup" : True ,
357+ }
358+ if source_plugin and source_plugin .pk :
359+ data ["replacedPlugin" ] = get_plugin_toolbar_info (source_plugin )
360+ if source_placeholder and source_placeholder .pk :
361+ data ["replacedPlaceholder" ] = {
362+ "placeholder_id" : source_placeholder .pk ,
363+ "deleted" : True ,
364+ }
365+ return self .render_close_frame (request , obj = None , action = "ALIAS_REPLACE" , extra_data = data )
366+
290367 def alias_usage_view (self , request , pk ):
291368 if not request .user .is_staff :
292369 raise PermissionDenied
0 commit comments