Axel Knauf
Axel Knauf

Reputation: 1683

Apache Tiles 2 + Spring MVC 3 using multiple sets of view definitions

This is a complex question, so please bear with me through the long explanation.

Current scenario

We are using Spring MVC 3.0.5 with Apache Tiles 2.2. Currently our Spring-based tiles configuration looks like this:

<bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/**/views.xml</value>
        </list>
    </property>

    <!-- resolving preparer names as Spring bean definition names -->
    <property name="preparerFactoryClass" 
        value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory" />
</bean>

<bean id="tilesViewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver"
    p:order="1" p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView" />

The (Tiles) view definitions are read from all views.xml files and when a Spring controller yields, say, "homepage" as logical view name to be rendered, the corresponding Tiles definition with name "homepage" gets displayed.

Aim

We now intend to allow different sets of view definitions from different directories within our web application. Reason is, that different user groups will have customized templates according to their group.

Let's say all my current view definitons reside in

 /WEB-INF/default-views/**/views.xml

And I want to add a second folder

 /WEB-INF/administrator-views/**/views.xml

This second folder shall contain view definitions with the same names as in the default-views folder. But depending on a URL pattern, either the one or the other shall be displayed. Here are two samples:

http://example.com/default/foobar 
==> Controller yields logical view name "foobar"
==> definition "foobar" from "default-views" folder shall be displayed

http://example.com/admin/foobar 
==> Controller yields logical view name "foobar"
==> definition "foobar" from "administrator-views" folder shall be displayed

In addition, we would like to allow a fallback mechanism. When a specialized view name (for "admin" in the example above) does not exist in the corresponding views folder, we want to display the default version from the other folder.

So far

Currently I am thinking about several starting points. Maybe I could be tweaking the TilesConfigurer. which keeps Tiles view definitions in a single property without distinction for the folders from where the view definitions came.

Another option is trying to accomplish this using chained view resolvers with the specialized ones being further up in the chain and the default ones at the end.

A third option is using different view names and intercept the view name response from the controller using a HandlerInterceptor to map it to the specialized view (may not work if it does not exists).

Questions

At the moment, my option #2 sound most convincing since I would like to prevent from twiddling with Springs classes when it's not really necessary. But I am missing the connection between chained view resolvers and the view definition list in TilesConfigurer.

Thanks for your patience and reading thus far.

Upvotes: 0

Views: 4669

Answers (1)

Axel Knauf
Axel Knauf

Reputation: 1683

Just for anybody who might encounter an issue like this, here's how we've implemented it:

  • use a custom HandlerInterceptorAdapter#postHandle(..) implementation to translate URL path components into logical view name prefixes
  • use Tiles view definition names with these URL prefixes in all views.xml files
  • use a custom UrlBasedViewResolver#loadView(..) implementation to first try the view name as given by Controller and HandlerInterceptor, and if it does not exist (super.loadView(..) yields null) try the default prefix instead

I hope this is clear enough.

Upvotes: 2

Related Questions