2.1 - FreeMarker Manual

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# 2.1

Date of release: 2002-10-17

Templates and the Java API are not fully compatible with 2.0 releases. You will need to revisit existing code and templates, or use 2.1 for new projects only. Sorry for this inconvenience; FreeMarker has undergone some revolutionary changes since the 1.x series. We hope things will soon be sufficiently mature for us to offer (almost) backward-compatible releases. Note that there is a backward-compatibility flag that can be set via `Configuration.setClassicCompatible(true)` that causes the new FreeMarker to emulate most of FreeMarker 1.x's quirks.

## Changes in FTL (FreeMarker Template Language)

- More strict, reveals accidental mistakes in the templates, prevents showing incorrect information when something went wrong:

  - An attempt to access an undefined variable causes an error and aborts template processing (by default at least; see later). In earlier versions undefined variables were silently treated as empty (zero-length) strings. However, you can handle undefined variables in the template with some new built-ins. For example, `${foo?if_exists}` is equivalent with the `${foo}` of earlier versions. Another way of looking at this is that null values no longer exist from the viewpoint of a template designer. Anything referenced must be a defined variable.

    Note however that the programmer can configure FreeMarker so that it ignores certain errors (say, undefined variables), and continues template processing by skipping the problematic part. This ``loose'' policy should be used only for sites that don't show critical information.

  - New variable type: boolean. Conditions in `if`/`elseif` and operands of logical operators (`&&`, `||`, `!`) must be booleans. Empty strings are no longer treated as a logical false.

- Local and global variables. More info: Template Author's Guide/Miscellaneous/Defining variables in the template

  - Local variables for macros. You can create/replace local variables in macro definition bodies with the `local` directive

  - You can create/replace global (non-local) variables with the `global` directive

- The `include` directive now by default treats the passed filename as being relative to the including template's path. To specify absolute template paths, you now have to prepend them with a slash.

- The `include` directive can now use the acquisition algorithm (familiar from the Zope system) to look up the template to include. Basically, if a template is not found where it is looked up first, it is looked up in parent directories. This is however not a default behavior, rather it is triggered by a new syntactic element.

- Strict syntax mode: Allows you to generate arbitrary SGML (XML) without worrying about clashes with FreeMarker directives. For more information read: Template Language Reference/Deprecated FTL constructs/Old FTL syntax

- Terse comments: you can use `<#-- ... -->` instead of `<comment>...</comment>`

- Directive that you can use to change the locale (and other settings) inside the template: `setting`

- Directive to explicitly flush the output buffer: `flush`

- The top-level (root) hash is available via the variable `root`, which is now a reserved name.

- The misnamed `function` directive has been renamed to `macro`.

- String literals support various new escape sequences, including UNICODE escapes (`\xCODE`)

- The `compress` directive is now more conservative in removing line breaks.

- Built-in to capitalize the first word: `cap_first`

- Built-in to generate on-the-fly templates: `interpret`

- `stop` directive has an optional parameter to describe the reason of termination

- Better error messages.

- New variable type: date. Date support is experimental. It can change substantially in the future. Keep this in mind if you use it.

## Changes on the Java side

- `ObjectWrapper`: You can put non-`TemplateModel` objects directly into hashes, sequences and collections, and they will be automatically wrapped with the appropriate `TemplateModel` implementation. The API of objects that are exposed to templates (`SimpleXXX`) has been changed according to this, for example in `SimpleHash` the old `put(String key, TemplateModel value)` is now `put(String key, Object object)`. Also, you can pass any kind of object as data-model to `Template.process`. The alternative reflection based `ObjectWrapper` can expose the members of any Java object automatically for the designer. More information: Object wrapping, Bean wrapper, Jython wrapper.

- The `Configuration` object was introduced as a central point to hold all your FreeMarker-related global settings, as well as commonly used variables that you want to have available from any template. Also it encapsulates the template cache and can be used to load templates. For more information read Programmer's Guide/The Configuration.

- `TemplateLoader`: pluggable template loader, separates caching from template loading

- `TemplateNumberModel`-s do not control their formatting anymore. They just store the data (i.e. a number). Number formatting is done by the FreeMarker core based on the `locale` and `number_format` settings. This logic applies to the new experimental date type as well.

- `TemplateBooleanModel` introduced: Only objects that implements this interface can be used as a boolean in true/false conditions. More info: Programmer's Guide/The Data Model/Scalars

- `TemplateDateModel` introduced: objects that implements this interface are recognized as dates and can be locale-sensitively formatted. Date support is experimental in FreeMarker 2.1. It can change substantially in the future. Keep this in mind if you use it.

- The `TemplateModelRoot` interface was deprecated. As of FreeMarker 2.1, you can simply use any instance of `TemplateHashModel` instead. This actually is due to a significant architectural change. Variables set or defined in a template are stored in a separate `Environment` object that only exists while the template is being rendered. Thus, the template doesn't modify the root hash.

- Changes to transformations

  - Completely rewritten `TemplateTransformModel` interface. More flexible, and does not impose output holding. More information: Programmer's Guide/The Data Model/Directives

  - The `transform` directive now takes an optional set of key/value pairs. `<transform myTransform; key1=value1, key2=value2 ...>`. More information: `transform` directive

  - The transforms that ship with the FreeMarker core are now available by default to all templates - i.e. `<transform html_escape>` will invoke the `freemarker.template.utility.HtmlEscape` transform. More information: Programmer's Guide/The Configuration/Shared variables

- User-defined `TemplateModel` objects now can access the runtime environment (read and set variables, get the current locale, etc.) using an `Environment` instance, which can be obtained by the static `Environment.getCurrentEnvironment()` method. As a result, `TemplateScalarModel.getAsString` has been changed: it has no locale parameter.

- `TemplateExceptionHandler`-s make it possible to define your own rules on what to do when a runtime error occurs (e.g. accessing a non existing variable) during template processing. For example, you can abort template processing (recommended for most sites), or skip the problematic statement and continue template processing (similar to old behavior). DebugMode has been removed, use `TemplateExceptionHandler.DEBUG_HANDLER` or `HTML_DEBUG_HANDLER` instead.

- Logging: FreeMarker logs certain events (runtime errors for example). For more information read Programmer's Guide/Miscellaneous/Logging.

- `SimpleIterator` was removed, but we provide a `TemplateCollectionModel` implementation: `SimpleCollection`.

- Arithmetic engine is pluggable (`Configuration.setArithmeticEngine`). The core distribution comes with two engines: `ArithmeticEngine.BIGDECIMAL_ENGINE` (the default) that converts all numbers to `BigDecimal` and then operates on them, and `ArithmeticEngine.CONSERVATIVE_ENGINE` that uses (more-or-less) the widening conversions of Java language, instead of converting everything to `BigDecimal`.

- Changes to `freemarker.ext.beans` package: The JavaBeans adapter layer has suffered several major changes. First, `BeansWrapper` is no longer a static utility class - you can now create instances of it, and every instance can have its own instance caching policy and security settings. These security settings are also new - you can now create JavaBeans wrappers that hide methods that are considered unsafe or inappropriate in a templating environment. By default, you can no longer call methods like `System.exit()` from the template (although you can manually turn off these safeguards). The `StaticModel` and `StaticModels` classes are gone; their functionality is now replaced with the `BeansWrapper.getStaticModels()` method.

- `freemarker.ext.jython` package: FreeMarker can now directly use Jython objects as data-models using the Jython wrapper.

- Changes to `freemarker.ext.jdom` package: The package now uses the Jaxen package instead of its predecessor, the werken.xpath package to evaluate XPath expressions. Since Jaxen is a successor to werken.xpath, this can be considered to be an upgrade. As a consequence, namespace prefixes are now recognized in XPath expressions and the overall XPath conformance is better.

- Better error reporting: If the processing of a template is aborted by a `TemplateException` being thrown, or using a `<#stop>` directive, FreeMarker will now output an execution trace with line and column numbers relative to the template source.

- The output is written to a simple `Writer`; no more `PrintWriter`. This redesign causes FreeMarker to no longer swallow `IOException`s during template processing.

- Various API cleanups, primarily the removing of superfluous constructor and method overloads.

## Other changes

- Documentation has been rewritten from scratch

## Differences between the RC1 and final release

- Added the support for date models and locale-sensitive date formatting. Date support is experimental in FreeMarker 2.1. It can change substantially in the future. Keep this in mind if you use it.

- Added the `default` built-in which makes it possible to specify default values for undefined expressions.

- `SimpleIterator` has been removed, `SimpleCollection` has been introduced

- Arithmetic engine is pluggable. The core now contains two arithmetic engines: `ArithmeticEngine.BIGDECIMAL_ENGINE` and `ArithmeticEngine.CONSERVATIVE_ENGINE`.

- `BeansWrapper` supports a new exposure level: `EXPOSE_NOTHING`

- `Constants` interface was removed. `..._WRAPPER` constants have been moved from `Constants` to `ObjectWrapper`, `EMPTY_STRING` constant was moved to `TemplateScalarModel`, `NOTHING` constant was moved to `TemplateModel`, `TRUE` and `FALSE` constants were moved to `TemplateBooleanModel`.

- `JAVABEANS_WRAPPER` was renamed to `BEANS_WRAPPER`

- `Configuration.get` and `put`, `putAll` were renamed to `getSharedVariable` and `setSharedVariable`, `setAllSharedVariables`

- `Configuration.getClassicCompatibility`, `setClassicCompatibility` were renamed to `isClassicCompatible`, `setClassicCompatible`

- `Template.process` method overloads with `useReflection` parameter was removed. But now we have `setObjectWrapper` method in the `Configuration`, so you can set the preferred root-object wrapper there.

- Some superfluous method overloads were removed; these changes are backward compatible with RC1

- Various minor JavaDoc and Manual improvements

- Bugfix: `include` directive has calculated the base path of relative paths wrongly

- Bugfix: We have accidentally used a J2SE 1.3 class, but FreeMarker 2.1 must able to run on J2SE 1.2

Previous Next