I'm going to provide a solution to the customization of nested layouts by introducing a Page "edit" state.
And I will get both the columns and the tcolumns based layouts fully in sync again.
Then, I'm going to extend the Customizer to allow adding (nested) layouts itself.
And finally, I will provide customization to the customizer itself using the (root) layout decorator.properties.
Page scoped "edit" state
Currently, layout "edit" state is handled through the PortletMode EDIT of the concerning Layout Portlet.
But, as noted by Randy above, this doesn't really match with the more Page scoped actions from the Customizer.
Thus, I will introduce a PageEditAccess component (interface) which will provide the current page "edit" state,
as well as information if the page is allowed to be edited.
As we already maintain a component called PageActionAccess internally for mapping current page fragments access,
I will simply extend that component and provide the PageEditAccess features as an interface extension.
As result of this change, page edit state will become independent of a specific LayoutPortlet PortletMode.
More specifically, setting a Page in edit state doesn't change any LayoutPortlet PortletMode anymore.
As a side-effect (but intentionally as I needed this myself anyway) of this, a root LayoutPortlet no longer needs
to support PortletMode.EDIT (via its portlet.xml definition). If it doesn't support it, it simply means the
root Layout won't be editable.
Another page level feature currently tied to the root LayoutPortlet I won't replace yet: Page Help.
Right now this is, and will remain so, only available when the root LayoutPortlet supports PortletMode.HELP.
Finally, I'm going to move the last page level action, Adding A Portlet through the popup Portlet Selector, to
each individual (and editable) Layout. This really is needed to be able to support nested layouts.
Currently, the PageActionAccess component is initialized in two locations: in the DecoratorValve and in the
JetspeedPowerTool (legacy usage). I will move the PageActionAccess and the related DecorationAction classes
to the decoration package as well as remove the legacy code from the JPT (no longer needed).
Adding Layouts through the Customizer
After getting nested layouts properly working, including moving and deleting both portlets and layouts itself,
the logical next step was adding (nested) layouts through the Customizer itself.
Already, the customizer allowed changing a layout type.
I'm going to remove the "auto change" of the layout type when the user selects a different one in the poplist.
As result, the same poplist can then be used for both changing the type as adding a new layout (within the
current one). For this, I'm going to provide two new buttons ("Change" and "Add") after the poplist.
Side note: The Customizer "bar" now provides a lot of features (if all are enabled that is, see next section
about customizing below). Besides adding a new Layout, a new Page (for root Layouts only), the "Add a Portlet"
icon too now has to be provided here. This "+" icon itself really wasn't indicative enough anymore, so I added
a "Portlet:" label in front of it (see also the screenshot I'll be attaching to this issue).
Customizing the Customizer
Although layouts itself now can be added through the Customizer, too many nested layouts isn't really going to be manageable.
So by default this is restricted to 2 levels. But this is configurable using the root layout decorator.properties.
And, other features for the Customizer can be configured (disabled) now likewise.
The default settings are:
Note: Changing the page theme and adding a page are only going to be provided by the root Layout Customizer anyway.
The above described changes are many...
Custom extensions and/or implementations of especially the Layout Portlets and the related layout templates
(columns.vm and tcolumns.vm) will have to be checked carefully and be upgraded.
Most important changes will be those to the form fields in the layout templates and the related handling within the
I initially tried to only use the current definitions, but that turned out to be almost impossible and became very
awkward too. So, you really need to check the template changes (they have become much simpler though...)
Another change which might impact custom extensions is that the MultiColumnLayoutPortlet won't be delegating "add"
and "delete" handling of portlets to its parent LayoutPortlet anymore. I did extend the LayoutPorlet to support
nested layout handling, but the actual usage is only from the MultiColumnLayoutPortlet.