In this beginner tutorial you create a simple template in Magnolia. You learn how to get content from the repository and display it on a page.

Installing Magnolia

Get Java

Magnolia needs a Java Runtime Environment (JRE). Type java -version in a terminal or command prompt. If the system reports a version number, Java is installed on your computer.
$ java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)

If you don't have Java, install it:

Java is not pre-installed on Mac OS X 10.7 and later. Download the latest Java from Oracle.

On Windows you need a Java SE Development Kit (JDK). The Java Runtime Environment (JRE) is not enough because the Tomcat application server does not recognize it.

What is the difference?

  • JRE is for users who run Java programs on their computer.
  • JDK is for developers who write Java-based applications.

Download and install JDK. By default JDK is installed in C:\Program Files\Java\jdk1.8.0_xx\. You can choose another location.

Check JAVA_HOME environment variable

  1. Open the command prompt.
  2. Type set and press ENTER.
  3. Find JAVA_HOME in the command output and verify that the path points to your JRE installation directory, for example C:\Program Files\Java\jdk1.8.0_xx.
  4. If JAVA_HOME is missing or it points to the wrong directory, see Set JAVA_HOME environment variable below.

Set JAVA_HOME environment variable

  1. Right-click My Computer and select Properties.
  2. Go to the Advanced tab. 
    (In Windows 7+, right-click Computer and select Advanced System Settings, then Environment variables.)
  3. If the JAVA_HOME environment variable does not exist in User variables or System variables, create it:
    • User variables apply to the currently signed-in user only. Create JAVA_HOME here if you want it to apply only to the currently logged in user. These variables take precedence over system variables.
    • System variables apply to all users. Create JAVA_HOME here if you want it to apply to all users. You must be an administrator to modify a system environment variable. 
  4. Set the value of JAVA_HOME to the path of your JDK installation directory, for example C:\Program Files\Java\jdk1.8.0_xx.
  5. Optional step: Add the Magnolia bin directory to the PATH variable, for example C:\Program Files\magnolia\apache-tomcat-x.y\bin. Setting the PATH allows you to issue the Magnolia start and stop commands from anywhere without navigating to the installation directory first. Separate the path from existing paths with a semicolon ( ; ). If you do this, you also need to add CATALINA_HOME to environment variables. Set the value of CATALINA_HOME to the Tomcat installation directory, for example C:\Program Files\magnolia\apache-tomcat-x.y
  6. Click OK.
  7. Go back to Check JAVA_HOME environment variable above and test that the variable is found and has the correct value. You need to open a new command prompt since environment variables are session specific.

Alternatively you can set JAVA_HOME with a batch file. Add this line to /apache-tomcat/bin/magnolia_control.bat:

set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_xx

The set command creates the JAVA_HOME environment variable and sets its value to the JDK directory. The command is executed when Magnolia starts.

Download the latest Java from Oracle. The installation directory varies from one Linux system to another. For example, on Ubuntu Linux 10 the OpenJDK Runtime Environment is installed in /usr/lib/jvm/java-8-openjdk/jre by default.

Download the latest Java from Oracle. You can install it in any directory such as /usr/java.

Get Magnolia

Download a Magnolia bundle or use the Magnolia CLI.

Download Magnolia

*

Error rendering macro 'artifact-resource-macro'

com.sun.jersey.api.client.ClientHandlerException: java.net.NoRouteToHostException: No route to host (Host unreachable)

Extract the zip to your computer.

magnolia-x.y/
├── add-ons/
└── apache-tomcat-x.y/
    ├── bin/
    ├── conf/
    ├── lib/
    ├── logs/
    ├── temp/
    └── webapps/
        ├── ROOT/
        ├── magnoliaAuthor/
        └── magnoliaPublic/

Where to extract:

Extract the zip to  /Applications  or another directory on your computer.

Extract the zip to C:\Users\<username>\magnolia or another directory on your computer.

If you are installing Magnolia for personal use extract the zip to /home/<your account> or equivalent directory. If you are installing onto a production server extract the zip to /usr/local or /opt . A normal user account may not have permissions to extract files into a target directory such as /opt . If this is the case extract the zip in the folder where you downloaded it, open a terminal window, and move the extracted folder using sudo mv magnolia-x.y. The sudo command will execute the mv (move) command as superuser, prompting you for a password.

If you are installing Magnolia for personal use extract the zip to /export/home/<your account> or equivalent directory. If you are installing onto a production server extract the zip to /usr/local or /opt . A normal user account may not have permissions to extract files into a target directory such as /opt . If this is the case extract the zip in the folder where you downloaded it, open a terminal window, and move the extracted folder using sudo mv magnolia-x.y. The sudo command will execute the mv (move) command as superuser, prompting you for a password.

Magnolia Community Edition software is distributed free-of-charge and without any warranty under the terms of the GNU General Public License (version 3), a license that permits you to redistribute and modify the software under certain terms and conditions. It is important that you read the license to understand your rights and obligations.

Magnolia CLI

If you are familiar with Magnolia's CLI use the jumpstart command to download, unpack and pre-configure the Magnolia Community Demo bundle. The bundle includes the Travel Demo and a Tomcat server. 

Start Magnolia

Open a shell and go to the bin directory of your Magnolia Tomcat bundle. If you installed the bundle from a ZIP file, cd to magnolia-x.y/apache-tomcat-x.y/bin. If you installed the Magnolia bundle with Magnolia CLI jumpstart, cd to apache-tomcat/bin.

Execute the start command:

./magnolia_control.sh start

Note: If you get an error due to a low "max open files" limit, try executing the command with the --ignore-open-files-limit option:

./magnolia_control.sh start --ignore-open-files-limit

Detailed instructions:

  1. Open a terminal window in Applications > Utilities > Terminal.
  2. Go to the Magnolia installation directory

    cd /Applications/magnolia-x.y/apache-tomcat/bin
  3. Start Magnolia.

    ./magnolia_control.sh start && tail -f ../logs/catalina.out

The first part of the startup command ./magnolia_control.sh start launches Magnolia. The second part && tail -f ../logs/catalina.out displays log messages written to /apache-tomcat/logs/catalina.out log file. This makes it easier to troubleshoot startup errors.

Magnolia reports startup information. If startup fails, look for the reason in the report. In a successful startup the last line reads: 
INFO: Server startup in 12345 ms.

To stop Magnolia, type CTRL + C, then ./magnolia_control.sh stop and press RETURN.

  1. Open a command prompt and go to the Magnolia installation directory. 
    (To do this, type cd C:\Users\<username>\magnolia-x.y\apache-tomcat\bin)
  2. Type magnolia_control.bat start and press ENTER.
    Magnolia reports startup information in a new Tomcat window. If startup fails, look for the reason in the report. In a successful startup the last line reads: INFO: Server startup in 12345 ms

To stop Magnolia, type CTRL + C , then ./magnolia_control.bat stop and press ENTER.

  1. Open a terminal window.
  2. Go to the Magnolia installation directory: 
    cd /home/<your account>/magnolia-x.y/apache-tomcat/bin 
    Your path may be different.
  3. Start Magnolia: 
    ./magnolia_control.sh start && tail -f ../logs/catalina.out

The first part of the startup command ./magnolia_control.sh start launches Magnolia. The second part && tail -f ../logs/catalina.out displays log messages written to /apache-tomcat/logs/catalina.out log file. This makes it easier to troubleshoot startup errors.

Magnolia reports startup information. If startup fails, look for the reason in the report. In a successful startup the last line reads: 
INFO: Server startup in 12345 ms

To stop Magnolia, type CTRL + C , then ./magnolia_control.sh stop and press ENTER.

  1. Open a terminal window.
  2. Go to the Magnolia installation directory: 
    cd /home/userAccount/magnolia-x.y/apache-tomcat/bin 
    Your path may be different.
  3. Start Magnolia: 
    ./magnolia_control.sh start && tail -f ../logs/catalina.out

The first part of the startup command ./magnolia_control.sh start launches Magnolia. The second part && tail -f ../logs/catalina.out displays log messages written to /apache-tomcat/logs/catalina.out log file. This makes it easier to troubleshoot startup errors.

Magnolia reports startup information. If startup fails, look for the reason in the report. In a successful startup the last line reads: 
INFO: Server startup in 12345 ms

To stop Magnolia, type CTRL + C , then ./magnolia_control.sh stop and press ENTER.

Install Magnolia

To install Magnolia:
  1. Open a browser and go to http://localhost:8080
  2. Click Run the Web update on the author instance, then Start install.
  3. Click Run the Web update on the public instance, then Start install.

Magnolia installs its modules. When the installation is complete on the author and public instances, click Start up Magnolia on both.

Log in

Go to http://localhost:8080/magnoliaAuthor/.magnolia/admincentral and sign in as:
  • Username: superuser
  • Password: superuser

The app launcher is displayed.

(info) superuser is a system administrator account that has permissions to do everything. It is useful for testing.

Troubleshooting

Having problems? See Known issues.

Creating a template module

Create a module for your templates.

Option 1: Build it yourself

  1. Go to the folder where you extracted Magnolia.
  2. Create the structure hello-magnolia (including subfolders) under apache-tomcat/webapps/magnoliaAuthor:

    webapps/
    └── magnoliaAuthor/
        └── hello-magnolia/
            ├── dialogs/
            ├── webresources/
            └── templates/

This is a typical Magnolia module structure where hello-magnolia is the name of your module. 

When creating a name for a module, do not use spaces, accented characters such as é, à, ç, ä, öü or special characters such as slashes /\ and so on. The name must match the regular expression [a-zA-Z0-9-_].


Magnolia scans directories inside the web application, in this case inside magnoliaAuthor, and registers your module automatically. It detects new and modified templates, dialogs and (web)resources.

Option 2: Download the complete example

*

Error rendering macro 'artifact-guess-resource-macro'

com.sun.jersey.api.client.ClientHandlerException: java.net.NoRouteToHostException: No route to host (Host unreachable)


Download the zip and extract it to apache-tomcat/webapps/magnoliaAuthor/hello-magnolia .

(warning) Remove any version number from the extracted folder name. It should be just hello-magnolia.

The complete example does not include the intermediate build stages as below, only the final module structure. You can use the template on a page right away.

Creating a page template

The first template we create is a page template.

Beware invalid characters

Highlight the code snippets you copy. Double-clicking may bring invalid characters.

Start with an HTML document

It is common to start with a static HTML document. You can view the static HTML document directly in your browser. It does not need to be processed by Magnolia. 

  1. Copy the HTML code below and save it to a new file hello-magnolia/templates/pages/hello.html

    hello-magnolia/templates/pages/hello.html
    <!DOCTYPE html>
    <html>
       <head>
          <title>Hello :-)</title>
          <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Raleway:200" type="text/css">
          <link rel="stylesheet" href="../../webresources/css/style.css">
       </head>
       <body>
          <div class="container">
             <header>
                <h1>Hello Magnolia :-)</h1>
                <p>We will use this page as a starting page to create our first page template.</p>
             </header>
          </div>
       </body>
    </html>
  2. Copy the CSS below and save it to a new file hello-magnolia/webresources/css/style.css. We reference this stylesheet in the HTML page and the template script (later on).

    hello-magnolia/webresources/css/style.css
    body {
       padding: 20px;
       font-family: Arial, Helvetica, Tahoma, Verdana, sans-serif;
       background-color: #1e5799;
       background-attachment: fixed;
    }
    .container {
       width: 100%;
       max-width: 960px;
       margin: 0px auto;
       padding: 20px;
       box-sizing: border-box;
       background-color: white;
    }
    header {
       padding: 20px;
       background-color: #f6f6f6;
       margin-bottom: 40px;
    }
    header p {
       font-style: oblique;
    }
    h1 {
       font-size: 4em;
       font-family: "Raleway", Arial, Helvetica, Tahoma, Verdana, sans-serif;
       font-weight: normal;
    }
    blockquote {
       margin-bottom:40px;
    }
    blockquote cite {
       padding-left:20px;
       font-size: 1.3em;
       color: #333;
    }
    blockquote p {
       border: 5px solid #0066aa;
       border-radius: 12px;
       padding: 25px 15px;
       position: relative;
       background-color: #fff;
       margin-bottom: 30px;
    }
    /** Add the bottom triangle for the quote bubble using CSS **/
    blockquote p:before, blockquote p:after {
       position: absolute;
       display: block;
       border-style: solid;
       content: "";
       height: 0;
       width :0;
       box-sizing: border-box;
    }
    blockquote p:before {
       left: 20px;
       bottom: -30px;
       border-color: transparent #0066aa transparent transparent;
       border-width: 0 30px 30px 0;
    }
    blockquote p:after {
       left: 29px;
       bottom: -15px;
       border-color: transparent #fff transparent transparent;
       border-width: 0 15px 15px 0;
    }

Page template definition

Every Magnolia template needs a definition and a script. A template definition gives the template a name and makes it available to the system. It also tells the system which script renders the content. Here we use YAML to create template definition.

  1. Copy the template definition code below.

    hello-magnolia/templates/pages/hello.yaml
    templateScript: /hello-magnolia/templates/pages/hello.ftl
    renderType: freemarker
    visible: true
    title: Hello
  2. Save it to a new file hello-magnolia/templates/pages/hello.yaml.

    hello-magnolia/
    ├── dialogs/
    ├── webresources/
    │   └── css/
    │       └── style.css
    └── templates/
        └── pages/
            ├── hello.html
            └── hello.yaml
If you add the YAML file by moving a whole directory into the webapp, you need to do one of the following for the definition to be registered: a. make a modification in your YAML file, or b. restart your instance.

Page template script

A template script contains the rendering instructions. A script can be completely static but it usually includes editable content fragments or other dynamically assigned values provided by Templating functions (for instance cmsfn to fetch content) or Rendering context objects.

  1. Rename the static HTML document (hello.html) to hello.ftl. The extension .ftl turns it into a FreeMarker script.
  2. Line 6: Change the CSS reference to use ${ctx.contextPath}. This template directive ensures that the path is correct on both author and public instance.
  3. Line 12: Render the template name with ${def.name}. (def is a context attribute, see Rendering context objects).
hello-magnolia/templates/pages/hello.ftl
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Magnolia :-)</title>
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Raleway:200" type="text/css">
    <link rel="stylesheet" href="${ctx.contextPath}/.resources/hello-magnolia/webresources/css/style.css">
  </head>
  <body>
    <div class="container">
      <header>
        <h1>Hello Magnolia :-)</h1>
        <p>This page has been created with the template named ${def.name}</p>
      </header>
    </div>
  </body>
</html>

Your file system should now look like this:

hello-magnolia/
├── dialogs/
├── webresources/
│   └── css/
│       └── style.css
└── templates/
    └── pages/
        ├── hello.ftl
        └── hello.yaml
  1. fake
  2. fakUse the template on a pag

Make the template available (Magnolia 5.4.6 and earlier)

As of version 5.4.7 of Magnolia, a page template such as this one will be instantly available to the editor. To be able to use the template in a page on pre-5.4.7 version of Magnolia, you must add the template to the list of available templates in the site

  1. Go to Magnolia and click WebDev > Site at the bottom of the page. 
  2. In the Site definitions tab, select templates/availability/templates.
  3. Add a content node called hello.
  4. Add a property called id with the value hello-magnolia:pages/hello to the node.

Use the template in a page

  1. Go to Magnolia and open the Pages app.
  2. Create a new page. Select the Hello template you just created.
  3. Open the page for editing.

Congratulations! You created your first Magnolia template. You turned a static HTML document into a processed FreeMarker template.

Making content editable

Magnolia 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 CMS.

Create a dialog definition

A dialog definition defines the editable properties of the template.

Copy the dialog definition below and save it to a new file hello-magnolia/dialogs/pages/hello.yaml.

hello-magnolia/dialogs/pages/hello.yaml
form:
  tabs:
    - name: tabText
      label: Texts
      fields:
        - name: title
          class: info.magnolia.ui.form.field.definition.TextFieldDefinition
          label: Title
        - name: introText
          class: info.magnolia.ui.form.field.definition.TextFieldDefinition
          label: Introduction text
actions:
  commit:
    class: info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition
  cancel:
    class: info.magnolia.ui.admincentral.dialog.action.CancelDialogActionDefinition

The dialog has two fields:

  • title: Edits the page title using a simple text field. We will render the content in the <title> and <h1> elements on the page.
  • introText: Edits an introduction paragraph. We will render the content in the first <p> element on the page.

Reference the dialog from the template

  1. Edit hello-magnolia/templates/pages/hello.yaml
  2. Set the dialog property on line 5. The value is an id to the dialog definition. The id follows the pattern <module name>:<relative path within the dialogs folder>.
hello-magnolia/templates/pages/hello.yaml
templateScript: /hello-magnolia/templates/pages/hello.ftl
renderType: freemarker
visible: true
title: Hello Magnolia
dialog: hello-magnolia:pages/hello

Add content references in the template script

Edit the template script to render the content entered in the dialog. The content variable represents the root node of the content element, in this case the page.

hello-magnolia/templates/pages/hello.ftl
[#assign title = content.title!"Hello Magnolia :-)"]

<!DOCTYPE html>
<html>
  <head>
    <title>${title}</title>
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Raleway:200" type="text/css">
    <link rel="stylesheet" href="${ctx.contextPath}/.resources/hello-magnolia/webresources/css/style.css">
	[@cms.page /]
  </head>
  <body>

    <div class="container">
      <header>
        <h1>${title}</h1>
        [#if content.introText?has_content]<p>${content.introText}</p>[/#if]
      </header>
    </div>

  </body>
</html>

Changes:

  • Line 1: content.title retrieves the title of the page from the CMS and assigns it to a FreeMarker variable title. The variable allows us to reuse the content in the <title> and <h1> elements. The FreeMarker expression also provides a default value "Hello Magnolia" we can fall back on if the page has no title.
  • Line 9[@cms.page /] adds toolbars and makes the page properties dialog available.
  • Line 16: ${content.introText} renders the introduction paragraph. We wrap it in an if directive which checks that the content exists in the CMS. 

Your file system should now look like this:

hello-magnolia/
├── dialogs/
│   └── pages/
│       └── hello.yaml
├── webresources/
│   └── css/
│       └── style.css
└── templates/
    └── pages/
        ├── hello.ftl
        └── hello.yaml

Edit the page content

To use the template on a page:

  1. In Magnolia, refresh the page.

  2. Click Edit page properties.

  3. Edit the page title and introduction paragraph.

  4. Save.

You now have an editable page. Authors can enter content in the CMS and render it on the page.

Creating areas and components

Areas and components help to modularize a project and structure pages. Once defined, you can reuse areas and components in many page templates.

Let's create an area with one component to add quotations. At the end it should look like this:


What is an area

Typically you organize pages into smaller elements called areas. Areas allow you to control the page layout and restrict what content editors can place inside the area. Areas are rendered as div elements in the HTML so you can style them with CSS. Areas also provide repeatability. An area template typically loops through the components inside it, rendering them one by one.

What is a component  

A component is the smallest block of content that editors can edit, delete and move as a single unit. Think of a component as content that "belongs together". When you look at a typical Magnolia page, you can identify components easily with that rule of thumb. At its simplest, a component is just a heading and some text that go together.

Define an area

Areas are defined in the page template definition. You don't need to create a separate area definition file.

Edit the hello-magnolia/templates/pages/hello.yaml template definition and add the main area:

hello-magnolia/templates/pages/hello.yaml
templateScript: /hello-magnolia/templates/pages/hello.ftl
renderType: freemarker
visible: true
title: Hello template
dialog: hello-magnolia:pages/hello
areas:
  main:
    renderType: freemarker
    availableComponents:
      quotation:
        id: hello-magnolia:components/quotation

You don't need to create an area template script. Magnolia uses a default script that looks like this:

[#list components as component ]
   [@cms.component content=component /]
[/#list]

Include the area within the page template script

The FreeMarker expression [@cms.area name="main"/] on line 18 includes the area.

hello-magnolia/templates/pages/hello.ftl
[#assign title = content.title!"Hello Magnolia :-)"]

<!DOCTYPE html>
<html>
   <head>
      <title>${title}</title>
      <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Raleway:200" type="text/css">
      <link rel="stylesheet" href="${ctx.contextPath}/.resources/hello-magnolia/webresources/css/style.css">
      [@cms.page /]
   </head>
   <body>
      <div class="container">
         <header>
            <h1>${title}</h1>
            [#if content.introText?has_content]<p>${content.introText}</p>[/#if]
         </header>
         <div class="main">
            [@cms.area name="main"/]
         </div>
      </div>
   </body>
</html>

Create a component

  1. Component template definition: Create the file hello-magnolia/templates/components/quotation.yaml.
  2. Template script: Create the file hello-magnolia/templates/components/quotation.ftl.
  3. Dialog: Create the file  hello-magnolia/dialogs/components/quotation.yaml.

Component template definition

hello-magnolia/templates/components/quotation.yaml
templateScript: /hello-magnolia/templates/components/quotation.ftl
renderType: freemarker
dialog: hello-magnolia:components/quotation
title: Quotation

Component template script

When rendering content you should test whether it exists. At least the quotation must exist, otherwise the whole component will not be rendered.

hello-magnolia/templates/components/quotation.ftl
[#if content.quotation?has_content]
<blockquote>
    ${cmsfn.decode(content).quotation}
    [#if content.citedPerson?has_content]<cite>${content.citedPerson}</cite>[/#if]
</blockquote>
[/#if]

Component dialog

We use a rich text editor to enter the quotation on line 7 in the dialog definition below. It stores text in a way that every paragraph is surrounded with a <p> tag. That's also the reason to decode the content using the  cmsfn.decode  function, line 3 above.

hello-magnolia/dialogs/components/quotation.yaml
form:
  tabs:
    - name: tabTexts
      label: Quotation
      fields:
        - name: quotation
          class: info.magnolia.ui.form.field.definition.RichTextFieldDefinition
          label: Quotation
        - name: citedPerson
          class: info.magnolia.ui.form.field.definition.TextFieldDefinition
          label: Cited person
actions:
  commit:
    class: info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition
  cancel:
    class: info.magnolia.ui.admincentral.dialog.action.CancelDialogActionDefinition

Final module structure

Your file system should now look like this:

├── dialogs/
│   ├── components/
│   │   └── quotation.yaml
│   └── pages/
│       └── hello.yaml
├── webresources/
│   └── css/
│       └── style.css
└── templates/
    ├── components/
    │   ├── quotation.ftl
    │   └── quotation.yaml
    └── pages/
        ├── hello.ftl
        └── hello.yaml

Congratulations! (big grin)

You now know the basics of Magnolia content templating. Using these techniques you can build websites where non-technical authors can manage content using dialogs.

Next steps:

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