Magnolia 5.6 reached end of life on June 25, 2020. This branch is no longer supported, see End-of-life policy.
Directives are a collection of templating statements and commands that simplify scripting. FreeMarker offers it's own directives and key templating features are available as custom Magnolia directives. Directives are quick to type but can render complex output.
Here are the most useful FreeMarker directives with sample code:
Common operators ( &&, ||, !, ==, !=, >, <, >=, <=
) are supported
Boolean test
[#if content.header?has_content] <h1>${content.header}</h1> [#else] DO_SOMETHING_ELSE [/#if]
[#if content.imageLocation == "top"] … [/#if]
[#if content.date?has_content] ${content.date?time?string.short} [#elseif content.endDate?has_content] ${content.endDate?time?string.short} [#else] No date is set! [/#if]
Can iterate over any collection that extends a Java collection.
[#list model.getSomeList() as elem] <li>${elem.title!}</li> [/#list]
Assign allows you to define variables. Any object except null can be passed to a variable.
[#assign title = content.title!content.@name] [#assign hasDate = content.date?has_content] [#assign dateShort = content.date?time?string.short] [#assign events = model.events] [#assign stringgy = "Some direct string data"]
The include directive includes a FreeMarker template script.
[#include "/my-module/templates/myScript.ftl"]
Macros allow you to reuse snippets of FreeMarker code.
[#macro test foo bar="Bar" baaz=-1] Test text, and the params: ${foo}, ${bar}, ${baaz} [/#macro] [@test foo="a" bar="b" baaz=5*5-2/] [@test foo="a" bar="b"/] [@test foo="a" baaz=5*5-2/] [@test foo="a"/]
Magnolia provides three custom directives:
cms:area
renders an area. cms:component
renders a component.cms:block
renders a block.cms:page
enables the page dialog.These directives are implemented by the
Directives
class. This class is configured in modules/rendering/renderers/freemarker/contextAttributes/cms/componentClass
.
Standard FreeMarker directives start with the # character and custom directives with the @ character followed by cms
, a dot character, the name of the macro, and any parameters.
Syntax:
[@cms.<directive name> <attribute>=<value> /]
Example: Rendering a component
[@cms.component content=component /]
The cms:area
directive (
AreaDirective
) renders an area and any components inside it. Editors can add components inside the area. Available components are configured in the area definition.
[@cms.area name="content"/]
The directive references an area by its name. The area name is the node or item that contains the area definition.
On the author instance, the result on the page is an area bar and an end marker. The title
property is rendered in the bar. When editors click the Add icon in the New Component box they can add components inside the area.
Attributes:
name | Name of the area definition node. |
contextAttributes | A hash of key-value pairs. Any custom attribute and its value as retrieved from the current context. [@cms.area name="content" contextAttributes={"divIDPrefix":divIDPrefix, "componentModel":model} /] |
The cms:component
directive (
ComponentDirective
) renders a component. The content
attribute defines what content the component edits. This tag is commonly used inside the list
directive to loop through the components in a map.
The content to render, and possibly edit in case of an editable component, is passed in the content
attribute. On the author instance the directive renders a component toolbar. The value of the title
property is rendered in the bar.
Attributes:
editable | Defines whether edit icons should be displayed. Mainly useful if content is inherited. Default is |
dialog | Opens the specified dialog when editing the component. |
contextAttributes | A hash of key-value pairs. Any custom attribute and its value as retrieved from the current context. [@cms.component content=component contextAttributes={"indexString":indexString, "useIndex":useIndex}/] |
Example:
[#list components as component ] [@cms.component content=component /] [/#list]
The cms:block
directive (
BlockDirective
) renders a block. The block directive and its API is provided by the content editor module which requires an EE license.
On the author instance in the Stories app or in a custom content editor, the directive provides UI elements to edit the content of the block.
The directive is commonly used inside the list directive to loop through blocks wrapped by a composition node of an article.
[#if articleContent?hasContent] [#assign blocks = cmsfn.children(articleContent, "mgnl:block") /] [#list blocks as block] [@cms.block content=block /] [/#list] [#/if]
The content
attribute (see line 4 above) defines the block node to be edited or rendered.
The cms:page
directive (PageDirective
(Git)) enables the page dialog, if any. The directive is added to the head element of the page template.
<head> [@cms.page /] </head>
The following attributes can be passed with any directive. They define which content the element created by the directive should work on.
Attributes:
content | An item, list or map. |
workspace | Workspace used if path is defined. Same as of the current content |
path | Path in the workspace. |
The content
attribute tells a script which item it should operate on. Scripts typically operate on the "current" node. For a page-level script the current node is the page, for an area-level script the current node is the area, and for a component-level script the current node is the component. However, there are cases where you want the script to operate on a different node. This is where the content
attribute is handy.
For example, assuming meta
area is a child area of main
area, and is a noComponent
area that has no content or components of its own. The area can operate on the page content to render information such as the page title. This is achieved using the content
attribute.
In the page script we tell the main
area "You should operate on the current node, which is a page because I am a page-level script".
<div id="wrapper-3"> [@cms.area name="main" content=content/] [@cms.area name="adverts"/] </div>
In the area script we again pass the same instruction down to the meta
area: "You should operate on the current node which is (still) the page".
<div id="main" role="main"> [@cms.area name="breadcrumb" content=content/] [@cms.area name="meta" content=content/] [@cms.area name="content"/] </div><!-- end main -->
Now the meta
area edits page content. Although it resides inside the main area DIV element on the page, the title really belongs to the page. It is a property of the page, not of the area, so it makes sense to store this property under the page node in the content structure.
The workspace
attribute tells the directive which workspace of the magnolia
JCR repository the content resides in. This is almost always the website
workspace and defaults to website
automatically if the current content resides in the website
workspace.
Here is an example of how directives are included in a page script and rendered on the page.
cms.page
directive enables the Page properties dialog.cms.area
directive calls the areas to be rendered. The directive identifies area by name. If an area has child areas you need a separate script which calls the children to be rendered. However, if the area contains only components you don't need an area script.