Similar content

Loading

Powered by Canoo FindIT.

Templating

Basics

Before attempting to write new STK templates, we suggest that you first become familiar with Magnolia templating. The following guides and resources are available:

The STK uses FreeMarker as the standard templating language. You can find a Magnolia-related introduction to this language at FreeMarker Primer.

STK Templating

In-place Template Scripts

All of the FreeMarker STK template scripts are accessible in the Templating Kit - Templates workspace. The templates can be immediately changed in Magnolia itself, which is ideal for evaluation, prototyping or smaller projects.

Templates can be edited in the Edit Dialog.

 

Once a template has been modified, it is necessary to check the Enable template box in order to tell the STK to use the customized template.

Loading Template Scripts

The template scripts can be loaded in three ways. The system searches for a template in the following order and places:

  1. The filesystem of the webapp;
  2. The in-place Templates workspace. The template needs to be enabled to be considered; and
  3. The class path. This is where the default STK templates are located.
The next question is where to ideally put the scripts and the answer varies according to the task:
  • Webapp is ideal when you want to edit real files, but are not going as far as creating a java project;
  • In-place Template workspace is suitable for prototyping, if you are using Magnolia as a service or in a wiki-style system;
  • Class path is ideal if you use a module, which is recommended for bigger projects or to facilitate team collaboration, as any modifications in your IDE are then immediately loaded.

main.ftl

This is the default entry point for all templates and is configured in the template prototype of the site definition. It is also a very good starting point from which to explore the system.

The following is an abbreviated version of the main.ftl template script.

<!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
[#assign cms=JspTaglibs["cms-taglib"]]
[#assign cmsu=JspTaglibs["cms-util-taglib"]]

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="${model.language}" lang="${model.language}">

<head> [#include def.htmlHeader.template] </head>

...

<body ${bodyID} ${bodyClass}> [#if def.dialog?has_content] [@cms.mainBar label="Page Info" dialog="${def.dialog!}" /] [#else] [@cms.mainBar label="" /] [/#if]

<div id="wrapper">

[#include def.header.template]

<div id="wrapper-2"> [#include def.navigation.vertical.template] <div id="wrapper-3"> … <div id="main"> [#if def.breadcrumb.enabled] [#include def.breadcrumb.template] [/#if]

[#include def.mainArea.template]

</div><!-- end main --> … </div><!-- end wrapper-3 --> … </div><!-- end wrapper-2 -->

[#include def.footer.template] </div><!-- end wrapper -->

</body> </html>

Let's analyze a few parts in detail.

<!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
[#assign cms=JspTaglibs["cms-taglib"]]
[#assign cmsu=JspTaglibs["cms-util-taglib"]]

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="${model.language}" lang="${model.language}">

Loads the tag libraries and assigns them.

   <head>
      [#include def.htmlHeader.template]
    </head>
The template loads dynamically and has been configured for the HTML header. This template is responsible for loading the various CSS and javascripts. To extend the HTML header, one could do the following:
  1. create a custom header template, for example /myproject/templates/global/htmlHeader.ftl;
  2. include the original header template - [#include "/templating-kit/templates/global/htmlHeader.ftl"];
  3. add the additional content. Perhaps some special meta tags, inline javascript, etc.
The same schema can be applied to many other use cases.

<body ${bodyID} ${bodyClass}>
The bodyID and bodyClass is set. The bodyID is configured in the template definition and allows custom styling for each template, while using a single CSS file. The bodyClass is calculated by the model if it is not configured directly on the template: ${model.bodyClass}. It transforms the actual configuration into an allowed body class. The considered configurations are:
  • vertical navigation shown?, which can change based on the page's level;
  • floating teasers;
  • extras (enabled, columns, small or big).
The bodyClass is then used in the CSS to style a page differently. For example, the width of the main div will be different if no vertical navigation is shown. This is the case until the current page reaches a deep-enough level to extend the horizontal navigation.

    [#if def.dialog?has_content]
        [@cms.mainBar label="Page Info" dialog="${def.dialog!}" /]
    [#else]
        [@cms.mainBar label="" /]
    [/#if]
Adds the main bar and configures it to use the dialog specified in the template definition.

    [#if def.breadcrumb.enabled]
        [#include def.breadcrumb.template]
    [/#if]
This snipped can be used in many variations in all the areas. It checks if an area is enabled, and if it is,  includes the configured template.

STK-specific Context Objects

In addition to the normal context objects (being content, def etc.), you can also add a STK object. Some of the common objects are enhanced by additional features.

Object Note
stk An instance of the STKUtil
content Same as normal, but will print the content HTML encoded by default. To avoid this, use the following code: ${stk.decode(content).title}
def In the case of a template definition, it is most likely an instance of STKTemplate
model Depends on the modelClass defined in the template, but is most likely an instance of an STKTemplateModel

The following are some useful snippets:

  the current site definition: ${model.site.name}
  the current site root: ${model.siteRoot.title}

Resources (Javascripts and CSS)

Configuration

CSS and javascript files can be defined on three levels:

  • theme;
  • site definition; and
  • template definition.
It is not necessary to store your resources in the Templating Kit - Resources workspace as they can point to any valid internal or external URL.

Bypassing the Workspace

The content in the workspace can be bypassed by checking the "bypass" option in the advanced tab. In that case the corresponding file in the class path will be used. This is mainly useful while developing or testing.

FreeMarker based resources

If a resource is of the type "processed", the content is interpreted as a FreeMarker template. This facilitates the use of constants, variables or any other logic. In the dialog of processed resources, it is possible to define the model class to be used, so that you can use any java logic or Magnolia functionality.

Aggregation of Javascripts

The /templating-kit/js/all script is an aggregation script, which combines all child pages into a single file. It also sets a context path variable that is used by some of the scripts.

/**
 * Aggregated script. All javascripts under this node will be included.
 */

var contextPath = '${contextPath}';

[#list content?children as subnode] ${mgnl.renderTemplate(subnode)} [/#list]

Site-aware Resources

A resource is not able to identify the current page as the page is only loaded once per site. This ensures that heavy javascripts or CSS files are only downloaded once and are cacheable. However, a resource can access the site definition through the model: ${model.site}