Hello World
A Quick Hands-On Introduction to Bloomreach Experience Manager Fundamental Concepts
This short tutorial gives a quick look into the fundamentals of Bloomreach Experience Manager and its 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 Bloomreach Experience Manager-based website.
This tutorial is specifically aimed at Java developers who want to get a quick hands-on start with Bloomreach Experience Manager 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 Bloomreach Experience Manager 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.
A Very Simple Hello World
First, you will build a simple static Hello World page that is served by Bloomreach Experience Manager. You will learn how to add a Freemarker template to the project and how to configure Bloomreach Experience Manager to use it.
Step 1: Create a New Project
Start by making sure your development environment meets the prerequisites.
Then generate your Bloomreach Experience Manager 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 repository-data/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:
repository-data/webfiles/src/main/resources/site/freemarker/home/home.ftl
<html> <head> </head> <body> <h1>Hello World </h1> </body> </html>
Step 4: Introducing the Console
Browse to the Console at http://localhost:8080/cms/console and log in using the default admin / admin credentials.
The Console provides direct access to the 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:myproject/hst:configurations node, that holds the configuration for your website.
Step 5: Configure the Template
Let's get started by configuring Bloomreach Experience Manager to use the template you just created. Browse to the node at /hst:myproject/hst:configurations/myproject and you will see something similar to this:
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:
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:myproject/hst:configurations/myproject/hst:templates: /homepage: jcr:primaryType: hst:template hst:renderpath: webfile:/freemarker/home/home.ftl
Step 6: Add a Page (Component)
The 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.
A reference to the homepage template configuration will appear next to the property value.
/hst:myproject/hst:configurations/myproject/hst:pages: /home: jcr:primaryType: 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. The 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:myproject/hst:configurations/myproject/hst:sitemap: /root: jcr:primaryType: 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:
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 Bloomreach Experience Manager.
Step 1: Create a Document Type
Bloomreach Experience Manager 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 myproject namespace and click on the New Document Type option in the dropdown.
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.
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 myproject folder.
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.
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 the 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/components/src/main/java/org/example/beans/Simpledocument.java:
@HippoEssentialsGenerated(internalName = "myproject:simpledocument") @Node(jcrType = "myproject:simpledocument") public class Simpledocument extends BaseDocument { @HippoEssentialsGenerated(internalName = "myproject:title") public String getTitle() { return getSingleProperty("myproject:title"); } @HippoEssentialsGenerated(internalName = "myproject:content") public HippoHtml getContent() { return getHippoHtml("myproject: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 the delivery tier, controllers are implemented as Java components.
Use your IDE to create a new Java class in the site-components module, in the package org.example.components, named SimpleComponent. Paste the following code in there:
site/components/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 final 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:
repository-data/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 Bloomreach Experience Manager-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:myproject/hst:configurations/myproject/hst:components: /simplecomponent: jcr:primaryType: 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:myproject/hst:configurations/myproject/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/:
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 ( myproject). 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:myproject/hst:configurations/myproject/hst:sitemap/root: hst:componentconfigurationid: hst:pages/home hst:relativecontentpath: hello-world
Write the changes to the repository and visit the site again. You now actually see the content being rendered!