Magnolia 5.3 reached end of life on June 30, 2017. This branch is no longer supported, see End-of-life policy.
Let's start the tutorial with the highest level template which is page. You need three things to create a page template: a script to render the content, a page definition to make the template available to the system, and a dialog that allows editors to enter content.
Page 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 elements such as headings and images.
In this exercise you will save the script file in the web application's directory on the file system. This is not the only possible place. Freemarker template scripts can also be loaded from the templates
repository or from inside your module's .jar file. JSP templates can only be loaded from the file system since they require pre-compiling by the server before they can be rendered.
To create a page script:
/<CATALINA_HOME>/webapps/<contextPath>/templates
, typically this is /apache-tomcat/webapps/magnoliaAuthor/templates
.templates
folder if it does not exist.templates
, create a new text file helloWorld.ftl
.Freemarker:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Page Title</title> </head> <body> Hello World! </body> </html>
JSP:
<html> <head> <title>Page Title</title> </head> <body> Hello World! </body> </html>
As you can see, declaring the contentType
is unnecessary in JSP. The script is served from the /templates
folder within the webapp
, not from /docroot
, so the content type is established by the servlet. If you use JSP, set the renderType
property in the template definition to jsp
and templateScript
to /templates/helloWorld.jsp
.
The script is very simple and merely displays the text "Hello World!" on the page. Your file system should look like this.
A page definition assigns the page template a name and makes it available to the system. The name is used to reference the template. The page definition also tells the system which dialog is used to edit page properties and which script is used to render the content.
In this tutorial you will create place the page definition in the Templating module. You can find it in Configuration > /modules/templating
. This is the same module that provides the basic templating functionality.
Node name | Value |
---|---|
modules | |
templating | |
templates | |
pages | |
helloWorld | |
renderType | freemarker |
templateScript | /templates/helloWorld.ftl |
title | Hello World |
visible | true |
Properties:
renderType
defines which renderer is used to render the template. Options are freemarker
, jsp
and stk
. Set value to freemarker
. See About scripting languages.templateScript
is a path to the corresponding page script. The script renders the content. Set value to /templates/helloWorld.ftl
.title
is the title of the template. Editors see it in the Template dropdown when they assign the page template to an actual page on the site. Set value to Hello World
.visible
makes the page template available to editors. Set value to true
.Your definitions do not have to reside in the Templating module. At an advanced level, the best practice is to create your own complete module. To place the configuration into your own module you will need to have a module descriptor that registers the module. In addition you will need a task that bootstraps configurations such as page definitions. This enables you to customize templates independent of other modules.
Freemarker is the most common templating language used with Magnolia. JSP is also popular. You can use both languages on the same site; Freemarker for some pages and JSP for others. You can even use JSP for a page and Freemarker for areas on the page (or vice versa) as long as you define a renderType
for the area separately. Otherwise the area will inherit the page's renderType
.
FreeMarker templates can be loaded from the webapp's classpath, the repository or the file system. JSP templates can be loaded only from the file system since they require pre-compiling by the server before they can be rendered. In this tutorial you find code examples in FreeMarker and JSP. Choose your code of preference.
It does not really matter where you put your template scripts as long as they are within the webapps
folder of your Magnolia instance. The path to the script file is in the template definition. This is how the system finds the script. By default, the templates
folder is in /<CATALINA_HOME>/webapps/<contextPath>/templates
. It is generally a good idea to organize your templates into folders.
To keep things simple, this tutorial does not deal with Cascading Style Sheets (CSS). Your template script can reference a CSS file if you wish. For example, to use the samples.css
file contained in the Templating Samples module from the file system, add the following line in the <head>
section of the script.
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/docroot/samples/samples.css"/>
CSS files can also be loaded from the repository. You can find samples in STK > Resources.
Now the page template is defined so the system can find it and editors can assign it to pages. You also have a page script so the system knows how to render content.
To assign the page template to a page:
hello
.The result may seem a little disappointing but this is a very basic page!
Now that basic infrastructure is in place, you can start rendering content from the repository and creating dialogs for content entry.
To learn how to deal with dynamic content, assign the page a title. The title is stored in a property named title
in the repository. You can render it in the browser title bar and on the page.
To assign a title to the page:
Page title is different from template title. Page title ("Hello Magnolia World") is displayed to visitors on the page. Template title ("Hello World") is an internal title of the page template which you defined in the page definition earlier; it is displayed to editors in the Template dropdown in AdminCentral.
The page title is stored with page content and other page properties in the website
repository. You can examine these properties with the JCR Browser . Go to Tools > JCR. Pages, and nodes in general, can have an arbitrary number of properties.
Templating support objects are available to your script implicitly. This means that you can access content and properties stored in the repository using tags in the script. The content
object represents the current node, in this case the Hello page. Page title is available through this object using the dot notation: content.title
. Properties are exposed as a map like cms:setNode
To display the page title on the page, edit the script.
FreeMarker:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>${content.title!}</title> </head> <body> <h1>${content.title!}</h1> </body> </html>
JSP:
<html> <head> <title>${content.title}</title> </head> <body> <h1>${content.title}</h1> </body> </html>
Now, refresh the Hello page. The page title "Hello Magnolia World" is displayed in the window title and in an h1 element on the page.
As you create new pages based on the Hello World template, the window title and h1 element will change dynamically to display each page's unique title.
The exclamation mark after content.title
is the Freemarker default value operator. On the right hand side of the exclamation mark you specify a default value that is substituted if the title
property does not have an actual value. This prevents the script from erroring if it encounters a null value. If you leave the substitute out, the exclamation mark alone sets the value to an empty string.
Each page element has a toolbar that editors use to edit the element's content and move it on the page. The page itself also has a toolbar that allows editors to edit page specific properties such as the title without leaving the page.
Toolbars are added to editable elements automatically. The Tag libraries is a collection of tags that render common elements such as toolbars. Use the cms.init
tag to initialize the tag library.
cms.init
tag in the head element.FreeMarker:
<html> <head> [@cms.init /] <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>${content.title!}</title> </head> <body> <h1>${content.title!}</h1> <p>My template content</p> </body> </html>
JSP:
<%@ taglib prefix="cms" uri="http://magnolia-cms.com/taglib/templating-components/cms" %> <html> <head> <cms:init/> <title>${content.title}</title> </head> <body> <h1>${content.title}</h1> <p>My template content</p> </body> </html>
Refresh the page.
The action bar now has page actions:
The authoring system uses dialogs to edit content. A dialog is an HTML form with input fields. Editors type content into the fields and the dialog saves it in the repository. It is an agile mechanism in the sense that you can create your own dialogs or customize the standard dialogs that ship with the system.
Like template definitions, dialogs are defined with configuration. The page properties dialog is a very common dialog. You will find it on every STK page for example. It allows editors to edit the page title, navigation title and page metadata without leaving the page.
You could reuse an existing page properties dialog. However, the dialog used in STK pages is not appropriate for the Hello World page because our page will not have navigation or metadata, to keep things simple. STK dialogs are too complex for this example. Create a dialog that allows you to edit the page title and enter some page content instead.
Dialogs consist of tabs, which again consist of fields. Each dialog needs to have at least one tab. Configure also two actions: save and cancel.
Node name | Value |
---|---|
modules | |
templating | |
dialogs | |
pageProperties | |
actions | |
cancel | |
class | info.magnolia.ui.admincentral.dialog.action.CancelDialogActionDefinition |
label | Cancel |
save | |
class | info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition |
label | Save changes |
form | |
tabs | |
text | |
fields | |
title | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
label | Page title |
text | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
label | Page text |
rows | 5 |
label | Page properties |
Reference the page properties dialog from the page definition so that the system knows which dialog to open when the Properties button is clicked.
/modules/templating/templates/pages/helloWorld
.dialog
and set its value to templating:pageProperties
.Node name | Value |
---|---|
modules | |
templating | |
templates | |
pages | |
helloWorld | |
dialog | templating:pageProperties |
renderType | freemarker |
templateScript | /templates/helloWorld.ftl |
title | Hello World |
visible | true |
The value of the dialog
node has two parts. The first part before the colon (:) is the name of the module folder where the dialog definition resides. The second part is a relative path.
<module name>:<relative path to dialog>
In this case the dialog is defined in the Templating module so the first part is templating
. The relative path always starts from inside the dialogs
folder. Since the pageProperties
dialog definition is right below the dialogs
folder, the name of the node is enough.
templating:pageProperties
Refresh the Hello page and click Properties. The dialog is displayed.
The Page title box already has a value "Hello Magnolia World". The system read the value from the title
property in the repository. This is the same value you entered in AdminCentral earlier. Controls store their values in properties named after the control: a control named title
stores values in a title
property, a control named text
stores values in a text
property and so on.
For a complete list of properties available in dialog and control definitions, see Dialog definitions and Common field properties.
Type some text in the Page text box and save the dialog. The text is stored in a new text
property under the page. You can verify this with the JCR Browser.
To render the text you typed:
<p>
and </p>
in the body.text
property from the content object using ${content.text!
}.Freemarker:
<html> <head> [@cms.init /] <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>${content.title!}</title> </head> <body> <h1>${content.title!}</h1> <p>${content.text!}</p> </body> </html>
JSP:
<%@ taglib prefix="cms" uri="http://magnolia-cms.com/taglib/templating-components/cms" %> <html> <head> <cms:init/> <title>${content.title}!</title> </head> <body> <h1>${content.title}</h1> <p>${content.text}</p> </body> </html>
The text you typed in the Page text box is now displayed on the page.
Next: Creating an area