Magnolia 4.5 reached end of life on June 30, 2016. This branch is no longer supported, see End-of-life policy.
Magnolia Templating Samples module is a showcase of Magnolia templating features for developers. It contains customizable examples of dialogs, page and component templates, and servlets. The examples demonstrate how to write the same action in Freemarker and JSP and introduce the tag libraries.
Templating Samples is available in the add-ons
folder of both the Enterprise and Community Edition bundles. You can also download it from the Magnolia Store or Nexus repository.
Templating Samples is a community module. It is not typically installed. Go to Magnolia Store > Installed modules in AdminCentral to check. To install the module individually, see the general module installation instructions.
See the general module uninstalling instructions and advice.
Shortcuts to the module configuration are in the Samples > Configuration menu in AdminCentral.
The module demonstrates how to customize the following page elements and components:
There are a number of toolbars on each page:
The authoring system uses Dialogs for content contribution and editing. Component dialogs are accessed by clicking edit icon in the toolbars.
The sample dialog definitions are in /modules/samples/dialogs
.
There are six sample dialogs:
mainProperties
configures page specific properties such as meta data.howTo
edits component title, text, image upload and date selection.samplesTextDialog
edits component title and text.externalLinkDialog
edits component external link title and target URL.intermalLinkDialog
edits component internal link title and target URL.samplesFieldShowRoom
demonstrates a variety of controls (input fields).Dialogs can be linked to page, area and component definitions and the same dialog can be used reused multiple times. For example the mainProperties
dialog is used by the main
page definition and the searchResult
component definition, and the samplesTextDialog
by the linkList
and text
components definitions.
A properties dialog typically allows for page specific properties such as the title displayed in the browser window and navigation menu, and page meta data such as the page keywords and description. Open any page on demoauthor and click Properties in the top bar to see how the dialog is used in the Standard Templating Kit.
The mainProperties
dialog in the Templating Samples module is a simple dialog that you can customize. It contains one tab
control , one edit
control and one fckEdit
control.
To open the dialog, click Properties in the top bar on any page based on the main
template, for example the ftl-sample-site
or jsp-sample-site
page. Change the title and note how the page title, browser window and tab title change dynamically. The title inserted in Website when the page is created is used as the default title
property and is rendered by the main page script.
To access the dialog configuration go to Samples > Configuration modules/samples/dialogs/mainProperties
. For a list of properties you can use in a dialog definition see Dialogs .
The howTo
dialog is an example of a component dialog. It is referenced in the howTo component definition. The dialog allows the user to enter a title and text, upload an image and select a date from a calendar. The HowTo
component script renders the dialog content and some additional content.
To open the dialog, open the ftl-howTo
or jsp-howTo
page, click the Main toolbar and then the Edit icon in the HowTo component toolbar.
The howTo
dialog configuration is in Configuration /modules/samples/dialogs/howTo
. The four fields use the edit
, fckEdit
, file
and date
controls.
The samplesTextDialog
is a simple dialog that contains two fields, title
and text
. The dialog configuration is in Configuration /modules/samples/dialogs/samplesTextDialog
. This configuration is identical to the howTo
dialog with the omission of the image
and date
fields. The dialog is referenced the linkList
and text
component definitions.
The externalLinkDialog
and internalLinkDialog
dialogs demonstrate how input is collected to render external and internal links. The former uses the edit
control for the target URL and the latter the link
control that allows for the selection of an internal page.
The dialogs are referenced by the externalLink
and internalLink
component definitions and the content is rendered by the link
component script.
The dialogs are configured in Configuration modules/samples/dialogs/externalLinDialog
and /internalLinkDialog
.
The samplesFieldShowRoom
dialog demonstrates numerous input controls available in Magnolia. This dialog is referenced by the fieldShowRoom
component.
The component is meant to showcase the dialog tabs and fields, and only renders static content when added to a page. To view the dialog:
main
template click the Main toolbar.Each tab of the dialog shows the many controls available with varying options.
The dialog is configured in Configuration /modules/samples/dialogs/samplesFieldShowRoom
and shows sample configurations for most available fields.
The module includes a number of page, area and component templates written in FreeMarker and JSP. The template definitions are in Configuration modules/samples/templates/pages
and /components
. Area template definitions are configured in the page template definition.
A template definition makes a template script available to the system by providing a name and common template properties.
A template script renders content. It can be written in FreeMarker, JSP or a custom templating language. The script instructs the renderer where on the page to place content. It contains placeholders for content attributes such as headings and images.
Template definition properties vary from definition to definition, but all have the following required properties:
renderType
that determines the TemplateRenderer
to use.templateScript
that defines the URI to the script. For each sample template definition scripts in FreeMarker and JSP are provided.With the exception of these two properties, the Freemarker and JSP template definitions are identical. Magnolia ships with two renderers FreemarkerRenderer and JspRenderer .
All of the sample FreeMarker and JSP scripts functionally identical. Scripts can also be written in a custom templating language provided that you integrate a renderer for that language into Magnolia.
JSP scripts can only reside on the file system. They are extracted onto the file system during module installation or update. To test JSP template scripts and see your changes take effect:
/<CATALINA_HOME>/webapps/<contextPath>/templates/samples
folder. This is typically at <apache-tomcat>/webapps/magnoliaAuthor/templates/samples
.FreeMarker scripts can be loaded from any of the options below and the system searches for them in this order:
/<CATALINA_HOME>/webapps/<contextPath>/templates
folder.templates
workspace. The template needs to be enabled to be considered.The easiest way to test FreeMarker scripts is to recreate them in the templates
workspace:
samples
. This starts a folder hierarchy that matches the template path in the module JAR.samples
: areas
, components
, includes
, macros
and pages
.The module includes two page templates.
main
renders the FTL and JSP Sample Site pages and all sub pages except the Sample Product Selection pages.mainVirtualURI
demonstrates the use of virtual URI mapping and renders the Sample Product Selection pages. When you select a product, the page is reloaded with your selection in the URL.The template definitions are in Configuration /modules/samples/templates/pages/ftl
and /jsp
.
The templates are used on pages like this:
Page | Template definition | Template script |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Go to Website in AdminCentral to see how the templates are assigned to pages.
The main
page template is a generic template sample that demonstrates multiple elements and functionality.
The main
page template definitions are in Configuration modules/samples/templates/pages/ftl
and /jsp
. Like all the sample template definitions the FreeMarker and JSP samples differ only in the renderer set in the renderType
property and the template script referenced in the templateScript
property.
The main
template definition:
class
node. A model class can be used to extend the default template definition by adding custom properties. A model class provides additional functionality and many templates do not use one.titleSize
property that is allowed for by the model class. This property defines the size of the title on the page. The model class reads the titleSize
property and makes it available to the template script. The script can then either render the property value on the page or use it in some custom presentation logic. See main page script below.mainProperties
dialog. Click on Properties in the top bar of any page to see the dialog.visible
property to true
.A parameters
content node with custom properties under it can be added to the definition as an alternative to using a custom model class, or in addition to using one. Any properties under parameters
are available to the template script automatically.
Custom properties are made available to the template script through the def
templating support object. See examples in main page script below.
Model is a Java program that holds your business logic. It can do any task required, such as execute a search or calculate an insurance policy. It holds the results of the logic execution and passes them to a renderer.
The
SampleTemplate
model class demonstrates how to extend the default template with custom properties. The Java logic makes the titleSize
property available to the template script.
public class SampleTemplate extends ConfiguredTemplateDefinition { private String titleSize = "1"; public String getTitleSize() { return titleSize; } public void setTitleSize(String titleSize) { this.titleSize = titleSize; }
No Java logic is needed to make properties under the parameters
content node available. This is default functionality for which you do not need a custom class.
The main
page script renders the main
page template. Here are a few coding examples. More examples are provided in Area templates and Component templates discussed later.
Tag libraries
The cms.init
tag initializes the tag libraries. Once initialized the toolbars on the author instance render automatically.
FreeMarker
<head> ... [@cms.init /] ... </head>
In JSP in addition to the cms.init
tag, the libraries need to be referenced specifically. Appropriate references should be added to all scripts.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="cms" uri="http://magnolia-cms.com/taglib/templating-components/cms"%> <%@ taglib prefix="cmsfn" uri="http://magnolia-cms.com/taglib/templating-components/cmsfn"%> .... <head> .... <cms:init /> .... </head>
Areas
main
script is an inclusive script i.e. it includes all page areas using the cms.area name
tag. Each area definition references its own script.
FreeMarker
<div id="header"> [#-- ****** navigation area ****** --] [@cms.area name="navigation" /] [#-- ****** stage area ****** --] [@cms.area name="stage"/] </div><!-- end header -->
JSP
<div id="header"> <!-- ****** navigation ****** --> <cms:area name="navigation" /> <!-- ****** stage area ****** --> <cms:area name="stage" /> </div>
Custom properties
The def
templating support object provides access to the template definition. The values of custom properties are read using the dot notation: def.<propertyName>
titleSize
property is an example of extending the default template definition with a custom property that is allowed by the model class. It defines the size of the main heading on the page. The model class makes the property available to the script.customProperty
property under the parameters
content node is an example of automatically extending the default template definition. These properties are available to the template script automatically.To see how they work amend the main
script as shown in the code examples below:
titleSize
property in the template definition to see how page title size can be changed by configuration.def.customProperty
tag.FreeMarker
[#-- ****** page content ****** --] <h${def.titleSize!}>${content.title!content.@name}</h${def.titleSize!}> <p>${def.customProperty!""}</p><br />
For custom properties under the parameters
content node of the definition JSP needs the containing parameters
node as part of the notation.
<!-- ****** page content ****** --> <h${def.titleSize}> <c:choose> ... </h${def.titleSize}> <p>${def.parameters.customProperty}</p><br />
Here is the result with the titleSize
set to 3
.
The mainVirtualURI
template definition is an example of using virtual URI mapping . The page template definitions are in Configuration modules/samples/templates/pages/ftl
and /jsp
.
Example mappings are configured in Configuration modules/samples/virtualURIMapping/ftl-products
and /jsp-products
. The
RegexpVirtualURIMapping
class allows you to specify a pattern that matches a sequence of characters. The regular expression in fromURI
maps an incoming request to a page defined in toURI
. The user is forwarded to what appears to be sub page of ftl-sample-site/ftl-products
and jsp-sample-site/jsp-products
but in fact the same page is loaded. The action prefix forward
hides the true target and displays the fromURI
URL in the browser address bar.
The virtualURI
page script creates links to products.
In FreeMarker ctx.contextPath
gets the context path corresponding to the current request and ctx.parameters.product
renders the selection.
<p>Select a product: <a href="${ctx.contextPath}${content.@path}/product1">Product 1</a> <a href="${ctx.contextPath}${content.@path}/product2">Product 2</a> <a href="${ctx.contextPath}${content.@path}/product3">Product 3</a> </p> <p>You selected: <b>${ctx.parameters.product!"none yet"}</p>
In JSP pageContext.request.contextPath
gets the context path corresponding to the current request and param.product
renders the selection.
<p>Select a product: <a href="${pageContext.request.contextPath}${content['@path']}/product1">Product 1</a> <a href="${pageContext.request.contextPath}${content['@path']}/product2">Product 2</a> <a href="${pageContext.request.contextPath}${content['@path']}/product3">Product 3</a> </p> <p>You selected: <b> <c:choose> <c:when test="${not empty param.product}">${param.product}</c:when> <c:otherwise>none yet</c:otherwise> </c:choose>
When a user clicks a link, the selected product is appended to the request URL.
http://localhost:8080/magnoliaAuthor/ftl-sample-site/ftl-products/product3
The products
virtual URI mapping captures the product from the URL and passes it back to the page as context parameter. It is now available to the script through the ctx
templating support object in FreeMarker.
http://localhost:8080/magnoliaAuthor/ftl-sample-site/ftl-products.html?product=product3
The user is forwarded back to the originating page. The forward
action prefix ensures the true target URL is not visible to the user. The script displays the context parameter ("You selected: product3") on the page.
Pages consist of areas which can consist of further areas or components. Areas structure the page and control what components are available in the area. The area toolbar shows the name of the area. Areas also have an end marker, a narrower green bar that displays at the bottom of the area. For more information see Areas.
Area definitions are configured in the page template definition. In the main
page template the areas definitions are in Configuration modules/samples/templates/pages/ftl/main/areas
and jsp/main/areas
.
An area definition:
enabled
node.renderType
node.templateScript
node.type
node. There are three options:single
: Area can only contain one component at a time but multiple components can be made available as options. Example: stage
area.list
: Area can contain multiple components that render in a list. Examples:main
, extras
and footer
areas.noComponent
: Area cannot contain any editable components. Used for system-generated automatic content such as breadcrumbs or static content that changes rarely and remains the same across the site such as branding. Example: navigation
area.Components are made available in the availableComponents
node that defines which componets may be added in the area. availableComponents
is map of components built by reading the configuration into a Java Bean using the Content2Bean mechanism.
To make a component available in an area, add a content node into the map and reference the component definition. The id
property identifies the component definition. The first part before the colon (:) is the name of the module folder where the component definition resides. The second part is the relative path.
An autoGeneration
node in an area definition allows you to create content automatically. An autogenerated component is configured in the extras
area of the main
template. This configuration in discussed later in Link components. To view the component open the ftl-sample-site
or jsp-sample-site
page. It is the second component in extras
area titled An autogenerated LinkList.
Areas support inheritance which is configured in the inheritance
node. The footer
area is an example of inheritance. The components in the area cascade down to child pages automatically. Inheritable component are only editable on the source page. For more information see Inheritable components.
In the inheritance
node:
enabled
property enables and disables inheritance for the area.components
property:none
: No components are inheritable. This has the same effect as disabling inheritance by setting the enabled property to false.all
: All components added in the area cascade down to child pages automatically.filtered
: Components in the area cascade only if a Show in subpage checkbox is configured and selected in the component dialog.The page areas are rendered by four area scripts:
single
renders stage
area.list
renders main
and extras
areasfooter
renders footer
area.navigation
renders the navigation
area.The areas are rendered with containing div
elements in the generated HTML so that you can control their layout on the page with CSS. A sample CSS file is included in the module and you can view it in the Git respository.
The single
script renders a single component and is suitable for most areas where the type
property is set to single
in the area definition. The cms.component content
tag renders the component content. Compare the code to that of the list
script below.
FreeMarker
[#if component?exists] [@cms.component content=component /] [/#if]
JSP
<c:if test="${not empty component}"> <cms:component content="${component}"/> </c:if>
The list
script can be used for most areas where the type
property is set to list
in the area definition. The template loops through the components in the area, rendering the them one by one.
In FreeMarker the #List
directive lists the content map of components in the availabeComponents
node.
<div id="${def.parameters.divId!}"> [#list components as component ] [@cms.component content=component /] [/#list] </div><!-- end ${def.parameters.divId!} -->
In JSP the tag libraries are referenced specifically and forEach items
lists the content map of components in the availabeComponents
node.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="cms" uri="http://magnolia-cms.com/taglib/templating-components/cms"%> <div id="${def.parameters.divId}"> <c:forEach items="${components}" var="component"> <cms:component content="${component}" /> </c:forEach> </div>
The type
property of the footer
area is list
but the area uses its own script that wraps the content in <div id="footer">
and nests the components in div id="footer-element">
.
FreeMarker
<div id="footer"> [#list components as component ] <div id="footer-element"> [@cms.component content=component /] </div><!-- end ${def.parameters.divID!} --> [/#list] </div><!-- end footer -->
JSP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="cms" uri="http://magnolia-cms.com/taglib/templating-components/cms"%> <div id="footer"> <c:forEach items="${components}" var="component"> <div id="footer-element"> <cms:component content="${component}" /> </div> </c:forEach> </div>
The type
property of the navigation
area is noComponent
and the content is rendered entirely by the navigation
script. The include
directive includes two further scipts, searchForm
that renders the search box and macros/navigation
that renders the horizontal navigation. The cmsfn.root
method assigns the mgnl:page
nodes as children. For more cmsfn
methods see
TemplatingFunctions
.
FreeMarker
[#include "/samples/includes/searchForm.ftl" ] <div id="navigation"> [#include "/samples/macros/navigation.ftl"] [#assign rootPage = cmsfn.root(content, "mgnl:page")!] <ul>[@renderNavigation rootPage /]</ul> </div><!-- end "navigation" -->
JSP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="cmsfn" uri="http://magnolia-cms.com/taglib/templating-components/cmsfn"%> <%@include file="/templates/samples/includes/searchForm.jsp" %> <div id="navigation"> <c:set var="pageNode" scope="request" value="${cmsfn:root(content, 'mgnl:page')}" /> <c:set var="maxDepth" scope="request" value="2" /> <ul><jsp:include page="/templates/samples/macros/navigation.jsp" /></ul> </div><!-- end "navigation" -->
The navigation bar is rendered by the macros/navigation
script. The script uses three cmsfn
methods cmsfn.page
, cmsfn.link
and cmsfn.children
.
FreeMarker
[#macro renderNavigation pageNode maxDepth=2 ] [#assign currentPage = cmsfn.page(content)] [#assign isSelected = (pageNode.@path == currentPage.@path)!false] [#if isSelected ] <li class="selected"><span>${pageNode.title!pageNode.@name}</span></li> [#else] <li><a href="${cmsfn.link(pageNode)}"><span>${pageNode.title!pageNode.@name}</span></a></li> [/#if] [#if pageNode.@depth < maxDepth] [#list cmsfn.children(pageNode, "mgnl:page") as childPage] [@renderNavigation childPage /] [/#list] [/#if] [/#macro]
JSP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="cmsfn" uri="http://magnolia-cms.com/taglib/templating-components/cmsfn"%> <!-- Set Display Name --> <c:choose> <c:when test="${not empty pageNode.title}"> <c:set var="displayName" value="${pageNode.title}"/> </c:when> <c:otherwise> <c:set var="displayName" value="${pageNode['@name']}"/> </c:otherwise> </c:choose> <!-- Get the currentPage --> <c:set var="currentPage" value="${cmsfn:page(content)}"/> <!-- Check if the current page is selected --> <c:set var="selected" value="${pageNode['@path'] == currentPage['@path']}"/> <c:choose> <c:when test="${selected == true}"><li class="selected"><span>${displayName}</span></li></c:when> <c:otherwise><li><a href="${cmsfn:link(pageNode)}"><span>${displayName}</span></a></li></c:otherwise> </c:choose> <!-- Check maxDepth --> <c:if test="${pageNode['@depth'] < maxDepth}"> <c:forEach var="pageNodeSubElement" begin="0" items="${cmsfn:children(pageNode, 'mgnl:page')}"> <c:set var="pageNode" scope="request" value="${pageNodeSubElement}" /> <jsp:include page="/templates/samples/macros/navigation.jsp" /> </c:forEach> </c:if>
Component is the smallest block of content that end users can edit, delete and move as a unit. The Templating Samples module provides seven sample components:
howTo
renders a title, text, image and date.text
renders a title and text.linkList
renders a link list.searchResult
renders search results.externalLink
renders an external link.internalLink
renders an internal link.fieldsShowRoom
demonstrates various input controls.The component definitions are in Configuration /modules/samples/templates/components/ftl
and /jsp
.
As in the case of page and area definitions, a component definition makes the component available to the system and references the script that renders the component. Among others, the definition also typically references the dialog
used to edit the component and a model class for additional functionality, but these properties are not strictly necessary.
Here is the howTo
component on the ftl-sample-site/ftl-howTo
page. It is edited with the howTo
dialog.
Here's the component definition for ftl/HowTo
:
description
displays below the title
in the selector dialog when the component is added on a page.i18nBasename
finds the translations for the description
and title
properties. For more information see Language.title
displays in the selector dialog and in the component toolbar.modelClass
property references the
SampleComponentModel
. This model class does not add functionality to the this component directly, but can be extended to do so. It's relevance here is the search box that renders in the component that in turn relates to the searchResult
component that is discussed later.Here's the selector dialog in main
area on the main
template. Match the text in the dialog to that in the messages_en.properties
file.
The JCR Browser allows you to see the content as it is stored in the website
repository. You can access the browser at Tools > JCR Browser (Website). This is how the content of the howTo
component is stored. Note that the search box and 'HowTo' component link that render on the page are not stored here. This content is rendered entirely by the howTo
script.
The howTo
script renders the howTo
component. Below are examples from the script that show how to create common page content in a component script.
Plain text
Plain text content entered in a dialog is rendered using the content.<field name>
notation. The component title text is stored in the title
property of the content node, as defined in the howTo
dialog definition.
In FreeMarker a tag to check if a content node is empty is not necessary. The !
(exclamation mark) operator provides a default value.
<h3>${content.title!content.@name}</h4.
In JSP not empty
evaluates the body only if a container exists or the corresponding item exists and is not empty.
<h3><c:choose> <c:when test="${not empty content.title}">${content.title}</c:when> <c:otherwise>${content['@name']}</c:otherwise> </c:choose></h4.
FCKEditor text
The text
property of the content node contains HTML markup as editorial content is added using the FCKEditor (controlType=fckEdit
). The cmsfn
TemplatingFunctions
expose useful methods. Here the decode
method is used to escape the HTML.
FreeMarker
[#if content.text?has_content]<p>${cmsfn.decode(content).text}</p>[/#if]
JSP
<c:if test="${not empty content.text}"><p>${cmsfn:decode(content).text}</p></c:if>
Image
The image is rendered using the cmsfn.link
method. The script retrieves the image from the repository at /ftl-sample-site/ftl-howTo/main/0/image/<image name.ext>
.
FreeMarker
[#if content.image?has_content]Image: <img src="${cmsfn.link(content.image)}" /> ... [/#if]
JSP
<c:choose> <c:when test="${not empty content.image}">Image: <img src="${cmsfn:link(content.image)}" /> </c:when> ... </c:choose>
Date
The date is stored in the repository in the mm/dd/yy
format. The following code renders and reformats the date as EEEE, d. MMMM yyyy
.
FreeMarker
[#if content.date?has_content]The date you specified: ${content.date?string("EEEE, d. MMMM yyyy")} ... [/#if]
JSP
<c:choose> <c:when test="${not empty content.date}"> <fmt:formatDate value="${content.date.time}" var="parsedDate" pattern="EEEE, d. MMMM yyyy" /> The date you specified: <c:out value="${parsedDate}" /> </c:when> ... </c:choose>
Search box
The include
directive includes the includes/searchForm
script that renders the search box. This script is used multiple times in the samples. It is also included in the navigation script and searchResult script.
FreeMarker
[#include "/samples/includes/searchForm.ftl" ]
JSP
<%@include file="/templates/samples/includes/searchForm.jsp" %>
Link
The 'HowTo' component link opens the component script file. Click the link on the page in preview mode to view the script in the browser. The
DisplaySamplesSourcesServlet
is executed when the requested path contains the pattern /.sources/*
. For more see Servlets below. The script provides an example of creating links by appending a static path to the context path.
In FreeMarker you can get the current context path from the ctx
templating support object.
<li><a href="${ctx.contextPath}/.sources/components/howTo.ftl">'HowTo' component</a>/li>
JSP
<li><a href="${pageContext.request.contextPath}/.sources/components/howTo.jsp">'HowTo' component</a></li>
The linkList
component is an example of a component that contains nested components. It is also used to demonstrate the configuration of an autogenerated component. Note how efficiently elements can be used multiple times.
A number of link components are available on pages based on main
template:
linkList
components can be added in main
, extras
and footer
areas.linkList
component is rendered in extras
area.internalLink
and externalLink
components can be made available in any area, if preferred.Here's how the various definitions interrelate.
The internalLink
and externalLink
components are used in the samples as nested components in the linkList
component. The component definitions are in Configuration modules/samples/templates/components/ftl
and jsp
. Both components are rendered by the link
script. The externalLink
component does not require or use a model class and the internalLink
component uses the
InternalLinkModel
class that resolves internal links by identifier or path.
The linkList
component defintion is in Configuration modules/samples/templates/components/ftl/linkList
and jsp/linkList
. Nested components are configured in the areas/links/availableComponents
node. Note that this node has an almost identical structure to the corresponding areas/<area name>/availableComponents
node in the page template definitions. Here <area name>
is substituted with the links
node. This structure identifies that the nested components reside within a sub area (node type=mgnl:area
) and are rendered by the script using the cms.area name="links"
tag. See Link component scripts below.
An autogenerated linkList
component is configured in the main
page template in Configuration modules/samples/pages/ftl/main/areas/extras/autoGeneration
and /jsp/main/areas/extras/autoGeneration
. Here the links that are rendered on the page are defined in the definition:
autoGeneration/generatorClass
node allows for the nodes and properties within the configuration.nodeTypes
are defined as follows:autoGenerated
node is mgnl:component
.autoGenerated/links
node is mgnl:area
.auotGenerated/links/internal
and external
nodes are mgnl:component
.autoGenerated
node:title
property.linkList
component in the templateID
property that in turn references the linkList
script that renders the main component.autotGenerated/links/internal
and external
nodes:target
and title
properties of the nested components.templateId
property. These component definitions, samples:components/ftl/internalLink
and samples:components/ftl/externalLink
in turn reference the link
script that renders the links.Here is the autogenerated component on the ftl-sample-site/ftl-howTo
page. The component is created atuomatically on all pages based on the main
page template.
Two relatively simple scripts combine to render the numerous link components.
link script
The internalLink
and externalLink
components are rendered by the link
script.
The
InternalLinkModel
makes the internal link properties available to the script and the model.targetLink
notation is used. The title of the target page renders as the link title unless another title is specified.
External links are rendered using the standard content.<field name>
notation.
FreeMarker
[#assign target = model.target!] [#if target?has_content] <li><a href="${model.targetLink!}">${content.title!target.title!target.@name}</a></li> [#else] <li><a href="${content.target!}">${content.title!content.target!}</a></li> [/#if]
JSP
... <c:catch var="exception"><c:set var="target" scope="request" value="${model.target}" /></c:catch> <c:if test="${empty exception}"><li><a href="${model.targetLink}"> <c:choose> <c:when test="${not empty content.title}">${content.title}</c:when> <c:when test="${empty content.title and not empty target.title}">${target.title} </c:when> <c:otherwise>${target['@name']}</c:otherwise> </c:choose></a></li> </c:if> <c:if test="${not empty exception}"><li><a href="${content.target}"> <c:choose> <c:when test="${not empty content.title}">${content.title}</c:when> <c:otherwise>${content.target}</c:otherwise> </c:choose></a></li> </c:if>
linkList script
The linkList
script renders the linkList
component. The links of the nested components are in a nested <div class>
and are rendered using the cms.area name
tag because the component definition is structured to identify their node as an area.
FreeMarker
[#if content.title?has_content] <h3>${content.title}</h4. [/#if] <div class="linkList"> <ul>[@cms.area name="links" /]</ul> </div>
JSP
... <c:if test="${not empty content.title}"><h3>${content.title}</h3></c:if> <c:if test="${not empty content.text}"><h4>${content.text}</h4></c:if> <div class="linkList"> <ul><cms:area name="links" /></ul> </div>
The searchResult
component renders the results of a search term entered in the search box. A page containing this type of component would normally be excluded from the navigation as it only renders meaningful content when a search is executed. For demonstration purposes the component is included on the ftl-sample-site/ftl-searchResult
and jsp-sample-site/jsp-searchResult
pages.
Here's the FreeMarker component after requesting the results for the term "ftl".
The component definitions are in Configuration modules/samples/templates/components/ftl/searchResult
and jsp/searchResult
. The component uses the searchResult
script and
SampleComponentModel
model class.
SampleComponentModel model class contains the Jave logic that renders the search results. The class gets and sets the query string and lists the search results using the following SQL query.
String sql = "SELECT * from nt:base WHERE jcr:path like '"+rootPagePath+"/%' AND contains(*, '"+query+"') AND (jcr:primaryType = 'mgnl:page' OR jcr:primaryType = 'mgnl:area' OR jcr:primaryType = 'mgnl:component') order by jcr:path";
The searchResult
script renders the results from the attributes made available by the model. Note the use of the cmsfn.page
method made available by
TemplatingFunctions
and the use of the ctx
templating support object. Here's the part of the script that renders the results.
FreeMarker
... [#if model.searchResult?has_content] <div id="search-results" > <h3>Query Results for: "${model.query!"No query set yet"}"</h4. <ul> [#list model.searchResult as resultItem] [#assign foundOnPage = cmsfn.page(resultItem)] <li><a href="${ctx.contextPath}${foundOnPage.@path}">${foundOnPage.title!foundOnPage.@name}</a><span>(found in Node: ${resultItem.@path})</span></li> [/#list] </ul> </div><!-- end search-results --> [/#if] ...
JSP
... <c:if test="${not empty model.searchResult}"> <div id="search-results" ><h3>Query Results for: <c:choose><c:when test="${not empty model.query}">${model.query}</c:when> <c:otherwise>No query set yet</c:otherwise> </c:choose> </h3><ul><c:forEach items="${model.searchResult}" var="resultItem"><c:set var="foundOnPage" value="${cmsfn:page(resultItem)}"/><li> <a href="${pageContext.request.contextPath}${foundOnPage['@path']}"> <c:choose> <c:when test="${not empty foundOnPage.title}">${foundOnPage.title}</c:when> <c:otherwise>${foundOnPage['@name']}</c:otherwise> </c:choose> </a><span>(found in Node: ${resultItem['@path']})</span></li> </c:forEach></ul> </div><!-- end search-results --> ...
DisplaySamplesSourcesServlet is an example of a custom servlet. Its purpose is to display the source file of a template or component script.
The servlet is registered in the servlets filter chain at Samples > Servlets /server/filters/servlets/DisplaySamplesSourcesServlets
. It is executed when the requested path contains the pattern /.sources/*
.
The /.sources/*
pattern is present in the *Display Component's Sources * links that render in the howTo
and searchResults
components. When you click these links the servlet loads the source of the howTo
or searchResult
scripts.
For more information see Filters.
The module installs a number of sample users, groups and roles to show how the bootstrap mechanism work. Bootstrapping is the process of pre-loading the system with content and configuration. This is useful when you want to load some data as a baseline for testing.
The Templating Samples module JAR has two bootstrap folders:
mgnl-bootstrap
contains files that are always bootstrapped. In the Templating Samples module dialog, template, virtualURIMapping, config definitions and the base
user role are loaded from here.mgnl-bootstrap-samples
contains files that are bootstrapped only if magnolia.bootstrap.samples
property is set to true
. Web pages, users, groups and roles are loaded from here.You can find the sample users, groups and roles in the Security menu in AdminCentral.
In Configuration modules/samples/config
there are a number of sample configurations. These are provided as examples and are not used by the module as such.