Spring Framework and Magnolia CMS: Creating Complex Java-based Websites

If you're thinking about building a new Web site or re-launching an old one, it usually makes sense to consider a Content Management System (CMS). Using a CMS offers a number of advantages over hand-crafting individual pages. However, if you're building a complex Web site, an off-the-shelf CMS often won't satisfy all your requirements out of the box. You'll likely need to customize it and because each CMS its own API and architecture, you'll usually need to invest a fair amount of time learning its innards before you can start adding custom features.

From a development perspective, the ideal solution would be a CMS that can be customized without needing any special training or knowledge. If you're a Spring developer, this ideal CMS is closer than you may think. Magnolia CMS, an open-source, enterprise-grade CMS written entirely in Java, has recently added Spring support, allowing Spring developers to easily extend the base CMS with custom functionality using their existing knowledge of the Spring Framework.

In this article, I'll introduce you to Blossom, the Magnolia CMS module for Spring, and illustrate how you can use it to integrate Spring controllers and views into the Magnolia architecture. Let's get started!

Assumptions and Prerequisites

Before we dive into the code, a few notes and assumptions are worth mentioning. This tutorial assumes that you have a working knowledge of Spring 3.0.x, and that you're comfortable with deploying Web applications using Spring MVC. It also assumes that you're familiar with Java Server Pages (JSP) and the process of creating, building and deploying JAR files to an Apache Tomcat server using Apache Maven.

The Blossom module serves as a bridge between Spring and Magnolia CMS, so this tutorial also requires you to have an understanding of the Magnolia CMS architecture, especially for templating and custom modules. To obtain this understanding, you should read the WebReference article Publish Web Content Efficiently with Magnolia CMS, and then briefly review the Magnolia CMS templating tutorial and module design guide, particularly the section on creating custom modules.

In terms of software, this tutorial assumes that you have a properly configured Spring development environment, including the following components:

Java (JDK 5 or JDK 6)

Spring Framework (v3.0.1 or better)

Apache Maven (v2.2 or better)

The code in the following sections also assumes that you have downloaded and installed:

You'll find detailed instructions on how to perform these tasks in the Magnolia CMS documentation, or in the WebReference beginner's tutorial Set Up the Magnolia CMS for Web Content Creation in Just a Few Clicks. Note that the Magnolia CMS download includes a bundled version of Apache Tomcat.

With all that out of the way, let's dive right into the code!

Introducing Blossom, the Spring and Magnolia CMS Bridge

As you may already know, Magnolia CMS uses a template-based architecture that allows users to define page types and subsections through a graphical, dialog-based interface. It then presents a composite WYSIWYG view with built-in editing controls for each subsection, allowing authors to directly modify different sections of the page and see the changes instantly. Figure 1 shows a screenshot that illustrates this in action.

Figure 1: Magnolia WYSIWYG Template Editor

Magnolia's templating system allows interface designers to easily create new templates to support custom use cases. There are two basic types of templates:

Paragraph templates represent elements within pages. Page templates represent complete pages.

A single template can be reused multiple times to create different content pages.

To define a new template, a designer or developer must first create a template script using either JSP or FreeMarker. This script file contains the HTML markup for the template, together with placeholder variables that are replaced with actual content at runtime. This template script must then be registered with Magnolia via a template definition, which exposes basic information such as the template name and script path. As shown in this tutorial, these tasks can be easily accomplished through the Magnolia CMS browser-based administration panel.

If you're a Spring developer, though, there's an easier way to define templates: you can simply annotate your Spring controller classes with @Paragraph or @Template , deploy them as a Blossom-compatible module, and Magnolia will automatically detect and make them available as templates in the authoring interface. This can significantly speed up template development, while also offering the opportunity to attach custom workflows or functions to templates.

Magnolia Module Basics

To see how this works, let's create a new Magnolia module that exposes a Spring controller as a paragraph template. In your Spring development workspace, create a new project (I'll call it example-module) and within the project directory, create the directory structure shown in Figure 2.

Figure 2: Initial project directory structure

This is the conventional directory structure followed for all Magnolia modules. Java classes are stored in the src/main/java directory, while additional resources such as JSP scripts or bootstrap files are stored in the src/main/resources directory.

Every Magnolia module must include a module description file, expressed in XML. This file contains information on the module, such as its name, version number and dependencies (if any). This information is displayed in Magnolia CMS during and after the module deployment process.

To create this file, open a text editor and save the following content to src/main/resources/META-INF/magnolia/example.xml:

<!--l version="1.0" encoding="UTF-8-->

<!--CTYPE module SYSTEM "module.dtd-->

example

Example Module

info.magnolia.module.example.ExampleModule

1.0.0

This specifies the name of the module (Example Module), its version number and the package it belongs to. By convention, Magnolia modules are packaged in the info.magnolia.module.moduleName namespace.

This ExampleModule class is responsible for starting Spring, initializing the application context and setting up the dispatcher servlet. It's generally recommended that this primary class extend the BlossomModuleSupport class; doing this ensures that the module is started and stopped correctly by Magnolia.

Here's what the code looks like:

package info.magnolia.module.example;

import info.magnolia.module.ModuleLifecycle;

import info.magnolia.module.ModuleLifecycleContext;

import info.magnolia.module.blossom.module.BlossomModuleSupport;

/**

* Module class that starts and stops Spring when called by Magnolia.

*/

public class ExampleModule extends BlossomModuleSupport implements ModuleLifecycle {

public void start(ModuleLifecycleContext moduleLifecycleContext) {

initRootWebApplicationContext("classpath:/applicationContext.xml");

initBlossomDispatcherServlet("blossom", "classpath:/blossom-servlet.xml");

}

public void stop(ModuleLifecycleContext moduleLifecycleContext) {

destroyDispatcherServlets();

closeRootWebApplicationContext();

}

}

Save this file as src/main/java/info/magnolia/module/example/ExampleModule.java.

At this point, all the basic pieces are in place, and we can move on to actually creating templates with Spring.

Page 1 of 3