blob: 8466625eca97d05bbc7df4262cf285777fca99c3 [file] [log] [blame]
<!doctype html>
<!-- Generated by FreeMarker/Docgen from DocBook -->
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>The types - Apache FreeMarker Manual</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="Apache FreeMarker Manual">
<meta property="og:title" content="The types">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/dgui_datamodel_types.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/dgui_datamodel_types.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1707770044859">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script>
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="https://freemarker.apache.org/docs/">
<meta itemprop="name" content="Apache FreeMarker Manual">
<!--[if lte IE 9]>
<div class="oldBrowserWarning" style="display: block">
Unsupported web browser - Use a modern browser to view this website!
</div>
<![endif]--> <div class="oldBrowserWarning">
Unsupported web browser - Use a modern browser to view this website!
</div>
<div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo">
<a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div>
<ul class="tabs"><li><a href="https://freemarker.apache.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="search-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"> <div class="breadcrumbs">
<ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui.html"><span itemprop="name">Template Author&#39;s Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_datamodel.html"><span itemprop="name">Values, Types</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_datamodel_types.html"><span itemprop="name">The types</span></a></li></ul> </div>
<div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper">
<div id="table-of-contents-wrapper" class="col-left">
<script>var breadcrumb = ["Apache FreeMarker Manual","Template Author\'s Guide","Values, Types","The types"];</script>
<script src="toc.js?1707770044859"></script>
<script src="docgen-resources/main.min.js?1707770044859"></script>
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_datamodel_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="dgui_datamodel_types" itemprop="headline">The types</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#dgui_datamodel_scalar" data-menu-target="dgui_datamodel_scalar">Scalars</a></li><li><a class="page-menu-link" href="#dgui_datamodel_container" data-menu-target="dgui_datamodel_container">Containers</a></li><li><a class="page-menu-link" href="#autoid_11" data-menu-target="autoid_11">Subroutines</a><ul><li><a class="page-menu-link" href="#dgui_datamodel_method" data-menu-target="dgui_datamodel_method">Methods and functions</a></li><li><a class="page-menu-link" href="#dgui_datamodel_userdefdir" data-menu-target="dgui_datamodel_userdefdir">User-defined directives</a></li><li><a class="page-menu-link" href="#autoid_12" data-menu-target="autoid_12">Function/method versus user-defined directive</a></li></ul></li><li><a class="page-menu-link" href="#autoid_13" data-menu-target="autoid_13">Miscellaneous</a><ul><li><a class="page-menu-link" href="#dgui_datamodel_node" data-menu-target="dgui_datamodel_node">Nodes</a></li><li><a class="page-menu-link" href="#dgui_datamodel_markupoutput" data-menu-target="dgui_datamodel_markupoutput">Markup output</a></li></ul></li></ul> </div><p>The suppored types are:</p><ul>
<li>
<a href="#dgui_datamodel_scalar">Scalars:</a>
<ul>
<li>
String
</li>
<li>
Number
</li>
<li>
Boolean
</li>
<li>
Date-like (date, time, or date-time)
</li>
</ul>
</li>
<li>
<a href="#dgui_datamodel_container">Containers:</a>
<ul>
<li>
Hash
</li>
<li>
Sequence
</li>
<li>
Collection
</li>
</ul>
</li>
<li>
Subroutines:
<ul>
<li>
<a href="#dgui_datamodel_method">Methods and
functions</a>
</li>
<li>
<a href="#dgui_datamodel_userdefdir">User-defined
directives</a>
</li>
</ul>
</li>
<li>
Miscellaneous/seldom used:
<ul>
<li>
<a href="#dgui_datamodel_node">Node</a>
</li>
<li>
<a href="#dgui_datamodel_markupoutput">Markup
output</a>
</li>
</ul>
</li>
</ul>
<h2 class="content-header header-section2" id="dgui_datamodel_scalar">Scalars</h2>
<a name="topic.designer.scalarVariable"></a>
<p>These are the basic, simple kind of values. They can
be:</p>
<ul>
<li>
<p>String: It is simple text, e.g., the name of a
product.</p>
<p>If you want to give a string value directly in the
template, rather than use a variable that comes from the data
model, you write the text between quotation marks, e.g.,
<code class="inline-code">&quot;green mouse&quot;</code> or <code class="inline-code">&#39;green
mouse&#39;</code>. (More details regarding the syntax can be
found <a href="dgui_template_exp.html#dgui_template_exp_direct_string">later</a>.)</p>
</li>
<li>
<p>Number: For example the price of a product.
<span class="marked-for-programmers">Whole numbers and non-whole
numbers are not distinguished; there is only a single number
type. So for example 3/2 will be always 1.5, and never 1. Just
like if you are using a calculator.</span></p>
<p>If you want to give a numerical value directly in the
template, then you write for example: <code class="inline-code">150</code> or
<code class="inline-code">-90.05</code> or <code class="inline-code">0.001</code>. (More
details regarding the syntax can be found <a href="dgui_template_exp.html#dgui_template_exp_direct_number">later</a>.)</p>
</li>
<li>
<p>Boolean: A boolean value represents a logical true
or false (yes or no). For example, if a the visitor has been
logged in or not. Typically you use booleans as the condition of
the <code class="inline-code">if</code> directive, like <code class="inline-code">&lt;#if
loggedIn
&gt;<em class="code-color">...</em>&lt;/#if&gt;</code> or
<code class="inline-code">&lt;#if price ==
0&gt;<em class="code-color">...</em>&lt;/#if&gt;</code>; in
the last case the result of the <code class="inline-code">price == 0</code>
part is a boolean value.</p>
<p>In the templates you can directly specify a boolean with
the reserved words <code class="inline-code">true</code> and
<code class="inline-code">false</code>.</p>
</li>
<li>
<p>Date: A date-like value stores date/time related
data. It has three variations:</p>
<ul>
<li>
<p>Date: Like April 4, 2003. Day precision, no time of
day part.</p>
</li>
<li>
<p>Time: Like 10:19:18 PM. Millisecond precision, no date
part.</p>
</li>
<li>
<p>Date-time (sometimes called &quot;time stamp&quot;) as April 4,
2003 10:19:18 PM. Both date and time, with millisecond
precision.</p>
</li>
</ul>
<p>Unfortunately, because of the limitations of the Java
platform, FreeMarker sometimes can&#39;t decide which parts of the
date are in use (i.e., if it is date-time, a date or a time).
The solution for this problem is an advanced topic that will be
discussed <a href="ref_builtins_date.html#ref_builtin_date_datetype">later</a>.</p>
<p>It is possible to define date-like values directly in
templates, but this is an advanced topic that will be explained
<a href="ref_builtins_string.html#ref_builtin_string_date">later</a>.</p>
</li>
</ul>
<p>Bear in mind that FreeMarker distinguishes strings from
numbers, booleans and date-like values. For example, while the
string <code class="inline-code">&quot;150&quot;</code> looks like the number
<code class="inline-code">150</code>, a string is still just arbitrary sequence of
characters, and you can&#39;t do arithmetic with it, can&#39;t compare it
with another number, etc.</p>
<h2 class="content-header header-section2" id="dgui_datamodel_container">Containers</h2>
<p>These are the values whose purpose is to contain other
variables; they are just containers. The contained variables are
often referred as <em>sub variables</em>. The container
types are:</p>
<ul>
<li>
<p>Hash: Associates a unique lookup name with each of
its sub variables. The name is an unrestricted string. A hash
<em>doesn&#39;t define an ordering</em> for the sub
variables in it. That is, there is no such thing as the first
subvariable, and the second subvariable, etc.; the variables are
just accessed by name.</p>
</li>
<li>
<p>Sequence: Associates an integer number with each
of its sub variables. The first subvariable is associated with
0, the second with 1, the third to 2, and so on; the sub
variables are ordered. These numbers are often called the
<em>indexes</em> of the sub variables. Sequences are
usually dense, i.e., all indexes up to the index of the last
subvariable have an associated subvariable, but it&#39;s not
strictly necessary. The type of the subvariable values need not
be the same.</p>
</li>
<li>
<p>Collection: A collection, from the viewpoint of
the template author, is a restricted sequence. You cannot access
its size or retrieve its sub variables by index, but they can be
still listed with the <a href="ref_directive_list.html#ref.directive.list"><code>list</code>
directive</a>. Furthermore, very often they can only be
listed once. (If you are a Java programmer,
"iterable" would be a more fitting name than
collection.)</p>
</li>
</ul>
<p>Note that since <a href="dgui_datamodel_basics.html#topic.multitype">a value can
have multiple types</a>, it is possible for a value to be both a
hash and a sequence, in which case it would support index-based
access as well as access by lookup name. However, typically a
container will be either a hash or a sequence, not both.</p>
<p>As the value of the variables stored in hashes and sequences
(and collections) can be anything, it can be a hash or sequence (or
collection) as well. This way you can build arbitrarily deep
structures.</p>
<p>The data-model itself (or better said the root of it) is a
hash.</p>
<p>FreeMarker templates don&#39;t support modifying the contents of
containers (such as adding, removing or replacing sub variables),
and it assumes that their content won&#39;t change during template
processing. (But you can make new container values by adding
together two existing container values with <code class="inline-code">+</code>;
see that in the <a href="dgui_template_exp.html#exp_cheatsheet">chapter about
expressions</a>, and please note the performance
consequences.)</p>
<h2 class="content-header header-section2" id="autoid_11">Subroutines</h2>
<h3 class="content-header header-section3" id="dgui_datamodel_method">Methods and functions</h3>
<a name="topic.designer.methodVariable"></a>
<p>A value that is a method or a function is used to calculate
another value, influenced by the parameters you give to it.</p>
<p><span class="marked-for-programmers">For programmer types:
Methods/functions are first-class values, just like in functional
programming languages. This means that functions/methods can be
the parameters or return values of other functions/methods, you
can assign them to variables, and so on.</span></p>
<p>Suppose that programmers have put the method variable
<code class="inline-code">avg</code> in the data-model that can be used to
calculate the average of numbers. If you give the 3 and 5 as
parameters when you access <code class="inline-code">avg</code>, then you get
the value 4.</p>
<p>The usage of methods will be explained <a href="dgui_template_exp.html#dgui_template_exp_methodcall">later</a>, but perhaps
this example helps to understand what methods are:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">The average of 3 and 5 is: ${avg(3, 5)}
The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
The average of the price of a python and an elephant is:
${avg(animals.python.price, animals.elephant.price)}</pre> </div>
<p>this will output:</p>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">The average of 3 and 5 is: 4
The average of 6 and 10 and 20 is: 12
The average of the price of a python and an elephant is:
4999.5</pre> </div>
<p>What is the difference between a method and a function? As
far as the template author is concerned, nothing. Well not really
nothing, as methods typically come from the data-model (<span class="marked-for-programmers">as they reflect the methods of Java
objects</span>), and functions are defined in templates (with
the <a href="ref_directive_function.html#ref.directive.function"><code>function</code>
directive</a> -- an advanced topic), but both can be used on
the same way.</p>
<h3 class="content-header header-section3" id="dgui_datamodel_userdefdir">User-defined directives</h3>
<p>A value of this type can be used as user-defined directive
(with other words, as FreeMarker tag). An user-defined directive
is a subroutine, something like a little reusable template
fragment. But this is an advanced topic that will be explained
<a href="dgui_misc_userdefdir.html">later</a> in its own
chapter.</p>
<p><span class="marked-for-programmers">For programmer types:
user-defined directives (such as macros), are first-class values
too, just like functions/methods are.</span></p>
<p>Just to get an idea about user-defined directives (so just
ignore this if you won&#39;t understand), assume we have a variable,
<code class="inline-code">box</code>, whose value is a user-defined directive
that prints some kind of fancy HTML message box with a title bar
and a message in it. The <code class="inline-code">box</code> variable could be
used in the template like this (for example):</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;@<strong>box</strong> title=&quot;Attention!&quot;&gt;
Too much copy-pasting may leads to
maintenance headaches.
&lt;/@<strong>box</strong>&gt;</pre> </div>
<h3 class="content-header header-section3" id="autoid_12">Function/method versus user-defined directive</h3>
<p>This is for advanced users again (so ignore it if you don&#39;t
understand). It&#39;s a frequent dilemma if you should use a
function/method or an user-defined directive to implement
something. The rule of thumb is: Implement the facility as
user-defined directive instead of as function/method if:</p>
<ul>
<li>
<p>... the purpose of it is generating a piece of the
output that&#39;s not just a single value, and typically involves
markup. The template language was designed for printing to the
output directly, piece by piece, as it goes though
<code class="inline-code">list</code> loops, <code class="inline-code">if</code>-s, etc.
Building up a string value in a variable then returning it is
much less convenient.</p>
</li>
<li>
<p>... it&#39;s the side-effect that is important and not the
return value. For example, a directive whose purpose is to add
an entry to the server log is like that. (In fact you can&#39;t
have a return value for a user-defined directive, but some
kind of feedback is still possible by setting non-local
variables.)</p>
</li>
<li>
<p>... it will do flow control on the caller side (like for
example <code class="inline-code">list</code> or <code class="inline-code">if</code>
directives do). You just can&#39;t do that with a
function/method.</p>
</li>
<li>
<p>... you are using legacy escaping via the
<code class="inline-code">escape</code> directive (instead of <a href="dgui_misc_autoescaping.html">auto-escaping</a>), and
the result contains markup. When you print the result with
<code class="inline-code">${<em class="code-color">...</em>}</code>, the
markup will be escaped and thus ruined, but if it&#39;s printed by
a directive call
(<code class="inline-code">&lt;@<em class="code-color">...</em>&gt;</code>),
it won&#39;t be.</p>
</li>
</ul>
<p>The Java methods of FreeMarker-unaware Java objects are
normally visible as methods in templates, regardless of the nature
of the Java method; you have no choice there.</p>
<h2 class="content-header header-section2" id="autoid_13">Miscellaneous</h2>
<h3 class="content-header header-section3" id="dgui_datamodel_node">Nodes</h3>
<p>Node variables represent a node in a tree structure, and are
used mostly with <a href="xgui.html">XML processing</a>, which
is an advanced, and specialized topic.</p>
<p>Still, a quick overview <em>for advanced
users</em>: A node is similar to a sequence that stores
other nodes, which are often referred as the children nodes. A
node stores a reference to its container node, which is often
referred as the parent node. The main point of being a node is the
topological information; other data must be stored by utilizing
that a value can have multiple types. Like, a value may be both a
node and a number, in which case it can store a number as the
&quot;pay-load&quot;. Apart from the topological information, a node can
store some metainformation as well: a node name, a node type
(string), and a node namespace (string). For example, if the node
symbolizes a <code class="inline-code">h1</code> element in an XHTML document,
then its name could be <code class="inline-code">&quot;h1&quot;</code>, it&#39;s node type
could be <code class="inline-code">&quot;element&quot;</code>, and it&#39;s namespace could be
<code class="inline-code">&quot;http://www.w3.org/1999/xhtml&quot;</code>. But it&#39;s up to
the designer of the data-model if what meaning these
metainformations have, and if they are used at all. The way of
retrieving the topological and metainformations is described <a href="ref_builtins_node.html">in a later chapter</a> (that you
don&#39;t have to understand at this point).</p>
<h3 class="content-header header-section3" id="dgui_datamodel_markupoutput">Markup output</h3>
<p>This type is related to <a href="dgui_misc_autoescaping.html">auto-escaping mechanism</a>
introduced FreeMarker 2.3.24; you can <a href="dgui_misc_autoescaping.html#dgui_misc_autoescaping_movalues">read about this type
there</a>. But in short, this is a value that stores text
that&#39;s already in the output markup format (like HTML, XML, RTF,
etc.), and hence must not be auto-escaped.</p>
<p>Values of this type are usually produced inside the
templates (like with <a href="ref_builtins_string.html#ref_builtin_no_esc"><code>no_esc</code>
built-in</a> or <a href="ref_directive_assign.html">output
capturing assignments</a>), but can also be part of the
data-model. Such values in the data-model are useful for example
if you have message resources that sometimes contain the message
in HTML format, rather than in plain text. If the data-model uses
HTML markup output values for those messages instead of strings,
then the template author need not know which messages contain HTML
and which plain text, as double escaping will be avoided
automatically when the message is inserted with
<code class="inline-code">${<em class="code-color">...</em>}</code>.</p>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_datamodel_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2024
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p>
</div></div></div></body>
</html>