Moved from https://github.com/divio/django-cms/issues/6110


Preamble

We should rethink the way how to handle the methods to determine which 
Plugin is eligible to become a child of another plugin.


Currently, when we open the CMS in structure mode, the Placeholder and its 
attached Plugins know which plugins may be added as children to an existing 
plugin. This is determined by each plugin through its attributes 
parent_plugins and child_plugins. These attributes may be either None or a 
list of strings. In the former case, all plugins are allowed as 
parent/children,
whereas in the latter case, only the named plugins are eligible as 
parents/children.



This static assignment has some drawbacks
   
   1. 
   
   In an ecosystem of plugins from different vendors, beforehand we don't 
   know, who may want to become the child of a plugin from another vendor. 
   This could cause one vendor having to as another vendor to add his plugin 
   to the list of allowed children.
   2. 
   
   Computing the eligible parent-children relationships is time consuming. 
   Therefore django-CMScaches this information internally, which removes 
   the possibility to determine dynamically, for instance by evaluating the 
   current context, which children plugins can be added to an existing plugin.
   3. 
   
   In structure mode, when rendering a deep tree of plugins, each plugin 
   comes with its own list of eligible children plugins. This can add many 
   kilobytes of additional data to the payload, when transferring a CMS page 
   in structure mode.
   4. 
   
   This rigid system of parent-children relationships, does for instance 
   not allow to add kinds of intermediate plugins, such as wrappers or logical 
   segments.
   
Therefore I want to propose a different method to determine which plugins 
are allowed as children of another plugin. Instead of computing this list 
statically *before* the CMS page is rendered, we should add a REST 
endpoint, which computes this relationship dynamically and based on the 
current context.


This list then is transferred from the server to the client and is used to 
render a list of possible
children plugins. The computation of this list should work as follows:

   - The plugin being asked for, iterates over all plugins registered in 
   the pool.
   - It then invokes a method, say allowed_as_child_of() for each of the 
   plugins of the pool,
   passing its own instance and the current context.
   - Based on the given parameters, this method returns a boolean, which 
   determines, whether a plugin can be added to the current plugin or not.

This computation can now be much more time consuming. This is because we 
only have to do it
whenever the user clicks on the + symbol inside the plugin editor, rather 
than having
to do it for all plugins inside the pool. Even if such a computation 
requires 200 milliseconds,
since this it is part of the user's interaction, this would disturb.



Possible new Features

Plugin systems, which map the Bootstrap grid, usually encounter the 
following problem:

A row may be part of a container, and columns may be part of that row. An 
accordion, carousel,
panel and similar elements can either be children of the container, the row 
or the column.

Depending below which of these elements an accordion panel is placed, its 
own children then
shall either be either rows, columns or plain content. This means that 
whenever
allowed_as_child_of() of an element is invoked, that method could check its 
potential
parent element, and if that does not contribute to the Bootstrap's grid 
structure (such as said
accordion, carousel, panel, etc.) it can go up a further level in the tree.

This feature would also make it possible to allow plugins depending on the 
siblings context.



Backwards Compatibility

Since we don't need the complicated caching functionality anymore, I even 
believe that it
reduces the amount of code. By adding an overridable method 
allowed_as_child_of() to the
base class CMSPluginBase, this feature could even be implemented in a 
backward compatible
manner. This method then just would have to examine the plugin's attribute 
parent_plugins
and the attribute of its ancestor child_plugins to determine whether it is 
allowed of
being added or not.



Implementation

In case the django-CMS community agrees on this proposal, I will implement 
this feature so
that it is available in a future major release. With this in mind, I'd like 
to open a discussion
about it.

-- 
Message URL: 
https://groups.google.com/d/msg/django-cms-developers/topic-id/message-id
Unsubscribe: send a message to 
[email protected]
--- 
You received this message because you are subscribed to the Google Groups 
"django CMS developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/django-cms-developers/c8f77073-0bba-409c-9b81-037a1cd6f258%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to