Directives

Directives are a collection of templating statements and commands that simplify scripting. FreeMarker offers its own directives, and key templating features are available as custom Magnolia directives. Directives are quick to type, but can render complex output.

Standard FreeMarker directives

Here are the most useful FreeMarker directives with sample code.

Using the compress directive in FreeMarker is not recommended because it may break area rendering. Consider installing the HTML Compressor module or the HtmlCompressor library instead.

if, else and elseif

Common operators (&&, ||, !, ==, !=, >, <, >=, <=) are supported.

Boolean test
[#if content.header?has_content]
   <h1>${content.header}</h1>
[#else]
   DO_SOMETHING_ELSE
[/#if]
Value comparison
[#if content.imageLocation == "top"]
   …
[/#if]
Alternatives
[#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]

list

This can iterate over any collection that extends a Java collection.

[#list model.getSomeList() as elem]
   <li>${elem.title!}</li>
[/#list]

assign

This 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"]

include

This includes a FreeMarker template script.

[#include "/my-module/templates/myScript.ftl"]

macro

This allows you to reuse a snippet 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"/]

Custom Magnolia directives

Magnolia provides four 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 info.magnolia.templating.freemarker.Directives class, which 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> /]
Rendering a component in FreeMarker
[@cms.component content=component /]

cms:area

The cms:area directive (info.magnolia.templating.freemarker.AreaDirective) renders an area and any components inside it. Editors can add components inside the area. Available components are configured in the area definition.

Rendering an area in FreeMarker
[@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: 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} /]

cms:component

The cms:component directive (info.magnolia.templating.freemarker.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 the 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 the Edit icon should be displayed. Mainly useful if the content is inherited. Default is cmsfn.isFromCurrentPage().

  • dialog: Opens the specified dialog when editing the component.

  • contextAttributes: 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]

cms:block

The cms:block directive (info.magnolia.templating.freemarker.BlockDirective) renders a block. The directive and its API are provided by the Content Editor module, which requires a DX Core 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.

cms:page

The cms:page directive (info.magnolia.templating.freemarker.PageDirective) enables the page dialog. The directive is added to the <head> element of the page template.

<head>
    [@cms.page /]
</head>

Common directive attributes

The following attributes can be passed with any directive. They define which content the element created by the directive should operate on.

Attributes
  • content: Item, list or map.

  • workspace: Workspace used if the path is defined. Same as of the current content.

  • path: Path in the workspace.

content attribute

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.

  • 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 comes in handy.

For example, let’s assume the meta area is a child area of the 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, the main area operates on the current node (page).

<div id="wrapper-3">
    [@cms.area name="main" content=content/]
    [@cms.area name="adverts"/]
 </div>

In the area script, the meta area operates on the current node (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 the page content. Although it resides inside the <div> element of the main area 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.

workspace attribute

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 that workspace.

Example directive rendering

Here is an example of how directives are included in a page script and rendered on the page:

  • The cms:page directive enables the page properties dialog.

  • The cms:area directive calls the areas to be rendered. The directive identifies areas by name. If an area has child areas, you will need a separate script that calls the children to be rendered. However, if the area contains only components, you do not need an area script.

Feedback

DX Core

×

Location

This widget lets you know where you are on the docs site.

You are currently perusing through the DX Core docs.

Main doc sections

DX Core Headless PaaS Legacy Cloud Incubator modules