FM-Classic Manual

Copyright © 1998 Benjamin Geer
Authors: Benjamin Geer, Mike Bayer

When you're writing servlets to generate dynamic web pages, how do you keep the HTML separate from your Java code, so that graphic designers can change the HTML without your having to change your classes? FM-Classic solves this problem by encapsulating HTML in templates.

The source code for a template is an HTML document that contains instructions for including dynamically-generated data. These instructions are simple and unobtrusive (so the graphic designers can still do their work), but powerful enough to let you use data structures of arbitrary complexity. It's easy to generate tables of data, and you can use "if" and "switch" statements to generate conditional HTML. Control structures (lists, if-else structures, and switch-case structures) can be nested as in any other programming language.

A servlet or other Java object can construct an object of class Template on initialization; the Template object compiles the template into an efficient, reusable form. Compiled templates respond almost as fast as static HTML pages. When processing a request, the servlet passes the Template a tree of data objects; the Template inserts the data from these objects into the appropriate places in the HTML, and sends the finished HTML page to the servlet's output stream. You can use the package to display data from your existing data objects, by writing thin adapter classes.

The data objects passed to a Template object must form a tree structure. Each node in the tree must implement one of four interfaces, allowing it to be used as a scalar (an object used for its string value), a hash (an object containing named elements), a list (an object whose elements can be read sequentially), or a method (an object that takes a list of arguments and returns one of the other object types). The root node must act as a hash. A simple data model could have this structure:

            hash
  +----------+----------+
  |          |          |
method      hash       list
  |          |          |
scalar   +---+---+      +hash--+------+
         |       |      |      |      |
       scalar  scalar   |    scalar scalar
                        |
                        +hash--+------+
                               |      |
                             scalar scalar

That is, a method returning a scalar, a hash of scalars, and a list of hashes of scalars. A list of hashes of scalars could be used to represent rows of data from a relational database.

After preparing the data model, the servlet can output HTML with a method call on the Template object:

// modelRoot is the root node of the data model, and out is a PrintWriter

template.process(modelRoot, out);

Error messages generated by template syntax errors, and messages from exceptions thrown by objects in the data model, are inserted as comments in the HTML output.

The FM-Classic classes you'll need to use directly are in the package freemarker.template.

All instructions in the template language are case-sensitive.