In progress for 4.5
Introduces new templating in preparation for Magnolia 5.0. Implementation tracked in SCRUM@jira.
Goals
- improve the templating to make it more intuitive
- prepare the new page editing
- align JSP and FreeMarker templating
- provide maximum possible backward compatibility
Summary
- rename paragraphs to (page) components
- introduce areas
- sub elements of a template
- container for components
- provide a new minimal set of directives
- area, render, edit
- better attribute names, aligned to the JCR API
- provide a set of standard functions to allow more complex operations
- streamline content expressions
- implementation is based on the Map interface
- allow using the JCR API: cmsfn.asNode(content).getProperty("bal")
- align component, area and page template definitions
- use the same renderer
- use the same definition beans
Paragraphs become (page) components
- for new Magnolia users and developers it was always difficult to grasp the term 'paragraph' as used in Magnolia
- CMS like Magnolia are known as component based system
Align page and component templates
Definitions
- use a single registry
- to avoid checks like in the rendering engine
- use a common template definition object
- drop the differentiation of components and page templates
- structure the templates with folders
- components/content/textImage, pages/article
- the path is used to reference a component/dialog
Renderers
- one renderer interface and a single renderer registry
- same set of context objects
- JSP: decide based on situation if we forward or include (forward if main content is the same as the current)
Template Definitions (Enhancements)
- additional context objects can be configured per template
- dialog can be configured in the template definition rather than being referenced
Template Variations
Template variations are similar to the former sub-templates.
- all templates can have variations (including areas and paragraphs)
- configured as a Map
Default variations
- json: renders a json representation of the content
- xml: renders a xml representation of the content
- formated similar to the JCR document view
Selection mechanism
- the variation is set in the aggregation state
- by default this is the extention
- other example: variations per device
Inheritance (from the base template)
- the template is merged with the 'base' template
- works the same way as in STK: current template and site's prototype
Areas
- templates have areas (regions having components)
- configured as a map in the template definition
- list available components (like in STK)
- defines the template script to be use
- enabled flag
- can have its own edit dialog
Types
Type | Description | Structure | Context |
---|---|---|---|
list |
| page (mgnl:page) - main (mgnl:area) - component[0] - component[1] - component[2] | |
| |||
single |
| page (mgnl:page) - stage (mgnl:area) - title - component (mgnl:component) - title | |
| |||
no-component |
| page (mgnl:page) - navigation (mgnl:area) - levels | |
|
Template script
- can be inlined (in the area tag)
- content object is the area's node
Non existing areas
- content is null if the area is not existent
- the script can render a placeholder
Model
- an area has a model like all templates do
Available components
- list of roles, groups and users
- enabled flag
- bean: ordered map
Sub Areas
- areas can have sub areas
Auto generations
- both single and list types can be auto generated
- on creation of the page
- if a generated component has a required property it is not deletable
- if a generated component has its orderable property set to false it can't be moved
Inheritance
- can be configured
- see chapter 'inheritance'
Tags/Directives
- minimal set of directives
- use jcr naming: node, property, path
Common attributes for passing the content to use
Attribute | Description | Default Value |
---|---|---|
content | a Node or ContentMap |
|
workspace | the workspace used if the uuid or path is defind | same as of the current content |
uuid |
|
|
path | the path in the workspace |
|
cms:area
- type list: replacement of the iterator tag and new bar
- type single: combines the new and edit bar
Attribute | Description | Default Value |
---|---|---|
name | the area name, will work on def.areas[MAGNOLIA5:name ] |
|
area | an area definition object |
|
components | list of available components | by area definition |
script |
| by area definition |
placeholderScript |
| null, by area definition |
type | list or single | list, by area definition |
dialog |
| null, by area definition |
inherit |
| false |
Context
In addition to the 'normal' context objects the followings objects are provided
- components: list of the area's components, includes inherited components and respects the order information
- component: in case of a single area, might be inherited
Inline Areas
- Status: Proposal, not implemented yet, see MAGNOLIA-4586
- Allow definitions directly in the template script (without definition)
# every thing is configured at def.areas[name] [@cms.area name="main"/] # inline [@cms.area name="main" components="paragraphs/content/textImage, paragraphs/content/linkList"] <div id="main"> [#list components as component] [@cms.render content=component ] [/#list] </div> [/@cms.area] # inline single [@cms.area name="stage" components="paragraphs/stages/stageA, paragraphs/stages/stageB" type="single"] <div id="stage"> [@cms.render content=component ] </div> [/@cms.area]
cms:component
- Renders a component
- Similar to the former includeTemplate
- Needs an existing node
Attribute | Description | Default Value |
---|---|---|
editable | if any editing elements should be shown. mainly useful if content is inherited | cmsfn.isFromCurrentPage() |
template | name of the template definition to use | the template defined on the node |
cms:edit
- Renders an edit bar (or button)
- Requires a node (is not a new bar)
- Can edit any node (for instance data module content)
Attribute | Description | Default Value |
---|---|---|
dialog | name of the edit dialog |
|
format | button or bar | bar |
[@cms.edit content=contact dialog="data/contact"/]
In practice, you rarely need to add the cms:edit
to a script. It is injected into editable areas and components automatically.
cms:context
- former attribute tag used for cms:render
- ctx.name
- attributes are removed after the rendering
- former values are restored
[#assign counter = counter +1] [@cms.render] content=child] [@cms.context name="counter" value=counter/] [/@cms.render] # in the paragraph script ${ctx.counter}
Functions
- Freemarker: cms context object provides functions
- JSP: static class delegating to the context object
- standard prefix cmsfn
Function | Description |
---|---|
asJCRNode(content) | to allow calls to the jcr API |
asContent(node) |
|
parent(content, [MAGNOLIA5:type]) | if the type is passed the first matching ancestor is returned |
children(content, [MAGNOLIA5:type]) |
|
uuid(content) |
|
wrap(content) | add wrappers used in the renderer |
link(content) |
|
edit(content, propertyName) | adds editor markup attributes |
decode(text) | decode content if the text is plain HTML code |
.... |
|
Utils
- other function libraries can be added
- like cmsutil.*
- cmsfn.* should just provide the essential functions
Content expressions
- align freemarker and JSP
- use a Map instead of content (Magnolia)
- drop ContentModel -> allow method calls on JCR nodes
- but still support TemplateNodeModel for ?children, ?parent, ...
ContentMap
- extends Map interface
- does not implement Content or Node
- has a asJCRNode() method
- all values are encoded
- all links are processed
- resolution
- property
- child node
- content.@uuid == cmsfn.uuid(content)
- content?children == cmsfn.children(content)
Binaries
- are now nodes (nt:resource)
- content.image --> cmsfn.link(content.image) to create a link
- content.image.size returns the size property
Namespaces
- content["mgnl:template"]
- content.template --> if no property "template" exists it checks if an other (with namespace) matches
Compatibility
- a separate compatibility package is needed (to keep new code clean)
Template and 'paragraph' definitions
- definition has to be migrated (converter will be provided)
- type is: jsp4x, ftl4x
Scripts (if of type jsp4x or ftl4x)
- old directives/tags are provided
- content (of type Content) is passed
- a single template script cannot mix old and new style (also true for includes)
Editor
- render the edit bars as before (where the cms:edit tag is)
- new bar -> render them as before (no autocreation of areas)
- no area bars
Inline (Magnolia 5)
annotated tags can be edited inline
<h2 ${cmsfn.edit(content, "title"}>${content.title}</h2>
Inheritance
Inheritance is supported by areas. In addition a set of functions and standardized content properties support custom solutions.
An area with inheritance enabled inherits properties and components from areas in its parent pages. Inheritance can be set to include only properties, only components or both.
By default properties and only components with a property 'inheritable' set to true are included.
Configuration
Options for components
- all
- none
- filtered, all components with a property 'inheritable' set to true (default)
Options for properties
- all (default)
- none
Component order
- a property 'nodeComparatorClass' set to a class name of a class implementing java.util.Comparator<Node>
Component filtering
- a property 'predicateClass' set to a class name of a class extending info.magnolia.jcr.predicate.AbstractPredicate<Node>
Editing
- inherited paragraphs are not editable
Functions
- cmsfn.inherit(content, innerPath): ContentMap
- cmsfn.inheritProperty(content, innerPath): String
- cmsfn.inheritList(content, innerPath, aggregate): Collection<ContentMap>
- aggregate: collect over several ancestors
- respects the orderdering information
- cmsfn.isFromCurrentPage(content)
- cmsfn.isInherited(content)
Special properties and mixins
TODO: use mixins?
TODO: list all special properties
References
TODO
- property mgnl:reference
- a wrapper replaces the node with the referenced node
- transparent for the template
- properties can be overriden
- very similar (or the same?) as the extends feature in configurations
Editor markup
The editor markup is only rendered if the page is shown in author mode. The editor uses this elements to inject his components into the page.
separators
Added by the Area- or EditComponent to mark the boundaries
<!-- cms:begin cms:content="ws:path" --> <!-- cms:end cms:content="ws:path" -->
area
<cms:area content="ws:path" name="name"paragraphs="paragraphs/textImage, ..." type="single" dialog="areas/main">
edit bars
<cms:edit content="ws:path" format="bar" dialog="paragraphs/textImage">
inline
Bind an element to a property to make it directly editable
<h2 ... cms:edit="inline" cms:content="ws:path@prop"">
Editor
Magnolia 4.5
TODO
Magnolia 5
- the content is rendered in an iframe
- this isolates the editor's and page's javascripts, css ...
- no initialization code in the page
81 Comments
Teresa Miyar
Would it be possible to have the inherit define the levels, or have an option to hide/show an inherited paragraph?
Philipp Bärfuss
level
we could, as an alternative you can do the following
hiding
You probably think about collections where you define on each paragraph wether it should be shown in sub pages. Yes I am going to add that.
Teresa Miyar
so you mean it will work if I have home/section/article1, article2 and I want the footer to be in home and in the articles but not on section?
Philipp Bärfuss
that is a tough one, in this case you can't get around some custom codingv
Christian Ringele
I think a solution/possibility to this would be:
That you can define inheritance itself on the Area:
Like this you could inherit a completet collection from the parent (the footer) or not, and a subpage can still inherit form the page two levels up. Inheritance just jumps over the Area form the first parent where 'notInheritable' is enabled.
Philipp Bärfuss
yep, the inheritance can now be configured in the area: exclution and ordering will be supported
Sean McMains
I like the direction this is going. It seem like it should result in cleaner, easier templates, while at the same time providing richer functionality. Nice work!
It does seem at some point like adding more functionality may have potential to break MVC, and have logic creep into the Freemarker code. For example, does exposing the method calls on JCR nodes allow you to update JCR content, or make unit testing your Freemarker templates harder? (Probably a minor concern, but it occurred to me while reading through this.)
Philipp Bärfuss
we should ship a patrol module which detects mischief and sends a notification to the system architect
Christian Ringele
Topic: Area - Paragraphs to add:
1. Paragraphs in Areas should have an 'enabled' flag (info.magnolia.module.templatingkit.templates.ParagraphConfig bean right now)
2. The paragraphs should be placed into a Map and not collection (most preferable a LinkedHashMap for keeping the original order) so:
3. Not only 'role' should be defineable on the Paragraphs (and the Templates and) availability, but also Groups (and Users). Mainly groups, cause it a complete group should be able to add it, its possible the a group is defined by many roles. You would have to add all of them to fetch for sure all according groups.
Philipp Bärfuss
added as suggested
Christian Ringele
Topic: Area - Creating singletonParagraphs
Wouldn't it make more sence to implement a default case on Area:
I have bit trouble to understand the singleton ideology when more than one paragraph is generated. Does that mean, that you can define more than one, but only one of each?
If so that would mean for me, that the general case is configurable as such on a area:
Area/paragraphs/concreteParagraphToAdd/option1=paragraphName
option2=isAutoGenerated
option3=isSingleton
And the is singleton just prohibits, that the newBar allows to add the same type again.
The newBar:
-> adding one paragraph with 'singleton' -> just creates it and no new bar appears
-> adding a second with 'autoGenerate', will be auto generated. A new bar appears, but only the second is addable.
Another question that rises here is:
Are autogenerated paragraphs (and singletons) movable over the edit bar? I think they shouldn't.
Philipp Bärfuss
there was probably some confusion. the auto generation has nothing to do with the fact wether this area is a collection or not. I renamed the attribute to 'collection' which can be set to true or false
Christian Ringele
I still don't see the differentiation of the colleciton and the singleton. Basically you always have to define what paragraph can be added, only one or more then one.
With allowing on the 'paragraphToAdd' the two options 'autoGenerated and/or singletong' you have all in one. No differentiation needed.
And you have some additional functionality you don't have otherwise: you can define, that a Flash paragraph can be added only once, but others still can be added. So the Flash paragraph would be some sort of singleton too (only once in a Area).
Philipp Bärfuss
The availability of paragraphs and the auto generation are two independent things. An example illustrating this is the following:
This two configurations can not be merged into one in a meaningful way.
The difference of collections and singletons (do we need a better name?) is the structure which gets created. In case of a singleton, the area node IS the paragraph node. The examples as found in todays STK:
Christian Ringele
General note on Map vs. Collections in beans:
I think all collection nodes definable on templates and paragraphs should always be Maps and not Lists or Collections. So the same item can't be added twice.
So on pobulation of the beans map you get automatically overwrite of already predefined configurations.
Christian Ringele
Topic: Functions
So you could do in a paragraph: getAllAreas(page(paragraphContentNode))and having a list of all area collection nodes
Philipp Bärfuss
we are going to add more functions as needed for now I am rather reluctant
Christian Ringele
Topic: Content Expressions:
Magnolia International
you can already do ${content.metaData.xxx) where xxx is a property of the
info.magnolia...MetaData
class.Christian Ringele
Oh, didn't know, that suprises me! Thought that were not providing any acces directly to the content's API for not beeing able to write into the content by the template. So I ecpected that only the .@attributes are provided for this, and no compley object is server by the content's map.LIke this (just tested) I can write by the template script directly into the meta data of this content node.
Good to know, thnx
Philipp Bärfuss
@path to be aligned with the JCR API
Christian Ringele
Topic: Common attributes for passing the content to use:
Do you mean by workspace the Area? Or the JCR workspace?
Philipp Bärfuss
JCR
Christian Ringele
Topic: Inheritance ordering:
To your question of ordering the collections:
You wrote, that the paragraph will have by default an injected edit bar.
Couldn't be injected a different edit bar on inherited parahaphs so:
So when the inheritance tag is collection the nodes, it can reorder them if the uuid is a part of the complete merged inherited collection
Philipp Bärfuss
I updated the following:
Christian Ringele
Topic: Templates and Paragraphs in the same registry:
I personally don't think thats good idea, even I see the benefits of it. The cons:
Probably I understand it wrong, and you mean its just one Registry, but still they are defined separetly on the module's level, but just registered by the same ManagerRegistry.
Then its a good Idea I think.
Philipp Bärfuss
We are going to merge them. So you will structure them in folders and reference them by path. This has the following advantages:
Christian Ringele
Referencing them by path makes it very hard to maintain projects.
If ever something is changed in the structure, you must know, what all is referencing it to change the path pointing to it.
No prefixes sounds nice, but I think in projects it tells something about the parargaphs to newbees too -> where it is located. A stkTextImage is clear where it comes from, as a basfTextImage too. No prefixes you talk about textImage paragraph, but which one. So you'll say/document anyhow the textImage of the stk.
Do I understand that right, that the property 'template' in the metadata will have a path and not only the name?
ONe thing you can do right now wich results in a lot of work is: rename a paragraph. But at least you coudlr estructure them within the modules without causing any additional work. When the path is stored, then even restructuring paragrpahs results in a lot of work (chaning all the values in the metadata). I'm really not sure, if this path/name adressing helps in projects, I think it results in many cases in more work and less flexibility.
Philipp Bärfuss
hm yes, the restructuring is an issue I have not yet thought about. we definitely had to provide some tooling for this. still I like the straightness of the new approach.
Christian Ringele
Topic: Templates and Paragraphs in the same registry -> more extendet paragraph definition
I assume, that we still register paragraphs in the module's paragraphs node.
The I would suggest having in the paragraph definition a more extendet configuration for making them interchangable within different collections. Mostly they just differ in two things:
As the template will have a specialized config as a Map of Areas I would suggest something similar on paragraph level. A Configuration of the areas where it can be added, which acts a a subTemplate (paragraphs def meant) definition for the accoring area.
The paragraph def itself is the default, used for every area if not defined different. But then you can ad into a node as subTemplates, fore example:
There you just define for example a differen dialog for subTemplates/areas/extras/dialog
So if added to the mainArea, it will pick up this dialog, and so on. This is comparable as a implicit extends mechanism.
I think subTemplates should be implmented for paragraphs too (which I think is planned) so the same config could be used for the area definitions (areas where it should pick up the subDefinition, not where it can be added, that on the templateDef/areas).
Actually I would suggest such a general base config:
paragraphDefinition/subDefintions/mimeTypes/
paragraphDefinition/subDefintions/areas/
Replacing subTemplates/mimeTypeName to subDefintions/mimeTypes/mimeTypeName
Philipp Bärfuss
I renamed sub templates into variations. for now the 'extends' mechanism should be enough. I don't like to add yet an other kind of overlay.
Christian Ringele
I agree, that another overlay can be confusing. But I'm not sure that the extends makes it easier to understand.
The 'bad' thing about the extends is, that the structure is fix by the extends. Yuu can't move paragrapgs & dialogs and rename them, cause some extends could point to it. Hard to find out, what is extending me.
So my idea was, that it's defined on the paragrpah itself, it's variations for the areas.
Philipp Bärfuss
I agree that the 'extends' mechanism can become cumbersome but I think the main reason lies in the lacking support in the UI. We should:
But the configuration is yet another topic.
Richard Unger
I think this will cause confusion with the existing concept of image variations in EE imaging module.
How about "template-variations" or "template-variants" or "alternate templates".
Philipp Bärfuss
true, if the context is not to obvious we will talk about template variations
Christian Ringele
I'm not sure, if extending your own parent won't leed to many problems? (or in htis case the parent of the parent).
Christian Ringele
Topic: Rendering Context Object:
A dynamic mechanism of defining what additional context objects can be provided to the template scripts. Right now if you wan't to provide an additional rendering context object, you need to extend the renderer and register it. But that means that all standard components which use the former renderer don't know anything of it.
So on the RenderableDefiniition (and therefore in stk in prototype), it would be nice to configure something like:
Philipp Bärfuss
agreed and added
Christian Ringele
Topic: Areas in TemplateDefs:
Generally I like this concept a lot! A question I want to rise here about that:
Shouldn't then a Area class contain a Map of Areas again?
I know this sound cumberson and unmanagable/hard to understand and keeping the overview.
But if you think of STK's etxras area. What we have there is actuall a top Area, and the two additional Areas again.
An Area in a Area you can compare, as having a paragraph with a collection of paragraphs, just htat the paragraph istself is not rendering anything but is enable-able and is scriptwise on page level (page freemarker includes).
Philipp Bärfuss
areas and templates (same as paragraphs) are going to extend the same definition base class. areas can consequently have sub areas.
Magnolia International
Philipp, have we thought about namespacing definitions? This could address some of Christian's concern. One could reference a def without namespace, falling back to "the first", or an exception thrown in ambivalent cases.
(the "namespace" would be the module's name?)
Christian, regarding duplicate names - if 2 modules register the same name, yeah, that's a problem. Perhaps addressed with namespaces. If it's within one single module, the fact that names have to be unique is probably a good thing, to avoid confusion.
Christian Ringele
I think so too, that not beeing allowed to register in a module a template/paragraph twice with the same name is a good thing.
Its more about the 'fact', that in STK (and that is what I teach as best prectice), we have for the SingletonParagraphPages the same names as their paragraphs. So if the paragraphs and templates are handeled by the same registry, then you could not do that anymore. That would mean we have to rename all these paragraphs or templates -> think about the updatetasks we will have to write in demo-project to change all contents. And all customers which probably habe used original stk components... and the scripts are named accordingly to the paragraph's names and so on.
The namespace wouldn't help, cause they are alle registered in the same module -> STK
Philipp Bärfuss
we use the path relative to the /modules/xxxx/templates node, but yes, having a module namespace might be needed
--> samples:pages/content/article
Richard Unger
I'd like to give my comments to the above proposal. We have been doing extensive work expanding magnolia for our customer in some of these areas, so I think I have some experience to share, and of course also a vested interest in what happens here, since it has to do with the future compatibility of our extensions.
Areas
I like this idea a lot. It's a logical generalization of the STK concept of Areas. Storing the areas in the template definition in a map is a critical improvement. Removing the STKs fixed idea of what areas make up a website will also greatly improve the versatility of the STK.
One difference to think about is that so far, areas have been handled "inline" (using #include), while paragraphs are normally handled in their own rendering context (using @cms.includeTemplate). I'm guessing that Areas will be able to have model-classes, like paras and pages, and so areas will in future have to be handled in "their own rendering contexts" (like paragraphs). This will have an impact on template design.
Will the areas be associated with a node type, the way paragraphs are associated with a mgnl:contentNode, and pages with a mgnl:content? Maybe mgnl:contentArea? Or will areas be without their own node, as they can be at the moment?
Will there be direct Area acess, in the same way there is direct Paragraph access?
Aligning Paragraphs and Templates (and Areas)
is a good idea! Do it. While you're doing it, add the subTemplate functionality to Paragraphs and Areas as well as Pages, subTemplates are useful.
Tags / Directives
We have created a complete set of CMS-Tags, implemented via freeMarker Directives, building on the ideas in the currently unfinished "templating-components" module.
Our goals for our implementation included:
The reasons for these goals were:
Our customer's editors are not trained specialists, and the backend was deemed to complicated to learn. With our extended templating components, we can create front-end UIs that more or less guide a completely inexperienced user through the process of creating content.
Implementing the CMS-Tags as Freemarker directives was no problem at all. It is somehow much nicer to work within freemarker templates using the directives, rather than the JSP Tags.
Aligning the tag-attribute names is certainly a good idea - having to write "contentNodeCollection=" each time (when "node=" would be sufficient) really drives me crazy!
The directives you propose look interesting, but I think there are still some flaws:
... inline template goes here ...
[/@cms.render]
Another comment: in your current proposal, it is not clear how the move function will work? I take it that whether move is shown in the edit-bar in some way depends on being within the same area tag?
Inline Editing
A good idea, and logical extension of the current functionality.
Inheritance
These ideas seem good. Consider providing two kinds of inheritance:
inheritAll() --> like the current functionality: content is inherited from ancestors, and aggregated into a list. Result is all such named nodes in the path to root.
inheritFirst() --> inherits only one such named node, the first one found when traversing ancestors towards the root. Similar to inheritAll()?first, but more efficient.
Ok, that's my 2c worth for the direct feedback. I will include abother post below, with some additional ideas at a more general level.
Richard Unger
Philipp Bärfuss
Areas
Sub templates (now named templates variations)
Tags / Directives
Inheritance
Richard Unger
Templating-Components-API
As mentioned in my previous comment, we have developed considerable extensions to the magnolia templating components for our customer. With the current proposal, we are of course concerned about the future compatibility of our modules.
In creating our customized templating components, I noted that currently there is a lack of a clear API via which the templating components talk to the rest of magnolia. Essentially, once it is rendered and displayed on the front-end, for a templating component (like an edit-button) to get something done, it currently has to make use of one of two "hooks" into magnolia, neither of which is a "clean API", and neither of which is "stable".
These are:
1. The cms-InterceptFiltor - configured in the magnolia filter-chain, this filter reacts to certain (undocumented) get-parameters in the request, and performs content-manipulation tasks like "move", "delete", activating preview mode, and similar.
2. The "javascript.js" javascript functions, also dialogs.js. These javaScript files provide convenience functions which take care of opening dialogs in pop-up windows (needed for "edit" and "new" buttons) and also provide the javaScript "GUI" code to highlight buttons, implement the move action, etc... These javaScript files are shared with parts of adminCentral, and can contain nasty interactions with the content javascripts. Also this javaScript API-layer is not documented, and not stable.
In addition, the templating components use the MgnlContext, the AggregationContext, RenderingEngine, Request-Attributes, etc... - these generally availabile APIs are also available, and used where necessary.
Proposal: Create a clean and stable API for templating components in magnolia.
This would allow different implementations of the front-end GUI to co-exist in the magnolia world, and would provide security for the investments made by your customers in customized GUIs.
The API would build on what exists today, and formalize it into a stable and general API.
The API would have a request-based interface, handled by the InterceptFilter.
API functions would include:
MOVE
Parameters:
DELETE
Parameters:
UPDATE (for inline-editing)
Parameters:
OPENDIALOG
Parameters:
OPENPAGE
Parameters:
I don't think much more than this would be needed.
Additional Comments:
MOVE and DELETE can operate on contentNodes or on pages. If moving pages, destination-parent must also be a page.
Except for OPENPAGE and OPENDIALOG, which only make sense when you want to show the resulting dialog window, all other commands can be called in an "AJAX" mode, which only returns success/error information. Alternatively, the commands can be called in "normal" mode, which re-renders the page content as the response.
In Magnolia 5, OPENPAGE and OPENDIALOG will probably be replaced by something like OPENVIEW which opens the given Vaadin view.
Combined with your suggestions for improving the templating mechanism I think such an API would be a very nice feature for magnolia, and open the door to interesting new front-end GUIs for the editors.
Philipp Bärfuss
The way the new page editor works is, thanks to the Vaadin framework, much different. The UI events are handled on the server side and thanks to IOC the most of this can be customized. A good example is adding additional actions like launching a workflow or so.
Note: the new directives produce editor markup which can be interpreted by other editors differently
In addition we want to expose a set of web-services following the CMIS standard to allow content manipulations.
So the both, the intercept filter and the "javascript.js" won't exist anymore.
Richard Unger
Does this mean I will be including Vaadin components in the authoring-view of my layouts?
I would ver VERY concerned about this.
One of the main problems we have with magnolia for our authors is with the templating-components.
Basically, the existing templating-components do not integrate well into arbitrary designs. There is too little control over size, placement and style, and this was one of the main motivators for developing our own templating-components. We can now set the style, alignment, etc... with sufficient flexibility to allow us to position the editing buttons whereever we need them.
I have also experimented with Vaadin - we have a few custom GUIs which we have already realized using Vaadin.
Bringing Vaadin into the front-end will not be easy, I think - we will have to deal with both CSS and JS conflicts between Vaadin and the page's layout.
Or expressed another way: In my opinion the templating-components need to be very "light-weight", having no impact on the site layout, and at the same time being tolerant to the layout's CSS and JS, over which we have little a priori control. Vaadin is definately not "light-weight".
Or have I misunderstood something?
Philipp Bärfuss
No you don't include the Vaadin components in your layout. The editor loads the page in a iframe and all javascript is isolated. the editor will then use the 'hints' in the loaded page to inject the editing functionality. This edit bars are normal divs having proper CSS classes.
Philipp Bärfuss
After some confusion I renamed the singleton area and use now the term "slot". An area is of type "collection" or "slot". This allows us to define more types if neede.
Christian Ringele
I like that naming, really tells what it is, and can't be confused with singleton terms already in use in STK.
Philipp Bärfuss
The directives/tags and the functions need a different name so I felt back on cmsfn for the functions. This is a bit uggly but I have not found a nicer solution.
Christian Ringele
cms:render
If passing a node to render, why the script has to be passed. Is the definition not stored in the metadate anymore? Probably I understand it wrong. As an optional value its really nice, but if mandatory not.
I big plus of rendering magnolia content is that you can render it, without knowing what the script it to render it with -> fetching some target node and you can just render it.
Philipp Bärfuss
Ups, that was a leftover and I changed it as you said.
Christian Ringele
topic functions:
parent(content, [type])
children(content, [type])
would be nice, if both could be used without a [type] -> when no type passed, the type of the passed content is taken.
Philipp Bärfuss
Using the brackets means that the parameter is optional param. Passing no type means that the method doesn't care about node types then and will return the direct parent, respectively all children.
Matt Dertinger
Here are a few requests I often get from content authors:
copy
button, along with themove
,edit
anddelete
buttons. Once the paragraph has been moved to the new page, it's content should be editable without effecting the original content that it was copied from.reference
node available fordialog
configuration, etc. in the STK. UI wise, content that is referenced should be marked as such when in edit mode (maybe something like the alias arrow in Mac OS X could be used). There should also be a button available in the editBar to create the reference from the original paragraph. Additionally, similar to the currentdependencies
tab, content authors should be able to view a list of all pages that refer to a particular paragraph. Developers should be able to configure whether content can be referenced, perhaps areferenceable
node with a boolean value in the {{paragraph/template def)?It would also be nice to see a list of all pages that have existing content that use a particular paragraph/template def. This would help with testing and refactoring. For instance, if I update this paragraph definition, what pages do I need to look at to verify I didn't break something?
Philipp Bärfuss
1. copy we are about to introduce the possability to move/copy paragraphs across different areas as well between pages
2. reference this has to be solved on a higher level but having a referencing feature which makes such content transparent is a good idea. The template script would simply not know that the current content is referenced (by faking the hierarchy while rendering.
3. undo has not much to do with the templating as such but this is foreseen as some of our mocks show.
4. paragraph search would have needed that several times myself (felt normally back on groovy scripts), but which tools we finally provide in the first release is not yet decided. Once we have the basics done right we will launch the discussion
Boris Kraft
what is the difference between a slot and a paragraph? If a slot can hold only one paragraph, where an area can hold many, somewhere the semantics of these words don't add up. Either you have an area, where all paragraphs are in slots, or you have areas where all content are paragraphs, and some are collections, some are not. The idea to call a single paragraph slot instead of singleton-paragraph is confusing for me.
Philipp Bärfuss
after some offline discussion we decided for the area types:
warning: we have serious discussions wether we should replace the term 'paragraph' with something easier to understand: block, component, ...
Christian Ringele
In training I never encountered a confusion about the term paragraph. I think its quite clear, cause it reflects a valid naming comparison to reality. Paragraph is a non technical word people know.
The reall confusin term in Magnolia always was 'Template:
- A page template (article etc, actually a definition), which defines its
- template script (jsp or freemarker)
- and a paragraph has a template script too
A pages template and a paragraphs template is then quite clear I think.
Personally I liked slot, bot no mattter, single is fine too.
- Slot for a paragraph
- Collection of pargraphs
were my favorites
Boris Kraft
FYI - In communication we always have to additionally qualify "Paragraph". Any non-Magnolian has no idea what we mean by "paragraph". But I agree that the whole templates naming scheme is really confusing.
Magnolia International
+1, a Magnolia "Paragraph" does not (necessarily) match what a paragraph means, and I've been suggesting renaming that concept for years
Philipp Bärfuss
Finally we decided for the name components. So Magnolia 5 will:
Now we have to experience a bit to see if we need more modifications.
Magnolia International
Chiming in late as usual, but won't that raise confusion with Java object components, ie
info.magnolia.objectfactory.Components
et al ?edit: as well as with templating-components ?
Christian Ringele
Me and Samuel Schmitt really really dislike the naming 'component':
1. Component is already a technical view/expression. The 'proof' of that is, that we need to rename things as templates-components and the Components (Object Factory).
This will lead to the same naming confiusions, as we have/had with the term 'template': 'You need to implement a new compnent - No not a Java class component, a page component and its script...'
2. A page component is not that clear, that could be anything needed for a page, for exampke a page script you could call a component too.
Samuel suggested, and I think thats a good naming which has no corellation to anything existing yet is: Element. A page element.
Evey non technical person will understand this:
'Add to the page a element, which renders a link list'
'You need to implement in your project a new page element, which renders a calendar entry from Lotus'
When we write project documentations, usually you write something like 'Add this element to the page'.
Boris Kraft
I honestly don't see why anybody would have difficulties to have at least an idea what "page component" could mean. Yes there are other things called component, but frankly we are talking different audiences here. An author will not bother about what other technical elements hidden from him may be called component. But she will have a much easier time understanding that she can create page components than paragraphs, simply because a paragraph has a different meaning specifically for authors.
On the other side, any decent developer will have no problem understanding the difference between a page component and anything else.
Christian Ringele
1. Delevolpers have now in training many confusing points about the naming 'template', if names are shared accross things, only experiance gets you a feeling for it. But that raises the entry barrier for new developers. We will produce the same confusion with the term components. When you give a training, you have to explain things. There it is irrelevant how good a developer is, but you will still need to always mention 'components, no not the one from the factory' and so on.
2. I think the term 'element' is as clear as component, but has not the mentioned draw backs. So why not using 'element' instead of components? And on the focus of not needing to rename anything existing (as templating-components and the ObjectFactory) it speaks for a different name too.
Philipp Bärfuss
I am aware of the fact that this conflicts with
info.magnolia.objectfactory.Components
but I think these are different enough to not confuse them with the page components. Especially now that we use IoC and the usage of this class will be rare.The templating components will have to be renamed to templating tags, directives, markup, ... I had always to explain what this 'components' are and it was never quickly grasped so renaming them wont hurt.
Christian Ringele
Had a talk with Boris, and now I belive you two
Components is fine.
Magnolia International
Ok if the "templating components" are already renamed, that's good. Indeed, the
i.m.o.Components
won't be used anymore, but the concept still exists (a module will still have to register... objects... components... manager-things and service-foobars...). Indeed very different concepts, and we might get away with a "prefix" to differentiate when needed (especially now that "templating component" is a free space )Richard Unger
I like where this is going. With all the discussion, I'm a bit lost as to what the final decision on the naming is? In any case, I don't think it is a big deal - just choose some names, people will adapt.
Making a single registry and aligning the definitions is a good idea, that will be less confusing.
Making the definition work with any content is also an improvement.
Please consider aligning the models in the same way. One of the most annoying side-effects of the current setup is that Template and Paragraph model-classes split into two trees below "RenderingModelImpl".
This means that a model-class inheriting from STKTemplateModel (required for STK templates) cannot be used for a paragraph model, and vice-versa.
A very common use-case is (at least, it is something I always need, I imagine other users will face the same trouble) to create a base model class, with some general functionality that will be needed in all the templates for a site. Just for example, if the site is a shop, you might want to create a BaseShopModel extends STKTemplateModel that provides the getShoppingCart() method in a central location.
The problem with the current setup is that you have to make 2 base models:
and duplicate all the common code (or create a delegate object or something like that). That's really annoying.
So it would be great if you could provide a single base model class, also for STK, that can be used for both paragraphs and templates (and areas).
Philipp Bärfuss
I am not sure if we can make it the same parent model (why should a paragraph have all the logic to assemble the navigation, ....) but we will do our best to make them not to different.
Anyhow, if you want to expose generic objects (like mgnl, stk, ...) one can register them in the freemarker configuration (server/rendering/freemarker/sharedVariables). We might even go as far as that any template definition can define such objects to uncouple this from the model class hierarchy.
Richard Unger
Another point:
For the template variants, you mention that json and xml variants will be always available.
Please make sure that these can be easily deactivated, it would be a definate No-No for us to permit our end-users to export arbitrary content as XML as JSON.
It's a nice feature, but needs to be disabled by default on the public instance, IMHO.
Philipp Bärfuss
right you are
Richard Unger
cms:render and other tags
It would be great to have more flexibility here. You permit passing the content and the template (definition).
Also, I express again the usefulness of inline-templates: allow specifying the freemarker code inline in the render tag. It's a really useful feature, mainly for debugging, but also to render some content with an alternate template, without having to create a whole new definition...
Philipp Bärfuss
true, this would facilitate the reuse of content a lot. we could make it very similar to the area tag which is not dependent on a definition
Mathias Conradt
Can somebody tell me how to properly get the property value of an inherited (string) property?
does not give me the value, neither does ${visual?string!""} nor ${visual.value!""}
${visual.string!""} gives me something what looks like the path to the property, but not the value:
${visual.value!""} gives me:
How to get the value from the QValueValue object in a freemaker template? I already googled for it, but ${visual.value.string} nor ${visual.value.value} does not work.
Christian Ringele
I hope you are aware that this is a proposal page for Magnolia 4.5 (2012&2111), we are now on Magnolia 5.4.
Was pure luck I saw this entry.
What you get back is a JCR Property:
You need to get the value out of the JCR Property:
I tried it with a standard default page property called 'title, works fine:
Mathias Conradt
Thanks, I meanwhile got it working via
Christian Ringele
Strange,
${visual.string!
""
} should also work.
Basically
${visual.value.string!
""
}
calls Property.getValue().getString(), so just operating on the Value object first.${visual.string!""} gives me something what looks like the path to the property, but not the value:
The path I got when I printed directly the property:
Title: ${title!"nope"}
Most important is, it works for you