Scalars - FreeMarker Manual

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# Scalars

There are 4 scalar types:

- Boolean
- Number
- String
- Date-like (subtypes: date (no time part), time or date-time)

For each scalar type is a `TemplateTypeModel` interface, where `Type` is the name of the type. These interfaces define only one method: `type getAsType();`. This returns the value of the variable with the Java type (`boolean`, `Number`, `String` and `Date` respectively).

Note:

For historical reasons the interface for string scalars is called `TemplateScalarModel`, not `TemplateStringModel`. (It's because in early FreeMarker strings were the only kind of scalars.)

A trivial implementation of these interfaces are available in `freemarker.template` package with `SimpleType` class name. However, there is no `SimpleBooleanModel`; to represent the boolean values you can use the `TemplateBooleanModel.TRUE` and `TemplateBooleanModel.FALSE` singletons.

Note:

For historical reasons the class for string scalars is called `SimpleScalar`, not `SimpleString`.

Scalars are immutable within FTL. When you set the value of a variable in a template, then you replace the `TemplateTypeModel` instance with another instance, and don't change the value stored in the original instance.

## Difficulties with the "date-like" types

There is a complication around date-like types, because Java API usually does not differentiate `java.util.Date`-s that store only the date part (April 4, 2003), only the time part (10:19:18 PM), or both (April 4, 2003 10:19:18 PM). To display the value as text correctly (or to do certain other operations), FreeMarker must know what parts of the `java.util.Date` stores meaningful information, and what parts are unused (usually 0-ed out). Unfortunately, this information is usually only available when the value comes from a database, because most databases have separate date, time and date-time (aka. timestap) types, and `java.sql` has 3 corresponding `java.util.Date` subclasses for them.

`TemplateDateModel` interface has two methods: `java.util.Date getAsDate()` and `int getDateType()`. A typical implementation of this interface, stores a `java.util.Date` object, plus an integer that tells the subtype. The value of this integer must be a constant from the `TemplateDateModel` interface: `DATE`, `TIME`, `DATETIME` and `UNKNOWN`.

About `UNKNOWN`: `java.lang` and `java.util` classes are usually converted automatically into `TemplateModel` implementations be the `ObjectWrapper` (see object wrapping earlier). If the object wrapper has to wrap a `java.util.Date`, that is not an instance of a `java.sql` date class, it can't decide what the subtype is, so it uses `UNKNOWN`. Later, if the template has to use this variable, and the subtype is needed for the operation, it will stop with error. To prevent this, for the problematic variables the template author must specify the subtype explicitly using the `date`, `time` or `datetime` built-ins (like `lastUpdated?datetime`). Note that if you use `string` built-in with format parameter, as `foo?string["MM/dd/yyyy"]`, then FreeMarker doesn't need to know the subtype.

Previous Next