Repository: django-cms/django-cms

Issue:
Placeholder Inheritance in frontend editing
in my base template, i have a header text. This text should be 
editable in every level of my navigation, and it should inherit the 
text of the levels above if there is no content. 
So, here is my example: 
In my base template, my placeholder is defined like:

```
{% placeholder header_img_txt inherit or %} 
  Default fallback 
{% endplaceholder %} 
```

So, this works without a problem. When there is no content, the 
fallback is shown, and when I add some content for level 0 it is shown 
in level 1. 

And now, there is my problem: When I go to a level 1 navigation point 
in my frontend and turn the edit mode on, then I edit the level 0 
content for my placeholder. But of course, I want to edit the level 1 
placeholder, to override my level 0 content with the level 1 content. 
When I go to the admin panel, and edit the level 1 content, everything 
works fine. But I want to do it in the frontend. 



Discussion:
Confirmed.
Bug exists in 2.2 as well.
I think it's too late for 2.3 fix

It would be really great to have a fix in version 2.3 already. I try to use django-cms in a productive environment, and it is hard to sell a system to a customer when I have to tell him, that he can edit everything in frontend, except of the header.

I agree on the importance of this issue: I escalated to core dev for further decisions.
2.3 has so many things in it that any further code change has to be carefully pondered over.
It would be of great help if you could provide a testcase for this.

I'm not sure what the best approach here would be.

Easiest: just disable the inheritance mechanism when in edit-mode. Not the most user-friendly approach, since the user is generally not aware that the content is inherited. Code impact: one line of code. This also reflects the current behavior in the admin.

More complicated: show the inherited content in edit mode, but don't make it editable. Instead, add a helper text to tell the user to add new plugins to override the inherited content. Not sure how easy that would be.

Best case in my opinion: copy the plugins in the placeholder when user enters edit mode, and delete them again if the user doesn't modify them. This way, the user doesn't even have to familiarize himself with the concept of "inheritance". But I have no clue in the first place how this could be solved and not result in a lot of unwanted copies.

Last solution is too much error prone: I bet most of the users not editing the data will simply move away from the page, rather than cleaning exiting from edit mode.
I know nothing of that part of the code, though, so I cannot guess how hard would be solution #2 (still not transparent to the users, but safe and not hard to explain to them).

A further point in this discussion is the fact that frontend editing is a bit of a moving target right now. We should not invest to much time into a solution that might be outdated with the release of 2.4.

In this perspective one-liners have their advantages :)


Resolving patch:
diff --git a/cms/templatetags/cms_tags.py b/cms/templatetags/cms_tags.py
--- a/cms/templatetags/cms_tags.py
+++ b/cms/templatetags/cms_tags.py
@@ -133,8 +133,12 @@ def _get_placeholder(current_page, page, context, name):
     return placeholder_cache[page.pk].get(name, None)
 
 def get_placeholder_content(context, request, current_page, name, inherit):
+    edit_mode = getattr(request, 'toolbar', None) and getattr(request.toolbar, 'edit_mode')
     pages = [current_page]
-    if inherit:
+    # don't display inherited plugins in edit mode, so that the user doesn't
+    # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion
+    # there for possible enhancements
+    if inherit and not edit_mode:
         pages = chain([current_page], current_page.get_cached_ancestors(ascending=True))
     for page in pages:
         placeholder = _get_placeholder(current_page, page, context, name)


Test patch: