Templates

Web pages created with Magnolia CMS are based on templates. Templates ensure that page structure and presentation remain consitent while the content varies from one page to another. For example, an event template helps you generate event pages that look and feel the same but display a different event each.

The system generates pages by merging a template with corresponding content from the repository. The position and inclusion of each page element is defined by the page template. The template allows authors to choose from a number of different components in a single area of the page.

Pages and components

Content nodes in the JCR hierarchy are rendered as headings, components, images, menus, forms, Javascript, meta-data and many other things. The following diagram shows the relationship between some content nodes and the corresponding page elements.

Note! The diagram shows the detailed JCR view on the left. This is not how authors see content. The user interface for authors and editors hides much of the complexity, providing a user-friendlier way to manage pages and paragraphs.

Numbered items:

  1. An article about basketball in the New York Times Sports sections has the following page properties:
    • title rendered as an H1 element on the page, "Bulls and the Thunder Make a Stand".
    • date and author rendered on the dateline.
    • abstract to provide an introductory paragraph.
  2. The next element on the page is the main collection which contains components.
  3. Component 0 is a text paragraph ("LeBron James scored 13...") with a matching image. The image file and its caption and credit are stored in the document management system (DMS).
  4. Copmponent 00 consist of text and an optional subtitle element "THUNDER 101, LAKERS 96".
  5. The page ends with a footer singleton paragraph which is a kind of placeholder. It can contain content such as a copyright statement.

Templating mechanism

Magnolia CMS templating mechanism consists of the follow components:

  • Template definition makes a template script available to the system by providing a name for it. It is the configuration for the template script. For instance, it defines the model class to use.
  • Template script renders the content. The script is written in FreeMarker, JSP or a custom templating language. The script instructs the renderer where to place the content on the page and also contains placeholders for content attributes such as headings and images.
  • Dialog is used to enter and edit content. It is a customized HTML form with fields for entering text and meta data and selecting images.
  • Content for the page or component is retrieved from the repository. It may contain text and references to images that need to be rendered. The content node meta data assigns it to a particular template definition. This way the rendering engine knows which template definition applies to the content. Through the definition, it can then choose the correct renderer. Note that the reference to a template definition is only a suggestion. It is also possible to use something else to render the content. You might define an alternative template when rendering content for a mobile device, for example.

Component relations

Below you find a more detailed map of relationships between the elements that make up the template mechanism. Starting at the top left corner, a template definition defines the template script used to render the content. The location of the script is given in the templateScript property. The template definition also assigns a dialog definition in the dialog property. The dialog definition is a group of configuration nodes just like the template definition. It defines what tabs and fields should be present in the dialog.

The template definition further defines a modelClass. Model is a Java program that holds your business logic. The model can do any task required such as execute a Google search or calculate an insurance policy. It holds the results of the logic execution and passes them to a renderer.

The renderer includes the results on the page as instructed by the template script. The script tells the renderer where to place the content. It contains placeholders for content attributes such as headings, images and the results of the business logic execution.

A Web page is the output of the rendering process where template and content are combined.

The following class diagram shows the relationships between the objects collaborating in rendering of a template.

Templating languages

The system provides two renderers out-of-the-box: JSP and Freemarker.

JSP stands for Java Server Pages. It is an extension of Java Servlet technology for combining Java server-side programs and HTML.

Writing a Magnolia CMS component in JSP:

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root version="1.2" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core"> 
    <jsp:directive.page contentType="text/html; charset=UTF-8" 
    session="false" />
    <c:if test="${not empty content.image}"> 
        <img src="${pageContext.request.contextPath}${content.image}" 
        class="contentImage_${content.imageFloat}" 
        alt="${content.imageAlt}" /> 
    </c:if> 
    <c:if test="${not empty content.title}"> 
        <h2>${content.title}</h2> 
    </c:if> ${content.text} 
</jsp:root>

With Magnolia CMS 4.0, we added support for Freemarker for several reasons: not only for its flexibility, cleaner syntax and better error reporting but also because it does not depend on the file system; templates don't have to be extracted to the file system so they can easily be stored in the repository.

Writing the same paragraph in Freemarker:

[#if content.image?has_content]
    <img src="${contextPath}${content.image}" 
    class="contentImage_${content.imageFloat}" 
    alt='${content.imageAlt!""}' />
[/#if]
[#if content.title?has_content]
    <h2>${content.title}</h2>
[/#if]
${content.text!""}

You can mix and match templates and paragraphs using both templating languages at will. You can also use another templating language. If a renderer for your language is available, it is likely that you can incorporate it into Magnolia CMS. This allows you to use a templating language that you are already familiar with.

Tag library

The Magnolia CMS tag library allows developers to customize the authoring environment and create templates in a fast, efficient and re-usable way. The system additionally supports third-party tag libraries such as JSTL to minimize the amount of code developers have to write.

Most important tags:

mainBar. Displays a toolbar that allows you to change page properties and switch to the preview mode. This tag can also add CSS and JavaScript links on the page if not previously defined but it is recommended to you add the cms:links tag to the header of the page instead. CSS links are not valid inside the HTML body element.

[@cms.mainBar label="Page Info" dialog="stkHomeProperties" /]

newBar. Displays a toolbar that allows you to create new components. The list of available components is passed as a list.

[@cms.newBar contentNodeCollectionName="mainColumnParagraphs" paragraph="samplesTextImage,samplesDownload,samplesLink" /]

editBar. Displays a toolbar that allows you to edit a component. This tag is often used within contentNodeIterator, which in turn will set all relevant parameters automatically.

[@cms.editBar /]

contentNodeIterator. Iterates over a contentNode collection. This tag is used whenever you want to loop over content, typically a collection of components. Parameter contentNodeCollectionName contains the name of the contentNode you are looping over. The contentNodeCollectionName is created in the first place by providing the name to a newBar. This will result in elements being created within that contentNode, and allows you to loop over them later.

[@cms.contentNodeIterator contentNodeCollectionName="main"]
   [@cms.includeTemplate /]
[/@cms.contentNodeIterator]

includeTemplate. Delegates the task of rendering a component to an appropriate ParagraphRenderer or includes JSP. When used within contentNodeIterator the parameters are provided automatically by the loop.

[@cms.includeTemplate contentNode=content.footer /]

Example of CMS tags in use

Here is an example how tags are rendered.

  1. A toolbar for the body of the page is added automatically. It allows you to define page properties and preview the page.
  2. The main area of the page is rendered with the area tag. The main area has its own template script which loops through any components inside the area and renders them. Note that the component with the basketball players, for example, is not rendered by the page script or the area script but the component script. As is the case with the page, the toolbars for areas and components are added automatically.
  3. The footer section also uses the component tag. In this case it renders a single component named in the content attribute.

contentNodeIterator (2) and newBar (3) are typically used together. contentNodeIterator renders the stored content, in this case the main collection. newBar stores new content into the main collection. The collection name is not fixed, it is defined within the script by the developer.

Templating support objects

These objects are available to template scripts to simplify development.

ObjectPurpose
contentCurrent content node exposed as a map like cms:setNode.
page or actpageCurrent page exposed as a map like cms:setNode. This attribute is called actpage in JSP because the name page is reserved.
defCurrent RenderableDefinition (template or component definition object).
modelJavaBean created by the renderer based on a modelClass defined in the paragraph or template definition. The current content, definition and the parent model are passed to the constructor.
actionResultThe result of the model's execute method. This string can be used to determine the template (in the definition) or in the template itself.
mgnlAn object providing access to various components and utility methods, for example to create links. See MagnoliaTemplatingUtilities.
ctxCurrent Context. Depending on the type of request, a different implementation will be used, but for a web request to a page, this will be a WebContext instance. In a web request, you can use ${ctx.contextPath} to get the context path corresponding to the current request.
stateCurrent AggregationState.
stkProvides access to STK templates. See STKUtil in JavaDoc.
i18nMessages from the current message bundle like the "Read on" message. i18n['<message key>'] for example i18n['link.readon']

Example usage:

[#-- Accessing content --]
The value of "someProperty": ${content.someProperty}
Accessing a child node: ${content.childNode}
Accessing the child node collection: ${content?children}
Accessing the parent node: ${content?parent}

[#-- Special content properties --] The current node handle: ${content.@handle} The current node name: ${content.@name} The current node uuid: ${content.@uuid}

[#-- MetaData --] The creation date: ${content.metaData.creationDate} Metadata.modificationDate: ${content.metaData.modificationDate!" This node has never been modified."}

[#-- Component definition --] The current component definition: ${def.name} A component definition property: ${def.style}

[#-- Context: ctx --] A request parmeter: ${ctx.myParam} The current user name ${ctx.user.name} The current locale ${ctx.locale}

[#-- MagnoliaTemplatingUtilities: mgnl --] Create a link to a page: ${mgnl.createLink(content)} Create a binary link: ${mgnl.createLink(content.image)} Referenced page: ${mgnl.getContentByUUID(content.referencedPage) @handle}

[#-- Status based rendering --] This is ${mgnl.authorInstance?string('indeed', 'not')} an author instance. This is ${mgnl.editMode?string('indeed', 'not')} the edit mode. This is ${mgnl.previewMode?string('indeed', 'not')} the preview mode.

[#-- The Model executed before the paragraph rendering: model --] The parent model: {model.parent} The result of the execute method: ${actionResult}

[#-- AggregationState: state --] Entry point of the rendering: ${state.mainContent} Current content node: ${state.currenContent}

Accessing your own Java methods from Freemarker

To access Java methods and functions from your own classes:
  1. Write and compile your Java class as you normally would.
  2. Copy the class file in WEB-INF/classes folder of your Magnolia web application.
  3. In AdminCentral, go to Configuration > /server/rendering/freemarker/sharedVariables.
  4. Under sharedVariables, create a content node myClass.
  5. Under myClass, create a data node class and set its value to the class name of your class, previously placed in WEB-INF/classes.
This allows you to access all the static methods the custom class from all the templates using ${myClass.myMethod()} Freemarker syntax.