Basics - FreeMarker Manual

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# Basics

You have seen how to build a data-model in the Getting Started using the standard Java classes (`Map`, `String`, etc.). Internally, the variables available in the template are Java objects that implement the `freemarker.template.TemplateModel` interface. But you could use standard Java collections as variables in your data-model, because these were replaced with the appropriate `TemplateModel` instances behind the scenes. This facility is called object wrapping. The object wrapping facility can convert any kind of object transparently to the instances of classes that implement `TemplateModel` interface. This makes it possible, for example, to access `java.sql.ResultSet` as sequence variable in templates, or to access `javax.servlet.ServletRequest` objects as a hash variable that contains the request attributes, or even to traverse XML documents as FTL variables (see here). To wrap (convert) these objects, however, you need to plug the proper `ObjectWrapper` implementation (possibly your custom implementation); this will be discussed later. The point for now is that any object that you want to access from the templates, sooner or later must be converted to an object that implements `TemplateModel` interface. So first you should familiarize yourself with writing of `TemplateModel` implementations.

There is roughly one `freemarker.template.TemplateModel` descendant interface corresponding to each basic type of variable (`TemplateHashModel` for hashes, `TemplateSequenceModel` sequences, `TemplateNumberModel` for numbers, etc.). For example, if you want to expose a `java.sql.ResultSet` as a sequence for the templates, then you have to write a `TemplateSequenceModel` implementation that can read `java.sql.ResultSet`-s. We used to say on this, that you wrap the `java.sql.ResultSet` with your `TemplateModel` implementation, as basically you just encapsulate the `java.sql.ResultSet` to provide access to it with the common `TemplateSequenceModel` interface. Note that a class can implement multiple `TemplateModel` interfaces; this is why FTL variables can have multiple types (see: Template Author's Guide/Values, Types/Basics)

Note that a trivial implementation of these interfaces is provided with the `freemarker.template` package. For example, to convert a `String` to FTL string variable, you can use `SimpleScalar`, to convert a `java.util.Map` to FTL hash variable, you can use `SimpleHash`, etc.

An easy way to try your own `TemplateModel` implementation, is to create an instance of that, and drop it directly into the data-model (as `put` it into the root hash). The object wrapper will expose it untouched for the template, as it already implements `TemplateModel`, so no conversion (wrapping) needed. (This trick is also useful in cases when you do not want the object wrapper to try to wrap (convert) a certain object.)

Previous Next