This page explains how to use the Magnolia Templating Kit (MTK), provided as a submodule of the Magnolia Templating Essentials module (MTE) . 


Magnolia Templating Essentials (MTE) provides useful templating functionality for all projects in the form of templating function libraries, definitions, imaging support and templates via the MTK submodule. MTE is front-end framework agnostic, which means you can use it with any modern CSS and JS framework.

MTK is a small set of ready-to-use component, area and page templates, that supplies the basic functionality that is common across websites. The templates are designed to be flexible, with dialog options that enable them to fit many use cases without development. The MTK templates can be used "as is", modified to suit your projects needs, or simply used as helpful examples of best-practice Magnolia templating. The MTK is intentionally small so that developers can learn it quickly.  CSS is kept to a minimum to enable developers to easily integrate their own CSS or frameworks. 

In addition to the standard maven module, the MTK is also available as a light module for easy access to the files. To get the latest version, see the download area on the release notes pages.

To experiment with MTK or Magnolia templating, put the unzipped MTK light module in Magnolia's resource directory, and make changes to the files. Due to Magnolia's resource loading mechanism, these files will be used instead of the ones in the Java classpath provided by the Maven module. 

MTK template definitions

The MTK module includes pagearea and component templates and associated dialogs.

Page template

The basic page template is a good starting point for custom page templates.

The basic template contains:

  • Page definition, page template script and a page properties dialog that allows you to set titles and metadata.
  • Areas: htmlHeadernavigationmain and footer
  • Components that are available in main and footer areas. See the page definition for component availability.
  • Navigation scripts.


The areas are defined in the page template (see the areas node below). Areas typically define what components editors can place inside the area (see the availableComponents node in footer and main areas below).

templateScript: /mtk/templates/pages/basic.ftl
dialog: mtk:pages/basic
renderType: freemarker
    link: /.resources/mtk/css/normalize-3.0.3.css
    link: /.resources/mtk/css/html5boilerplate-main-5.3.0.css
    link: /.resources/mtk/css/video.css
    link: /.resources/mtk/js/modernizr-2.8.3.min.js
    type: noComponent
    createAreaNode: false
    templateScript: /mtk/templates/areas/htmlHeader.ftl
    type: noComponent
    createAreaNode: false
    templateScript: /mtk/templates/areas/navigation.ftl
      components: all
      enabled: true
    availableComponents: &footerAvailableComponents
        id: mtk:components/link
        id: mtk:components/textImage
        id: mtk:components/image
    availableComponents: # using all components from footer plus others
      <<: *footerAvailableComponents
        id: mtk:components/html
        id: mtk:components/linkList
        id: mtk:components/teaser
        id: mtk:components/video
        id: mtk:components/pageIntro


The MTK provides basic components for use in your templates:

Text and image

ID: mtk:components/textImage

Displays text and an image.

ID: mtk:components/link

Creates a link to an internal or external page or a downloadable asset.

ID: mtk:components/linkList

Organizes link components into a bulleted, inline or ordered list.


ID: mtk:components/image

Displays an image.


ID: mtk:components/teaser

Promotes another Magnolia page, third-party website or a downloadable asset, inviting the visitor to click for more.


ID: mtk:components/html

Allows editors to enter HTML markup and renders it on the page.


ID: mtk:components/video

Adds the possibility to add a video. Videos can be taken from the assets app - or you may just add "embed code" as provided by youtube and other public video repositories.

Page intro

ID: mtk:components/pageIntro

A component to render the page properties title and abstract.


The MTK provides basic navigation to use in your templates. Add subpages to see the navigation.  

The navigation is provided by two scripts that use navfn templating functions which are included in the MTE module.

The navigation area is rendered by the navigation.ftl script. This script sets the root page, navigation depth and behavior, and includes the navigation.ftl macro. 

[#include "/mtk/templates/macros/navigation.ftl"]

[#assign navigationRootPage = navfn.rootPage(content)!]

[@navigation navParentItem=navigationRootPage depth=1 expandAll=true /]

The macro does the "heavy-lifting" and generates a simple navigation which you can use as a starting point.

[#-- Basic navigation macro which generates simple navigation. You can adjust it to fulfil your needs. --]
[#macro navigation navParentItem depth=1 expandAll=false navClass="nav"]

    [#if navParentItem?has_content &amp;&amp; depth > 0]
    <ul class="${navClass}">

        [#assign navItems = navfn.navItems(navParentItem)]
        [#list navItems as navItem]
            [#-- This is example how to resolve navigation from the content apps. Uncomment and adjust to your needs.
            [#if navfn.hasTemplate(navItem, "mtk:pages/contactsOverview") || navfn.hasTemplateSubtype(navItem, "contactsOverview")]
                    [#if navfn.isHiddenInNav(navItem)]
                        <a href="#">${navItem.navigationTitle!navItem.title!navItem.@name}</a>
                        <a href="${!"#"}">${navItem.navigationTitle!navItem.title!navItem.@name}</a>
                        [#assign navContentItems = navfn.navItemsFromApp("contacts", "/", "mgnl:contact")]
                        [#list navContentItems as navContentItem]
                            <li><a href="${navfn.linkWithSelector(navItem, navContentItem)!"#"}">${navContentItem.lastName!navContentItem.@name}</a></li>
                [#assign activeNavItem = navfn.isActive(content, navItem)] [#-- Active navigation item is the one which is same as current page--]
                [#assign openNavItem = navfn.isOpen(content, navItem)] [#-- Open navigation item is the one which is ancestor of current page--]
                [#if activeNavItem]
                    <li class="active">
                [#elseif openNavItem]
                    <li class="open">
                        <a href="${!"#"}">${navItem.navigationTitle!navItem.title!navItem.@name}</a>
                        [#if expandAll || activeNavItem || openNavItem]
                            [@navigation navItem depth-1 /]
            [#-- End 'if' for navigation from the content apps]


#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))