##### General Information

- Overview
- Features
- Specification
- Getting Started
- Howto Build Turbine
- Changes

##### Documentation

- Services
- Howtos
- Wiki
- JavaDocs

##### Development

- Proposals
- How To Help
- Todo

##### Project Documentation

- Project Information
- Project Reports

##### Apache

- Apache Website
- License
- How the ASF works
- Sponsorship
- Thanks
- Security

## Unified Templating Service

There are multiple templating services that provide similar functionality, but have different API. This is due to different types of "Context" objects. All these types main"Map" semantics (question: is there any other important functionality in the Contexts?). We could define a single service interface that all of the templating services (WebMacro, Velocity, FreeMarker and JSP at the moment) would implement. Its methods would use Map type to represent a Context or another interface extending or similar to map. The service would include the following methods:

    public interface TemplatingService
        extends Service
    {
        public boolean templateExists( String name );
        public Map createContext( RunData data );
        public Map createContext( );
        public Strinq merqeTemplate( String name, Map context );
    }

Definition of this common interface would allow creation of new base Modules (Screen, Navigation, Layout and Page) that would take advantage of the templating abstraction provided by the Service. This would make the modules (esp. Screens) contained in the application independent of the particular templating mechanism.

I don't know enough about FreeMarker to tell if it can fit into this model. If not, I would even suggest dropping the support for it, as it's user base seems nonexistent.

There is one important special case to consider. JSP service is unable to return the results of template merging as a String - they are written to the Response stream directly. To encompass this case in our framework, we could declare that the return value of merge template in this case is a null. The Modules would be subject to the same semantics: a null returned from build() method would mean that data was written to the response directly, and the caller should act accordingly. (an example of such case is the interaction of the Layout and the RawScreen).

The special semantics of JSP templating lead in turn to a special Page and Layout module behavior. While the "normal" Layout module executes the Screen module and merges its template before merging it's own template ("prefix" rendering), the JSP Layout needs to wrap Screen rendering in a context tool so that it is executed in the appropriate place in the Layout's markup. ("infix" rendering). The same patterns apply to Page-Layout interaction. We have the option to define JSPPage and JSPLayout Modules, or define InfixPage, InfixLayout and the LayoutRenderer and ScreenRenderer context tools, that will be used with those templating services that write the merging results directly to the Response stream. Note that during the normal Layout processing, the Navigations are subject to "infix" rendering, and the current TemplateNavigation class is a prototype of *Renderer.

The unified interface and the Infix* Modules will make adding support for other templating engines easy. This will also make porting applications easier - templates in one templating language can be created, then supporting Turbine modules are created. Later the templates can be converted to another language, and the only change to support that on the code side of things is switching a property in TR.props

The template lookup functionality that is currently contained in TemplateService, probably should be contained in the service I'm describing here, probably in an abstract base class.

Another class that would be affected by the changes mentioned here is the TempateInfo class. Right now it uses a HashTable to store it's data. Now, thanks to defining the common Context type (or using the Map type in its place), it's possible to turn the runtime typed HashTable entries into compile time typed instance variables.

The amount of work needed to port an existing application should not be very large. The applications following the Pull MVC design model would not be affected at all. The traditional Push applications would require changes in the Screen and Navigation classes regarding the names of the Context type and the parent type of the Screen/Navigation in question. These changes can be effectively introduced using an automated tool.

The Page and Layout classes would require more in-depth modifications, but a typical application would contain single customized Page and Layout classes, if any.