This article covers a Hippo CMS version 11. There's an updated version available that covers our most recent release.

Hello World

A Quick Hands-On Introduction to Hippo's Fundamental Concepts

This short tutorial gives a quick look into the fundamentals of Hippo CMS and Hippo's delivery tier (HST), by guiding you through a 'Hello World style' example that highlights how the Model-View-Controller pattern is implemented to render pages in a Hippo-based website.

This tutorial is specifically aimed at Java developers who want to get a quick hands-on start with Hippo development. However, anyone with some basic Java knowledge and access to an IDE should be able to follow.

What about the Essentials Setup Application and Feature Library?

You might have seen that Hippo provides an Essentials setup application including a feature library that contains many out-of-the-box features, allowing you to quickly kickstart your project. This tutorial 'bypasses' Essentials and lets you implement a simple Hello World page from scratch, so you can actually see how it works under the hood.

To learn how to set up your project using Essentials and build a website using out-of-the-box features, follow the Get Started and Build a Website tutorials.

A Very Simple Hello World

First, you will build a simple static Hello World page that is served by Hippo. You will learn how to add a Freemarker template to the project and how to configure Hippo to use it.

Step 1: Create a New Project

Start by making sure your development environment meets the prerequisites.

Then generate your Hippo project using the Maven archetype as explained in Create the Project.

After the project is generated, open it in the IDE of your choice (see our pages about Eclipse and Intellij).

Step 2: Build the Project

Compile and run the project by using the following Maven commands:

mvn verify
mvn –Pcargo.run

This creates WAR files and immediately runs the project using Cargo. If you are doing this for the first time, it might take some time as Maven will download all project dependencies from a remote repository server.

Step 3: Add a Freemarker Template

In your IDE, browse to the bootstrap/webfiles/src/main/resources/site folder and create a folder called freemarker and inside it a folder called  home, and add a file called  home.ftl to it. Paste the following code into the file:

bootstrap/webfiles/src/main/resources/site/freemarker/home/home.ftl

<html>
    <head>        
    </head>
    <body>
        <h1>Hello World </h1>
    </body>        
</html>
By placing the Freemarker template in the web files module, it will be automatically reloaded any time you modify it, speeding up development.

Step 4: Introducing the Console

Browse to the Hippo Console at http://localhost:8080/cms/console and log in using the default admin / admin credentials.

The Console provides direct access to Hippo's content repository. All data, including content as well as configuration, is stored in this repository as JCR nodes. The Console displays these nodes in a tree structure. Clicking on a node allows you to view and change the properties of that node. Nodes have a node type which defines its properties and child nodes, in a similar way to how an XML schema defines elements and attributes.

In this tutorial you will be working in the delivery tier configuration section, in the hst:hst/hst:configurations node, that holds the configuration for all websites.

Step 5: Configure the Template

Let's get started by configuring Hippo to use the template you just created. Browse to the node at /hst:hst/hst:configurations/myhippoproject and you will see something similar to this:

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/console-myhippoproject.png

The node contains several child nodes with configuration, but for this specific step select the hst:templates node. Add a new child node, by either clicking on 'Add' in the top menu or by right-clicking the node then selecting 'Add node'. Name it homepage. The node type should be set to hst:template by default. Click OK to create. After this, click on the 'Add Property' button above the properties. This will open a dialog:

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/add-property.png

Add a property named hst:renderpath. Set the value to the location of the Freemarker file you created:  webfile:/freemarker/home/home.ftl. Click OK to close the dialog.

/hst:hst/hst:configurations/myhippoproject/hst:templates
    + homepage [hst:template]
        - hst:renderpath = webfile:/freemarker/home/home.ftl

Step 6: Add a Page (Component)

Hippo's delivery tier uses a hierarchical Model-View-Controller pattern to render web pages. Each page is a hierarchy of MVC components. So far you have created a view by creating the Freemarker template and adding it to the configuration. You don't have a controller or a model yet but you can already configure a page consisting of a single MVC component with just a view.

Select the hst:pages node and add a child node called home of type hst:component. Note that there is no separate node type for a page, the page node is simply the top level component in the hierarchy.

Add a property hst:template to the home node with the value homepage.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/add-page.png

A reference to the homepage template configuration will appear next to the property value.

/hst:hst/hst:configurations/myhippoproject/hst:pages
    + home [hst:component]
        - hst:template = homepage

Step 7: Configure the Sitemap

The final step to take is to map a URL to the page you configured. Hippo's delivery tier uses a sitemap to configure the URL space of a website and map each URL to a page and (optionally) a content item. You want your page to be rendered as the home page of your site, which means you have to add a root sitemap item.

Select the hst:sitemap node and add a child node called root of type hst:sitemapitem.

Add a property called hst:componentconfigurationid and set the value to hst:pages/home (referring to the page configuration you just created).

/hst:hst/hst:configurations/myhippoproject/hst:sitemap
    + root [hst:sitemapitem]
        - hst:componentconfigurationid = hst:pages/home

Step 8: Write the Changes

Click on the 'Write changes to repository' button in the top right corner to persist the changes you made, enabling the new template, page, and sitemap configuration.

Open the site ( http://localhost:8080/site/) to see the wonderfully simple page you created:

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/simple-page.png

A More Dynamic Hello World

In the previous section, you created a static template. However, a big part of content management is the fact that you can manage the information that is displayed. So in this section, you will extend the example so it dynamically renders content that is created and managed in Hippo CMS.

Step 1: Create a Document Type

Hippo CMS maintains a strict separation of content and presentation. Content is stored in documents. These documents have a clearly defined structure, making it very easy for editors to work with. The separation makes it easy for editors to work on the actual content. No HTML knowledge is required and, best of all, you can reuse the content anywhere.

To be able to create content, you first need to define a document type. For this, we will use the CMS document type editor.

In the CMS open the Content perspective and select Document Types in the dropdown in the top left corner. Select the myhippoproject namespace and click on the New Document Type option in the dropdown.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/new-document-type.png

In a real-world implementation you will want to be as specific as possible when creating document types (so editors work on documents like News or Blogs rather than a generic document), but for this example you will create a very basic document type called simpledocument.

Next, select the layout of the document type. This is used to determine the layout of the editing template in the CMS and has no relationship with how the content is rendered in the site. Select the 2 column layout option.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/document-type-editor.png

The document type editor allows you to add fields to the type. Add a String field (Primitive) for our title and set the Caption to Title and Path to title. Next, add a Rich Text Editor (Compound Field) to the document type. Set the Caption to Content and the path to content. After adding the fields, click 'Done' and then select 'Type Actions', 'Commit'. The document type is now ready for use in the CMS.

Step 2: Create a Document

Select 'Documents' from the dropdown in the top left corner and add a new document to the myhippoproject folder.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/new-document.png

Name the document Hello World. Also, note the URL name in the field below. It uses the name to create a URL friendly version of the document, which is used as the filename. After you click OK, you will be presented with the document editor interface containing the fields we configured for this document type.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/edit-document.png

Enter some text in the document fields and click 'Save & Close'. Then click on the 'Publish' option in the 'Publication' menu so the document becomes available to the site.

Step 3: Create a Model

In the simple Hello World example, you created a view in the form of a static template. Now that you have some content to render, it is time to create the model and controller as well and configure a full MVC component.

Let's start with the model. In Hippo's delivery tier, models are implemented as so-called content beans: plain Java objects that wrap the actual content that is stored in JCR nodes in the repository. In most cases, content beans can be automatically generated using the Beanwriter tool in the setup application.

Browse to http://localhost:8080/essentials/ and click on 'Get started' to move on to the main part of the application. Next, click on the 'Tools' tab. Click on 'Use Beanwriter'. The Beanwriter tool will save you a lot of time when creating document types in the CMS, because it will generate the beans rather than you having to write them yourself. After the bean has been generated, you should have a Java class similar to the one below in our IDE at  site/src/main/java/org/example/beans/Simpledocument.java:

@HippoEssentialsGenerated(internalName = "myhippoproject:simpledocument")
@Node(jcrType = "myhippoproject:simpledocument")
public class Simpledocument extends BaseDocument {
   @HippoEssentialsGenerated(internalName = "myhippoproject:title")
    public String getTitle() {
        return getProperty("myhippoproject:title");
   }

   @HippoEssentialsGenerated(internalName = "myhippoproject:content")
    public HippoHtml getContent() {
        return getHippoHtml("myhippoproject:content");
   }
}

Step 4: Create a Controller

With the model in place (the content bean wrapping the content), you can now create a controller and implement the business logic to retrieve the content bean and make it available to the view. In Hippo's delivery tier, controllers are implemented as Java components.

Use your IDE to create a new Java class in the site module, in the package  org.example.components, named SimpleComponent. Paste the following code in there:

site/src/main/java/org/example/components/SimpleComponent.java

package org.example.components;

import org.example.beans.Simpledocument;
import org.hippoecm.hst.component.support.bean.BaseHstComponent;
import org.hippoecm.hst.core.component.HstComponentException;
import org.hippoecm.hst.core.component.HstRequest;
import org.hippoecm.hst.core.component.HstResponse;
import org.hippoecm.hst.core.request.HstRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleComponent extends BaseHstComponent {

    public static final Logger log = LoggerFactory.getLogger(SimpleComponent.class);

    @Override
    public void doBeforeRender(final HstRequest request, final HstResponse response) throws HstComponentException {
        super.doBeforeRender(request, response);
        final HstRequestContext ctx = request.getRequestContext();

        // Retrieve the document based on the URL
        Simpledocument document = (Simpledocument) ctx.getContentBean();

        if (document != null) {
            // Put the document on the request
            request.setAttribute("document", document);
        }
   }
}

There is just one method in the class, the doBeforeRender method. This method is called just before the view is rendered, and its purpose is to perform any business logic and prepare any data that is required to render the view.

The example above is a very typical implementation. A content bean is retrieved from the request context, based on the URL (you configure the homepage URL to map to the document you created in one of the next few steps). The content bean is then stored in a request attribute so it is accessible to the template engine when the view is rendered.

Step 5: Make the View Dynamic

You now have a model and a controller which retrieves it and stores it in a request attribute. Now you can modify your Freemarker template to make the view dynamically render the content wrapped by the model.

Open the home.ftl template again and modify it so it looks like this:

bootstrap/webfiles/src/main/resources/site/freemarker/home/home.ftl

<#assign hst=JspTaglibs["http://www.hippoecm.org/jsp/hst/core"] >
<html>
<head>
</head>
<body>
  <#if document??>
    <h1>${document.title?html}</h1>
    <div>
      <@hst.html hippohtml=document.content />
    </div>
    <#else>
      <h1>Goodbye? cruel world</h1>
  </#if>
</body>
</html>

In addition to the regular Freemarker syntax and expressions, you can use Hippo-specific tags from the HST tag library. An example in the template above is the <@ hst.html> tag. This tag will process the data contained in the Rich Text field, ensuring that all internal links are validated and rewritten to the correct URL in the current page context.

You are now done with all the code changes, so stop, rebuild, and restart the project:

mvn verify
mvn -Pcargo.run

Step 6: Configure the MVC Component

After the build is done, go back to the Console to add the newly created Java component.

Add a new hst:component node to the hst:components section. Call it simplecomponent and after it is created, add a property called hst:componentclassname and set the value to org.example.components.SimpleComponent. You have now added your first reusable component!

/hst:hst/hst:configurations/myhippoproject/hst:components
    + simplecomponent [hst:component]
        - hst:componentclassname = org.example.components.SimpleComponent

Now configure the page to use that component.

Select the home node in hst:pages. Add a property to it named hst:referencecomponent and set the value to hst:components/simplecomponent.

/hst:hst/hst:configurations/myhippoproject/hst:pages/home
    - hst:referencecomponent = hst:components/simplecomponent
    - hst:template = homepage

Don't forget to write your changes.

Visit the site again at  http://localhost:8080/site/:

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/goodbye.png

Step 7: Map the URL to the Content

The template engine currently executes the logic for not having a document present. This makes sense because you have configured your view and your controller, but not yet where to retrieve your model (and thus, your document).

Go back to the console for one last time and select the hst:sitemap node. Select the root node. Add a property called hst:relativecontentpath and set the value to hello-world. This will tell the delivery tier to locate the content at that path, relative to the root folder of the site ( myhippoproject). Here you use the 'URL name' displayed while naming your document when you created it. If you created the document inside a subfolder, enter the path like mysubfolder/hello-world.

/hst:hst/hst:configurations/myhippoproject/hst:sitemap/root
    - hst:componentconfigurationid = hst:pages/home
    - hst:relativecontentpath = hello-world
In a real-world project, you typically use wildcards to map complete groups of documents, so you don't have to manually map each document to a specific URL.

Write the changes to the repository and visit the site again. You now actually see the content being rendered!

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/trails/hello-world/hello-content.png

Next Tutorial

Build a Website