Skip to content

Commit c146769

Browse files
authored
fix: Create alias view errored (#308)
* fix: Create alias view errored * fix: tests * fix: Plugins cache * fix: Improve databridge interface * fix: Reload browser after "Create alias..." to ensure frontend data consistency
1 parent 66ee5c0 commit c146769

File tree

5 files changed

+39
-60
lines changed

5 files changed

+39
-60
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.idea/
55
.tox/
66
.eggs/
7+
.vscode/
78
dist/
89
!djangocms_alias/static/djangocms_alias/js/dist/
910
build/

djangocms_alias/cms_plugins.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from copy import copy
2-
31
from cms.plugin_base import CMSPluginBase, PluginMenuItem
42
from cms.plugin_pool import plugin_pool
53
from cms.toolbar.utils import get_object_edit_url
@@ -140,26 +138,24 @@ def can_detach(cls, user, target_placeholder, plugins):
140138

141139
@classmethod
142140
def detach_alias_plugin(cls, plugin, language):
143-
source_placeholder = plugin.alias.get_placeholder(language, show_draft_content=True) # We're in edit mode
141+
source_plugins = plugin.alias.get_plugins(language, show_draft_content=True) # We're in edit mode
144142
target_placeholder = plugin.placeholder
143+
plugin_position = plugin.position
144+
plugin_parent = plugin.parent
145+
target_placeholder.delete_plugin(plugin)
146+
if source_plugins:
147+
if target_last_plugin := target_placeholder.get_last_plugin(plugin.language):
148+
target_placeholder._shift_plugin_positions(
149+
language,
150+
start=plugin_position,
151+
offset=len(source_plugins) + target_last_plugin.position + 1, # enough space to shift back
152+
)
145153

146-
# Deleting uses a copy of a plugin to preserve pk on existing
147-
# ``plugin`` object. This is done due to
148-
# plugin.get_plugin_toolbar_info requiring a PK in a passed
149-
# instance.
150-
target_placeholder.delete_plugin(copy(plugin))
151-
target_placeholder._shift_plugin_positions(
152-
language,
153-
plugin.position,
154-
offset=target_placeholder.get_last_plugin_position(language),
155-
)
156-
if source_placeholder:
157-
source_plugins = source_placeholder.get_plugins_list()
158-
copied_plugins = copy_plugins_to_placeholder(
154+
return copy_plugins_to_placeholder(
159155
source_plugins,
160156
placeholder=target_placeholder,
161157
language=language,
162-
start_positions={language: plugin.position},
158+
root_plugin=plugin_parent,
159+
start_positions={language: plugin_position},
163160
)
164-
return copied_plugins
165161
return []

djangocms_alias/models.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -193,16 +193,17 @@ def get_placeholder(self, language=None, show_draft_content=False):
193193
content = self.get_content(language=language, show_draft_content=show_draft_content)
194194
return getattr(content, "placeholder", None)
195195

196-
def get_plugins(self, language=None):
196+
def get_plugins(self, language=None, show_draft_content=False):
197197
if not language:
198198
language = get_language()
199+
cache_key = f"{language}-{show_draft_content}"
199200
try:
200-
return self._plugins_cache[language]
201+
return self._plugins_cache[cache_key]
201202
except KeyError:
202-
placeholder = self.get_placeholder(language)
203+
placeholder = self.get_placeholder(language, show_draft_content=show_draft_content)
203204
plugins = placeholder.get_plugins_list() if placeholder else []
204-
self._plugins_cache[language] = plugins
205-
return self._plugins_cache[language]
205+
self._plugins_cache[cache_key] = plugins
206+
return self._plugins_cache[cache_key]
206207

207208
def get_languages(self):
208209
if not self._content_languages_cache:
@@ -307,25 +308,27 @@ def populate(self, replaced_placeholder=None, replaced_plugin=None, plugins=None
307308
placeholder=self.placeholder,
308309
)
309310
return
310-
311311
if replaced_placeholder:
312-
plugins = replaced_placeholder.get_plugins(self.language)
313-
placeholder = replaced_placeholder
314-
add_plugin_kwargs = {}
315-
else:
316-
plugins = CMSPlugin.objects.filter(
317-
id__in=[replaced_plugin.pk] + replaced_plugin._get_descendants_ids(),
312+
replaced_placeholder.cmsplugin_set.update(placeholder=self.placeholder)
313+
return add_plugin(
314+
replaced_placeholder,
315+
plugin_type="Alias",
316+
language=self.language,
317+
alias=self.alias,
318318
)
319-
placeholder = replaced_plugin.placeholder
320-
add_plugin_kwargs = {"position": "left", "target": replaced_plugin}
319+
320+
placeholder = replaced_plugin.placeholder
321+
plugins = CMSPlugin.objects.filter(
322+
id__in=[replaced_plugin.pk] + replaced_plugin._get_descendants_ids(),
323+
)
324+
add_plugin_kwargs = {"position": "left", "target": replaced_plugin}
321325

322326
copy_plugins_to_placeholder(
323327
plugins,
324328
placeholder=self.placeholder,
325329
language=self.language,
326330
)
327-
plugins.delete()
328-
placeholder._recalculate_plugin_positions(self.language)
331+
replaced_plugin.delete()
329332

330333
new_plugin = add_plugin(
331334
placeholder,
@@ -334,9 +337,6 @@ def populate(self, replaced_placeholder=None, replaced_plugin=None, plugins=None
334337
alias=self.alias,
335338
**add_plugin_kwargs,
336339
)
337-
if replaced_plugin:
338-
new_plugin.position = replaced_plugin.position
339-
new_plugin.save(update_fields=["position"])
340340
return new_plugin
341341

342342

djangocms_alias/templates/djangocms_alias/alias_replace.html

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,7 @@
1414
// we have a special case here cause the CMS namespace
1515
// can be either inside the current window or the parent
1616
(function(Window) {
17-
Window.CMS.$(document).ready(function () {
18-
// make sure we're doing after the "modal" mechanism kicked in
19-
setTimeout(function () {
20-
{% if replaced_placeholder %}
21-
Window.CMS.API.StructureBoard.invalidateState('CLEAR_PLACEHOLDER', {{ replaced_placeholder|safe }});
22-
{% else %}
23-
Window.CMS.API.StructureBoard.invalidateState('DELETE', {{ replaced_plugin|safe }});
24-
{% endif %}
25-
{% for added_plugin, structure in added_plugins %}
26-
var addedPlugin = {{ added_plugin|safe }};
27-
addedPlugin.structure = {{ structure|safe }};
28-
Window.CMS.API.StructureBoard.invalidateState('ADD', addedPlugin);
29-
{% endfor %}
30-
{% for moved_plugin in moved_plugins %}
31-
var moveData = {{ moved_plugin|safe }};
32-
Window.CMS.API.StructureBoard.invalidateState('MOVE', moveData);
33-
{% endfor %}
34-
35-
Window.CMS.API.StructureBoard._requestcontent = null;
36-
Window.CMS.API.StructureBoard.updateContent();
37-
}, 100);
38-
});
17+
Window.CMS.API.Helpers.reloadBrowser();
3918
})(window.parent || window);
4019
</script>
4120
{% endblock %}

djangocms_alias/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ def create_alias_view(request):
136136
"Plugins are required to create an alias",
137137
)
138138

139+
plugin = create_form.cleaned_data.get("plugin")
140+
plugin_pk = plugin.pk if plugin else None
139141
replace = create_form.cleaned_data.get("replace")
140142
if not Alias.can_create_alias(user, plugins, replace):
141143
raise PermissionDenied
@@ -144,8 +146,9 @@ def create_alias_view(request):
144146
emit_content_change([alias_content])
145147

146148
if replace:
147-
plugin = create_form.cleaned_data.get("plugin")
148149
placeholder = create_form.cleaned_data.get("placeholder")
150+
if plugin is not None:
151+
plugin.pk = plugin_pk # Restore pk after it was set to None in form.save()
149152
return render_replace_response(
150153
request,
151154
new_plugins=[alias_plugin],

0 commit comments

Comments
 (0)