16.7 Using themes

16.7.1 Introduction

The theme support provided by the Spring web MVC framework enables you to further enhance the user experience by allowing the look and feel of your application to be themed. A theme is basically a collection of static resources affecting the visual style of the application, typically style sheets and images.

16.7.2 Defining themes

When you want to use themes in your web application you'll have to set up a org.springframework.ui.context.ThemeSource. The WebApplicationContext interface extends ThemeSource but delegates its responsibilities to a dedicated implementation. By default the delegate will be a org.springframework.ui.context.support.ResourceBundleThemeSource that loads properties files from the root of the classpath. If you want to use a custom ThemeSource implementation or if you need to configure the basename prefix of the ResourceBundleThemeSource, you can register a bean in the application context with the reserved name "themeSource". The web application context will automatically detect that bean and start using it.

When using the ResourceBundleThemeSource, a theme is defined in a simple properties file. The properties file lists the resources that make up the theme. Here is an example:

styleSheet=/themes/cool/style.css
background=/themes/cool/img/coolBg.jpg

The keys of the properties are the names used to refer to the themed elements from view code. For a JSP this would typically be done using the spring:theme custom tag, which is very similar to the spring:message tag. The following JSP fragment uses the theme defined above to customize the look and feel:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
   <head>
      <link rel="stylesheet" href="<spring:theme code="styleSheet"/>" type="text/css"/>
   </head>
   <body background="<spring:theme code="background"/>">
      ...
   </body>
</html>

By default, the ResourceBundleThemeSource uses an empty basename prefix. As a result the properties files will be loaded from the root of the classpath, so we'll have to put our cool.properties theme definition in a directory at the root of the classpath, e.g. in /WEB-INF/classes. Note that the ResourceBundleThemeSource uses the standard Java resource bundle loading mechanism, allowing for full internationalization of themes. For instance, we could have a /WEB-INF/classes/cool_nl.properties that references a special background image, e.g. with Dutch text on it.

16.7.3 Theme resolvers

Now that we have our themes defined, the only thing left to do is decide which theme to use. The DispatcherServlet will look for a bean named "themeResolver" to find out which ThemeResolver implementation to use. A theme resolver works in much the same way as a LocaleResolver. It can detect the theme that should be used for a particular request and can also alter the request's theme. The following theme resolvers are provided by Spring:

Table 16.6. ThemeResolver implementations

ClassDescription
FixedThemeResolverSelects a fixed theme, set using the "defaultThemeName" property.
SessionThemeResolverThe theme is maintained in the users HTTP session. It only needs to be set once for each session, but is not persisted between sessions.
CookieThemeResolverThe selected theme is stored in a cookie on the user-agent's machine.

Spring also provides a ThemeChangeInterceptor, which allows changing the theme on every request by including a simple request parameter.