These are the built-ins that normally you should not use, but in exceptional situations (debugging, advanced macros) they can be useful. If you need to use these in your normal page templates, you may revisit the data-model so you don't need to use these.
[TODO: document some border cases]
With the help of this built-in you can read and write the local variables of another macro that is just executing its nested content. That is, if we have something like [@theParent]...[@theChild /]...[/@theParent] then the theChild macro can communicate with the enclosing theParent macro by reading and writing the local variables of the theParent macro call.
The usage is theParentMacro?scope, which returns a hash that corresponds to the local variables. The hash can be read and enumerated as usual hashes, and in additional it can be modified with [#set theLocalVariable = newValue in theHash]. Hence the communication between the two macros can be two way.
Example 1: Assume you have two macros, that fulfill similar role as UL and LI in HTML. The problem is, for generating its own output, the LI-like macro should know what bullet you have specified in the UL-like macro.
| |||
The output will be (apart from some needless whitespace):
| |||
Example 2: We want to number items in an arbitrary section of the template.
| |||
The output will be (after removing some needless whitespace):
| |||
Returns a SimpleNumber which contains the same value as the original variable, but uses java.lang.Type for the internal representation of the value. This is useful if a method is overloaded, or if a TemplateModel unwrapper has problem with automatically choosing the suitable java.lang.* type. Note that since version 2.3.9 the unwrapper has been improved substantially, so you will hardly ever need to use these built-ins, except for resolving ambiguity in overloaded method invocation.
This built-in evaluates a string as an FTL expression. For example "1+2"?eval returns number 3.
It is true if the variable exists (and isn't Java null) and is not ''empty'', otherwise it is false. The meaning of ''empty'' depends on the concrete case. This follows intuitive common-sense ideas. The following are empty: a string with 0 length, sequence or hash with no subvariables, a collection which has passed the last element. If the value is not a string or sequence or hash or collection, then it counts as non-empty if it's a number or a date or a boolean (e.g., 0 and false are not empty), otherwise it counts as empty. Note that when your data-model implements multiple template model interfaces you may get unexpected results. However, when in doubt you can use always use expr!?size > 0 or expr!?length > 0 instead of expr?has_content.
This buit-in is exceptional in that you can use the parentheses trick like with the default value operator. That is, you can write both product.color?has_content and (product.color)?has_content. The first doesn't handle the case when product is missing, the last does.
This built-in interprets a string as a FTL template, and returns an user-defined directive that executes the template just as if it was included at that point. Example:
| |||
The output:
| |||
As you can see, inlineTemplate is a directive that, when executed, runs the template that was generated on-the-fly using the interpret.
You can also apply this built-in to a two-element sequence. In this case the first element of the sequence is the template source, and the second element is a name for the inline template. It can be useful to give an explicit name to the inline template for debugging purposes. So, you could have written:
| |||
as well in the above template. Note that giving the inline template a name has no immediate effect - it is only useful as an extra bit of information if you get an error report.
To find out if an existing variable is null, Java programmers would immediately write expr == null, but that's WRONG in FTL. You should write: exp?is_null. Note that this built in will not suppress undefined variable errors. (For more information about handling null values and missing variables, read this...)
Before using it, consider if exp?? wouldn't be better. If you write variable?is_null, a mistake in the variable name will cause undefined variable error, which is a good thing. On the other hand, if you write variable??, the template will endure the subtle data-model changes where a variable will be rather undefined than having a null value. In general, non-programmer template authors should just always use exp??, as it doesn't assume the deeper knowledge of the Java objects behind data-model.
Why is var == null wrong? In Java/C++ the == operator does a pointer comparison. For example, if you compare two String-s like s1 == s2, then you ask if the two objects has the same identity (same memory address), and not if they store identical text. For that, you had to write s1.equals(s2) in Java. But in FTL, like in most scripting languages, s1 == s2 is like s1.equals(s2). And thus, like in Java s1.equals(null) or null.equals(s2) fails, this will fail as well. Not because of technical reasons, but simply because it doesn't make sense to ask "Is this text the same as another text that I don't know about?". That question can't be safely answered, and thus FreeMarker stops with error.
These built-ins check the type of a variable, and returns true or false depending on the type. The list of is_... built-ins:
| Built-in | Returns true if the value is a ... |
|---|---|
| is_string | string |
| is_number | number |
| is_boolean | boolean |
| is_date | date (all types: date-only, time-only and date-time) |
| is_method | method |
| is_transform | transform |
| is_macro | macro |
| is_hash | hash |
| is_hash_ex | extended hash (i.e., supports ?keys and ?values) |
| is_sequence | sequence |
| is_collection | collection |
| is_enumerable | sequence or collection |
| is_indexable | sequence |
| is_directive | Whatever kind of directive (for example a macro, or TemplateDirectiveModel, TemplateTransformModel, etc.) |
| is_node | node |
This built-in returns the namespace (a hash) associated with a macro variable. You can use it with macros only.
This is to create a variable of a certain TemplateModel implementation.
On the left side of ? you specify a string, the full-qualified class name of a TemplateModel implementation. The result is a method variable that calls the constructor, and returns the new variable.
Example:
| |||
For more information about how the constructor parameters are unwrapped and how overloaded constructor is chosen, read: Programmer's Guide/Miscellaneous/Bean wrapper
If you have an existing macro, you can define a new macro that is identical to the existing one, but specifies new or different default values for some parameters. A naive approach to this would be:
| |||
There is however a more elegant approach, using the ?use_defaults built-in for this purpose, i.e.,:
| |||
The use_defaults is especially useful when you pass one macro as a parameter to the other. Consider the following example:
| |||
In the above example, you have a generic macro "renderInputElement" that renders one table row with a label and an input element. The input element is rendered by another macro passed in as the parameter named "renderer". The "renderInputElement" macro will pass the input element name to the renderer, but it doesn't know about any other, renderer specific parameters (i.e., the list of options in the dropdown list). This macro couldn't invoke the "renderSelect" directly, as it can't pass it the required parameter "options". Fortunately, using the use_defaults, you can pass it a tailored version of the "renderSelect" macro with its "options" parameter set.
You can use the use_defaults built-in on macros, transforms, functions, and method models alike. You can use it to specify default values using either positional or named arguments syntax, although use with positional arguments tends to be awkward.


