You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/03/13 10:58:09 UTC
[33/50] incubator-freemarker-site git commit: 2.3.26-nightly docs
preview
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/pgui_datamodel_directive.html
----------------------------------------------------------------------
diff --git a/builds/2.3.26-nightly/pgui_datamodel_directive.html b/builds/2.3.26-nightly/pgui_datamodel_directive.html
new file mode 100644
index 0000000..80af372
--- /dev/null
+++ b/builds/2.3.26-nightly/pgui_datamodel_directive.html
@@ -0,0 +1,411 @@
+<!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>Directives - 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="Directives">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://freemarker.org/docs/pgui_datamodel_directive.html">
+<link rel="canonical" href="http://freemarker.org/docs/pgui_datamodel_directive.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="http://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?1489402528979">
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-55420501-1', 'auto');
+ga('send', 'pageview');
+</script>
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://freemarker.org/docs/">
+ <meta itemprop="name" content="Apache FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker">
+</a><ul class="tabs"><li><a href="http://freemarker.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="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.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="searc
h-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"><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="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel.html"><span itemprop="name">The Data Model</span></a></li><li class="step-3" itempr
op="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel_directive.html"><span itemprop="name">Directives</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><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","Programmer\'s Guide","The Data Model","Directives"];</script>
+ <script src="toc.js?1489402528979"></script>
+ <script src="docgen-resources/main.min.js?1489402528979"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_datamodel_method.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_node.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="pgui_datamodel_directive" itemprop="headline">Directives</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#autoid_35" data-menu-target="autoid_35">Example 1</a></li><li><a class="page-menu-link" href="#autoid_36" data-menu-target="autoid_36">Example 2</a></li><li><a class="page-menu-link" href="#autoid_37" data-menu-target="autoid_37">Notices</a></li></ul> </div><p>Java programmers can implement user-defined directives in Java
+ using the <code class="inline-code">TemplateDirectiveModel</code> interface. See in
+ the API documentation.</p> <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p><code class="inline-code">TemplateDirectiveModel</code> was introduced in
+ FreeMarker 2.3.11, replacing the soon to be depreciated
+ <code class="inline-code">TemplateTransformModel</code>.</p>
+ </div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_35">Example 1</h2>
+
+
+ <p>We will implement a directive which converts all output
+ between its start-tag and end-tag to upper case. Like, this
+ template:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">foo
+<strong><@upper></strong>
+ bar
+ <#-- All kind of FTL is allowed here -->
+ <#list ["red", "green", "blue"] as color>
+ ${color}
+ </#list>
+ baaz
+<strong></@upper></strong>
+wombat</pre></div>
+
+ <p>will output this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">foo
+ BAR
+ RED
+ GREEN
+ BLUE
+ BAAZ
+wombat</pre></div>
+
+ <p>This is the source code of the directive class:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">package com.example;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+
+/**
+ * FreeMarker user-defined directive that progressively transforms
+ * the output of its nested content to upper-case.
+ *
+ *
+ * <p><b>Directive info</b></p>
+ *
+ * <p>Directive parameters: None
+ * <p>Loop variables: None
+ * <p>Directive nested content: Yes
+ */
+public class UpperDirective implements TemplateDirectiveModel {
+
+ public void execute(Environment env,
+ Map params, TemplateModel[] loopVars,
+ TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+ // Check if no parameters were given:
+ if (!params.isEmpty()) {
+ throw new TemplateModelException(
+ "This directive doesn't allow parameters.");
+ }
+ if (loopVars.length != 0) {
+ throw new TemplateModelException(
+ "This directive doesn't allow loop variables.");
+ }
+
+ // If there is non-empty nested content:
+ if (body != null) {
+ // Executes the nested body. Same as <#nested> in FTL, except
+ // that we use our own writer instead of the current output writer.
+ body.render(new UpperCaseFilterWriter(env.getOut()));
+ } else {
+ throw new RuntimeException("missing body");
+ }
+ }
+
+ /**
+ * A {@link Writer} that transforms the character stream to upper case
+ * and forwards it to another {@link Writer}.
+ */
+ private static class UpperCaseFilterWriter extends Writer {
+
+ private final Writer out;
+
+ UpperCaseFilterWriter (Writer out) {
+ this.out = out;
+ }
+
+ public void write(char[] cbuf, int off, int len)
+ throws IOException {
+ char[] transformedCbuf = new char[len];
+ for (int i = 0; i < len; i++) {
+ transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
+ }
+ out.write(transformedCbuf);
+ }
+
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ public void close() throws IOException {
+ out.close();
+ }
+ }
+
+}</pre></div>
+
+ <p>Now we still need to create an instance of this class, and
+ make this directive available to the template with the name "upper"
+ (or with whatever name we want) somehow. A possible solution is to
+ put the directive in the data-model:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">root.put("upper", new com.example.UpperDirective());</pre></div>
+
+ <p>But typically it is better practice to put commonly used
+ directives into the <code class="inline-code">Configuration</code> as <a href="pgui_config_sharedvariables.html">shared
+ variables</a>.</p>
+
+ <p>It is also possible to put the directive into an FTL library
+ (collection of macros and like in a template, that you
+ <code class="inline-code">include</code> or <code class="inline-code">import</code> in other
+ templates) using the <a href="ref_builtins_expert.html#ref_builtin_new"><code>new</code>
+ built-in</a>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#-- Maybe you have directives that you have implemented in FTL -->
+<#macro something>
+ ...
+</#macro>
+
+<#-- Now you can't use <#macro upper>, but instead you can: -->
+<#assign upper = "com.example.UpperDirective"?new()></pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_36">Example 2</h2>
+
+
+ <p>We will create a directive that executes its nested content
+ again and again for the specified number of times (similarly to
+ <code class="inline-code">list</code> directive), optionally separating the the
+ output of the repetations with a <code class="inline-code"><hr></code>-s.
+ Let's call this directive "repeat". Example template:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign x = 1>
+
+<strong><@repeat count=4></strong>
+ Test ${x}
+ <#assign x++>
+<strong></@repeat></strong>
+
+<strong><@repeat count=3 hr=true></strong>
+ Test
+<strong></@repeat></strong>
+
+<strong><@repeat count=3; cnt></strong>
+ ${cnt}. Test
+<strong></@repeat></strong></pre></div>
+
+ <p>Output:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> Test 1
+ Test 2
+ Test 3
+ Test 4
+
+ Test
+<hr> Test
+<hr> Test
+
+ 1. Test
+ 2. Test
+ 3. Test
+ </pre></div>
+
+ <p>The class:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">package com.example;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Map;
+
+import freemarker.core.Environment;
+import freemarker.template.SimpleNumber;
+import freemarker.template.TemplateBooleanModel;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateNumberModel;
+
+/**
+ * FreeMarker user-defined directive for repeating a section of a template,
+ * optionally with separating the output of the repetations with
+ * <tt>&lt;hr></tt>-s.
+ *
+ *
+ * <p><b>Directive info</b></p>
+ *
+ * <p>Parameters:
+ * <ul>
+ * <li><code>count</code>: The number of repetations. Required!
+ * Must be a non-negative number. If it is not a whole number then it will
+ * be rounded <em>down</em>.
+ * <li><code>hr</code>: Tells if a HTML "hr" element could be printed between
+ * repetations. Boolean. Optional, defaults to <code>false</code>.
+ * </ul>
+ *
+ * <p>Loop variables: One, optional. It gives the number of the current
+ * repetation, starting from 1.
+ *
+ * <p>Nested content: Yes
+ */
+public class RepeatDirective implements TemplateDirectiveModel {
+
+ private static final String PARAM_NAME_COUNT = "count";
+ private static final String PARAM_NAME_HR = "hr";
+
+ public void execute(Environment env,
+ Map params, TemplateModel[] loopVars,
+ TemplateDirectiveBody body)
+ throws TemplateException, IOException {
+
+ // ---------------------------------------------------------------------
+ // Processing the parameters:
+
+ int countParam = 0;
+ boolean countParamSet = false;
+ boolean hrParam = false;
+
+ Iterator paramIter = params.entrySet().iterator();
+ while (paramIter.hasNext()) {
+ Map.Entry ent = (Map.Entry) paramIter.next();
+
+ String paramName = (String) ent.getKey();
+ TemplateModel paramValue = (TemplateModel) ent.getValue();
+
+ if (paramName.equals(PARAM_NAME_COUNT)) {
+ if (!(paramValue instanceof TemplateNumberModel)) {
+ throw new TemplateModelException(
+ "The \"" + PARAM_NAME_HR + "\" parameter "
+ + "must be a number.");
+ }
+ countParam = ((TemplateNumberModel) paramValue)
+ .getAsNumber().intValue();
+ countParamSet = true;
+ if (countParam < 0) {
+ throw new TemplateModelException(
+ "The \"" + PARAM_NAME_HR + "\" parameter "
+ + "can't be negative.");
+ }
+ } else if (paramName.equals(PARAM_NAME_HR)) {
+ if (!(paramValue instanceof TemplateBooleanModel)) {
+ throw new TemplateModelException(
+ "The \"" + PARAM_NAME_HR + "\" parameter "
+ + "must be a boolean.");
+ }
+ hrParam = ((TemplateBooleanModel) paramValue)
+ .getAsBoolean();
+ } else {
+ throw new TemplateModelException(
+ "Unsupported parameter: " + paramName);
+ }
+ }
+ if (!countParamSet) {
+ throw new TemplateModelException(
+ "The required \"" + PARAM_NAME_COUNT + "\" paramter"
+ + "is missing.");
+ }
+
+ if (loopVars.length > 1) {
+ throw new TemplateModelException(
+ "At most one loop variable is allowed.");
+ }
+
+ // Yeah, it was long and boring...
+
+ // ---------------------------------------------------------------------
+ // Do the actual directive execution:
+
+ Writer out = env.getOut();
+ if (body != null) {
+ for (int i = 0; i < countParam; i++) {
+ // Prints a <hr> between all repetations if the "hr" parameter
+ // was true:
+ if (hrParam && i != 0) {
+ out.write("<hr>");
+ }
+
+ // Set the loop variable, if there is one:
+ if (loopVars.length > 0) {
+ loopVars[0] = new SimpleNumber(i + 1);
+ }
+
+ // Executes the nested body (same as <#nested> in FTL). In this
+ // case we don't provide a special writer as the parameter:
+ body.render(env.getOut());
+ }
+ }
+ }
+
+}</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_37">Notices</h2>
+
+
+ <p>It's important that a
+ <code class="inline-code">TemplateDirectiveModel</code> object usually should not
+ be stateful. The typical mistake is the storing of the state of the
+ directive call execution in the fields of the object. Think of
+ nested calls of the same directive, or directive objects used as
+ shared variables accessed by multiple threads concurrently.</p>
+
+ <p>Unfortunately, <code class="inline-code">TemplateDirectiveModel</code>-s
+ don't support passing parameters by position (rather than by name).
+ This is fixed starting from FreeMarker 2.4.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_datamodel_method.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_node.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="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">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></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href
="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://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="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 </p>
+<p class="copyright">
+� <span itemprop="copyrightYear">1999</span>\u20132017
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. </p>
+</div></div></div></body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/pgui_datamodel_method.html
----------------------------------------------------------------------
diff --git a/builds/2.3.26-nightly/pgui_datamodel_method.html b/builds/2.3.26-nightly/pgui_datamodel_method.html
new file mode 100644
index 0000000..172aeed
--- /dev/null
+++ b/builds/2.3.26-nightly/pgui_datamodel_method.html
@@ -0,0 +1,90 @@
+<!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>Methods - 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="Methods">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://freemarker.org/docs/pgui_datamodel_method.html">
+<link rel="canonical" href="http://freemarker.org/docs/pgui_datamodel_method.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="http://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?1489402528979">
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-55420501-1', 'auto');
+ga('send', 'pageview');
+</script>
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://freemarker.org/docs/">
+ <meta itemprop="name" content="Apache FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker">
+</a><ul class="tabs"><li><a href="http://freemarker.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="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.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="searc
h-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"><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="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel.html"><span itemprop="name">The Data Model</span></a></li><li class="step-3" itempr
op="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel_method.html"><span itemprop="name">Methods</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><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","Programmer\'s Guide","The Data Model","Methods"];</script>
+ <script src="toc.js?1489402528979"></script>
+ <script src="docgen-resources/main.min.js?1489402528979"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_datamodel_parent.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_directive.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="pgui_datamodel_method" itemprop="headline">Methods</h1>
+</div></div><p>Method variables exposed to a template implement the
+ <code class="inline-code">TemplateMethodModel</code> interface. This contains one
+ method: <code class="inline-code">TemplateModel exec(java.util.List
+ arguments)</code>. When you call a method with a <a href="dgui_template_exp.html#dgui_template_exp_methodcall">method call expression</a>,
+ then the <code class="inline-code">exec</code> method will be called. The arguments
+ parameter will contain the values of the FTL method call arguments.
+ The return value of <code class="inline-code">exec</code> gives the value of the FTL
+ method call expression.</p><p>The <code class="inline-code">TemplateMethodModelEx</code> interface extends
+ <code class="inline-code">TemplateMethodModel</code>. It does not add any new
+ methods. The fact that the object implements this
+ <em>marker</em> interface indicates to the FTL engine that
+ the arguments should be put to the <code class="inline-code">java.util.List</code>
+ directly as <code class="inline-code">TemplateModel</code>-s. Otherwise they will be
+ put to the list as <code class="inline-code">String</code>-s.</p><p>For obvious reasons there is no default implementation for these
+ interfaces.</p><p>Example: This is a method, which returns the index within the
+ second string of the first occurrence of the first string, or -1 if
+ the second string doesn't contains the first.</p>
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">public class IndexOfMethod implements TemplateMethodModel {
+
+ public TemplateModel exec(List args) throws TemplateModelException {
+ if (args.size() != 2) {
+ throw new TemplateModelException("Wrong arguments");
+ }
+ return new SimpleNumber(
+ ((String) args.get(1)).indexOf((String) args.get(0)));
+ }
+}</pre></div><p>If you put an instance of this, say, into the root:</p>
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">root.put("indexOf", new IndexOfMethod());</pre></div><p>then you can call it in the template:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign x = "something">
+${indexOf("met", x)}
+${indexOf("foo", x)}</pre></div><p>and then the output will be:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output">2
+-1</pre></div><p>If you need to access the runtime FTL environment (read/write
+ variables, get the current locale, etc.), you can get it with
+ <code class="inline-code">Environment.getCurrentEnvironment()</code>.</p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_datamodel_parent.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_directive.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="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">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></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href
="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://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="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 </p>
+<p class="copyright">
+� <span itemprop="copyrightYear">1999</span>\u20132017
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. </p>
+</div></div></div></body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/pgui_datamodel_node.html
----------------------------------------------------------------------
diff --git a/builds/2.3.26-nightly/pgui_datamodel_node.html b/builds/2.3.26-nightly/pgui_datamodel_node.html
new file mode 100644
index 0000000..e00919a
--- /dev/null
+++ b/builds/2.3.26-nightly/pgui_datamodel_node.html
@@ -0,0 +1,123 @@
+<!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>Node variables - 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="Node variables">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://freemarker.org/docs/pgui_datamodel_node.html">
+<link rel="canonical" href="http://freemarker.org/docs/pgui_datamodel_node.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="http://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?1489402528979">
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-55420501-1', 'auto');
+ga('send', 'pageview');
+</script>
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://freemarker.org/docs/">
+ <meta itemprop="name" content="Apache FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker">
+</a><ul class="tabs"><li><a href="http://freemarker.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="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.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="searc
h-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"><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="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel.html"><span itemprop="name">The Data Model</span></a></li><li class="step-3" itempr
op="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel_node.html"><span itemprop="name">Node variables</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><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","Programmer\'s Guide","The Data Model","Node variables"];</script>
+ <script src="toc.js?1489402528979"></script>
+ <script src="docgen-resources/main.min.js?1489402528979"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_datamodel_directive.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_objectWrapper.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="pgui_datamodel_node" itemprop="headline">Node variables</h1>
+</div></div><p>A node variable embodies a node in a tree structure. Node
+ variables were introduced to help <a href="xgui.html">the handling of
+ XML documents in the data-model</a>, but they can be used for the
+ modeling of other tree structures as well. For more information about
+ nodes from the point of view of the template language <a href="dgui_datamodel_types.html#dgui_datamodel_node">read this earlier section</a>.</p><p>A node variable has the following properties, provided by the
+ methods of <code class="inline-code">TemplateNodeModel</code> interface:</p><ul>
+ <li>
+ <p>Basic properties:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">TemplateSequenceModel
+ getChildNodes()</code>: A node has sequence of children
+ (except if the node is a leaf node, in which case the method
+ return an empty sequence or null). The child nodes should be
+ node variables as well.</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">TemplateNodeModel getParentNode()</code>: A
+ node has exactly 1 parent node, except if the node is root
+ node of the tree, in which case the method returns
+ <code class="inline-code">null</code>.</p>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <p>Optional properties. If a property does not make sense in
+ the concrete use case, the corresponding method should return
+ <code class="inline-code">null</code>:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">String getNodeName()</code>: The node name
+ is the name of the macro, that handles the node when you use
+ <a href="ref_directive_visit.html#ref.directive.recurse"><code>recurse</code></a>
+ and <a href="ref_directive_visit.html#ref.directive.visit"><code>visit</code></a>
+ directives. Thus, if you want to use these directives with the
+ node, the node name is <em>required</em>.</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">String getNodeType()</code>: In the case of
+ XML: <code class="inline-code">"element"</code>, <code class="inline-code">"text"</code>,
+ <code class="inline-code">"comment"</code>, ...etc. This information, if
+ available, is used by the <code class="inline-code">recurse</code> and
+ <code class="inline-code">visit</code> directives to find the default
+ handler macro for a node. Also it can be useful for other
+ application specific purposes.</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">String getNamespaceURI()</code>: The node
+ namespace (has nothing to do with FTL namespaces used for
+ libraries) this node belongs to. For example, in the case of
+ XML, this is the URI of the XML namespace the element or
+ attribute belongs to. This information, if available, is used
+ by the <code class="inline-code">recurse</code> and <code class="inline-code">visit</code>
+ directives to find the FTL namespaces that store the handler
+ macros.</p>
+ </li>
+ </ul>
+ </li>
+ </ul><p>On the FTL side, the direct utilization of node properties is
+ done with <a href="ref_builtins_node.html">node built-ins</a>, and
+ with the <code class="inline-code">visit</code> and <code class="inline-code">recurse</code>
+ macros.</p><p>In most use cases, variables that implement
+ <code class="inline-code">TemplateNodeModel</code>, implement other interfaces as
+ well, since node variable properties just provide the basic
+ infrastructure for navigating between nodes. For a concrete example,
+ see <a href="xgui.html">how FreeMarker deals with XML</a>.</p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_datamodel_directive.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_objectWrapper.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="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">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></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href
="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://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="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 </p>
+<p class="copyright">
+� <span itemprop="copyrightYear">1999</span>\u20132017
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. </p>
+</div></div></div></body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/pgui_datamodel_objectWrapper.html
----------------------------------------------------------------------
diff --git a/builds/2.3.26-nightly/pgui_datamodel_objectWrapper.html b/builds/2.3.26-nightly/pgui_datamodel_objectWrapper.html
new file mode 100644
index 0000000..ead2dd9
--- /dev/null
+++ b/builds/2.3.26-nightly/pgui_datamodel_objectWrapper.html
@@ -0,0 +1,412 @@
+<!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>Object wrappers - 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="Object wrappers">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://freemarker.org/docs/pgui_datamodel_objectWrapper.html">
+<link rel="canonical" href="http://freemarker.org/docs/pgui_datamodel_objectWrapper.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="http://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?1489402528979">
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-55420501-1', 'auto');
+ga('send', 'pageview');
+</script>
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://freemarker.org/docs/">
+ <meta itemprop="name" content="Apache FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker">
+</a><ul class="tabs"><li><a href="http://freemarker.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="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.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="searc
h-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"><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="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel.html"><span itemprop="name">The Data Model</span></a></li><li class="step-3" itempr
op="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel_objectWrapper.html"><span itemprop="name">Object wrappers</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><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","Programmer\'s Guide","The Data Model","Object wrappers"];</script>
+ <script src="toc.js?1489402528979"></script>
+ <script src="docgen-resources/main.min.js?1489402528979"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_datamodel_node.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_config.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="pgui_datamodel_objectWrapper" itemprop="headline">Object wrappers</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#pgui_datamodel_defaultObjectWrapper" data-menu-target="pgui_datamodel_defaultObjectWrapper">The default object wrapper</a></li><li><a class="page-menu-link" href="#pgui_datamodel_customObjectWrappingExample" data-menu-target="pgui_datamodel_customObjectWrappingExample">Custom object wrapping example</a></li></ul> </div><p>The object wrapper is an object that implements the
+ <code class="inline-code">freemarker.template.ObjectWrapper</code> interface. It's
+ purpose is to implement a mapping between Java objects (like
+ <code class="inline-code">String</code>-s, <code class="inline-code">Map</code>-s,
+ <code class="inline-code">List</code>-s, instances of your application specific
+ classes, etc.) and FTL's type system. With other words, it specifies
+ how the templates will see the Java objects of the data-model
+ (including the return value of Java methods called from the template).
+ The object wrapper is plugged into the
+ <code class="inline-code">Configuration</code> as its
+ <code class="inline-code">object_wrapper</code> setting (or with
+ <code class="inline-code">Configuration.setObjectWrapper</code>).</p><p>FTL's type system is technically represented by the
+ <code class="inline-code">TemplateModel</code> sub-interfaces that were introduced
+ earlier (<code class="inline-code">TemplateScalarModel</code>,
+ <code class="inline-code">TemplateHashMode</code>,
+ <code class="inline-code">TemplateSequenceModel</code>, etc). To map a Java object
+ to FTL's type system, object wrapper's <code class="inline-code">TemplateModel
+ wrap(java.lang.Object obj)</code> method will be called.</p><p>Sometimes FreeMarker needs to reverse this mapping, in which
+ case the <code class="inline-code">ObjectWrapper</code>'s <code class="inline-code">Object
+ unwrap(TemplateModel)</code> method is called (or some other
+ variation of that, but see the API documentation for such details).
+ This last operation is in
+ <code class="inline-code">ObjectWrapperAndUnwrapper</code>, the subinterface of
+ <code class="inline-code">ObjectWrapper</code>. Most real world object wrappers will
+ implement <code class="inline-code">ObjectWrapperAndUnwrapper</code>.</p><p>Here's how wrapping Java objects that contain other objects
+ (like a <code class="inline-code">Map</code>, a <code class="inline-code">List</code>, an array,
+ or an object with some JavaBean properties) usually work. Let's say,
+ an object wrapper wraps an <code class="inline-code">Object[]</code> array into some
+ implementation of the <code class="inline-code">TemplateSquenceModel</code>
+ interface. When FreeMarker needs an item from that FTL sequence, it
+ will call <code class="inline-code">TemplateSquenceModel.get(int index)</code>. The
+ return type of this method is <code class="inline-code">TemplateModel</code>, that
+ is, the <code class="inline-code">TemplateSquenceModel</code> implementation not
+ only have to get the <code class="inline-code">Object</code> from the given index of
+ the array, it's also responsible for wrapping that value before
+ returning it. To solve that, a typical
+ <code class="inline-code">TemplateSquenceModel</code> implementation will store the
+ <code class="inline-code">ObjectWrapper</code> that has cerated it, and then invoke
+ that <code class="inline-code">ObjectWrapper</code> to wrap the contained value. The
+ same logic stands for <code class="inline-code">TemplateHashModel</code> or for any
+ other <code class="inline-code">TemplateModel</code> that's a container for further
+ <code class="inline-code">TemplateModel</code>-s. Hence, usually, no mater how deep
+ the value hierarchy is, all values will be wrapped by the same single
+ <code class="inline-code">ObjectWrapper</code>. (To create
+ <code class="inline-code">TemplateModel</code> implementations that follow this
+ idiom, you can use the
+ <code class="inline-code">freemarker.template.WrappingTemplateModel</code> as base
+ class.)</p><p>The data-model itself (the root variable) is a
+ <code class="inline-code">TemplateHashModel</code>. The root object that you specify
+ to <code class="inline-code">Template.process</code> will be wrapped with the object
+ wrapper specified in the <code class="inline-code">object_wrapper</code>
+ configuration setting, which must yield a
+ <code class="inline-code">TemplateHashModel</code>. From then on, the wrapping of
+ the contained values follow the logic described earlier (i.e., the
+ container is responsible for wrapping its children).</p><p>Well behaving object wrappers bypass objects that already
+ implement <code class="inline-code">TemplateModel</code> as is. So if you put an
+ object into the data-model that already implements
+ <code class="inline-code">TemplateModel</code> (or you return as such object from a
+ Java method that's called from the template, etc.), then you can avoid
+ actual object wrapping. You do this usually when you are creating a
+ value specifically to be accessed from a template. Thus, you avoid
+ much of the object wrapping performance overhead, also you can control
+ exactly what will the template see (not depending on the mapping
+ strategy of the current object wrapper). A frequent application of
+ this trick is using a
+ <code class="inline-code">freemarker.template.SimpleHash</code> as the data-model
+ root (rather than a <code class="inline-code">Map</code>), by filling it with
+ <code class="inline-code">SimpleHash</code>'s <code class="inline-code">put</code> method (that's
+ important, so it won't have to copy an existing <code class="inline-code">Map</code>
+ that you have already filled). This speeds up top-level data-model
+ variable access.</p>
+
+
+
+
+<h2 class="content-header header-section2" id="pgui_datamodel_defaultObjectWrapper">The default object wrapper</h2>
+
+
+
+
+
+
+ <p>The default of the <code class="inline-code">object_wrapper</code>
+ <code class="inline-code">Configuration</code> setting is a
+ <code class="inline-code">freemarker.template.DefaultObjectWrapper</code>
+ singleton. Unless you have very special requirements, it's
+ recommended to use this object wrapper, or an instance of a
+ <code class="inline-code">DefaultObjectWrapper</code> subclass of yours.</p>
+
+ <p>It recognizes most basic Java types, like
+ <code class="inline-code">String</code>, <code class="inline-code">Number</code>,
+ <code class="inline-code">Boolean</code>, <code class="inline-code">Date</code>,
+ <code class="inline-code">List</code> (and in general all kind of
+ <code class="inline-code">java.util.Collection</code>-s), arrays,
+ <code class="inline-code">Map</code>, etc., and wraps them into the naturally
+ matching <code class="inline-code">TemplateModel</code> interfaces. It will also
+ wrap W3C DOM nodes with
+ <code class="inline-code">freemarker.ext.dom.NodeModel</code>, so you can
+ conveniently traverse XML as <a href="xgui.html">described in its
+ own chapter</a>). For Jython objects, it will delegate to
+ <code class="inline-code">freemarker.ext.jython.JythonWrapper</code>. For all
+ other objects, it will invoke <code class="inline-code">BeansWrapper.wrap</code>
+ (the super class's method), which will expose the JavaBean
+ properties of the objects as hash items (like
+ <code class="inline-code">myObj.foo</code> in FTL will call
+ <code class="inline-code">getFoo()</code> behind the scenes), and will also expose
+ the public methods (JavaBean actions) of the object (like
+ <code class="inline-code">myObj.bar(1, 2)</code> in FTL will call a method). (For
+ more information about BeansWrapper, <a href="pgui_misc_beanwrapper.html">see its own section</a>.)</p>
+
+ <p>Some further details that's worth mentioning about
+ <code class="inline-code">DefaultObjectWrapper</code>:</p>
+
+ <ul>
+ <li>
+ <p>You shouldn't use its constructor usually, instead create
+ it using a <code class="inline-code">DefaultObjectWrapperBuilder</code>. This
+ allows FreeMarker to use singletons.</p>
+ </li>
+
+ <li>
+ <p><a name="topic.defaultObjectWrapperIcI"></a><code class="inline-code">DefaultObjectWrapper</code> has an
+ <code class="inline-code">incompatibleImprovements</code> property, that's
+ highly recommended to set to 2.3.22 or higher (see the <a href="http://freemarker.org/docs/api/freemarker/template/DefaultObjectWrapper.html#DefaultObjectWrapper-freemarker.template.Version-">API
+ documentation</a> for the effects). How to set it:</p>
+
+ <ul>
+ <li>
+ <p>If you have set the
+ <code class="inline-code">incompatible_improvements</code> setting
+ <em>of the <code class="inline-code">Configuration</code></em>
+ to 2.3.22 or higher, and you didn't set the
+ <code class="inline-code">object_wrapper</code> setting (so it had
+ remained on its default value), then you have to do nothing,
+ as it already uses a <code class="inline-code">DefaultObjectWrapper</code>
+ singleton with the equivalent
+ <code class="inline-code">incompatibleImprovements</code> property
+ value.</p>
+ </li>
+
+ <li>
+ <p><a name="topic.setDefaultObjectWrapperIcIIndividually"></a>Otherwise you have to set the
+ <code class="inline-code">incompatibleImprovements</code> independently of
+ the <code class="inline-code">Configuration</code>. Depending on how you
+ create/set the <code class="inline-code">ObjectWrapper</code>, it can be
+ done like this:</p>
+
+ <ul>
+ <li>
+ <p>If you are using the builder API:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">... = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build()</pre></div>
+ </li>
+
+ <li>
+ <p>Or, if you are using the constructor:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">... = new DefaultObjectWrapper(Configuration.VERSION_2_3_25)</pre></div>
+ </li>
+
+ <li>
+ <p>Or, if you are using the
+ <code class="inline-code">object_wrapper</code> property
+ (<code class="inline-code">*.properties</code> file or
+ <code class="inline-code">java.util.Properties</code> object):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">object_wrapper=DefaultObjectWrapper(2.3.25)</pre></div>
+ </li>
+
+ <li>
+ <p>Or, if you are configuring the
+ <code class="inline-code">object_wrapper</code> through a
+ <code class="inline-code">FreemarkerServlet</code> with an
+ <code class="inline-code">init-param</code> in
+ <code class="inline-code">web.xml</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified"><init-param>
+ <param-name>object_wrapper</param-name>
+ <param-value>DefaultObjectWrapper(2.3.25)</param-value>
+</init-param></pre></div>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <p>In new or properly test-covered projects it's also
+ recommended to set the
+ <code class="inline-code">forceLegacyNonListCollections</code> property to
+ <code class="inline-code">false</code>. If you are using
+ <code class="inline-code">.properties</code> or
+ <code class="inline-code">FreemarkerServlet</code> init-params or such, that
+ will look like <code class="inline-code">DefaultObjectWrapper(2.3.22,
+ forceLegacyNonListCollections=false)</code>, while with the
+ Java API you call
+ <code class="inline-code">setForceLegacyNonListCollections(false)</code> on
+ the <code class="inline-code">DefaultObjectWrapperBuilder</code> object before
+ calling <code class="inline-code">build()</code>.</p>
+ </li>
+
+ <li>
+ <p>The most common way of customizing
+ <code class="inline-code">DefaultObjectWrapper</code> is overriding its
+ <code class="inline-code">handleUnknownType</code> method.</p>
+ </li>
+ </ul>
+
+
+
+
+
+<h2 class="content-header header-section2" id="pgui_datamodel_customObjectWrappingExample">Custom object wrapping example</h2>
+
+
+
+
+
+
+
+
+ <p>Let's say you have an application-specific class like
+ this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">package com.example.myapp;
+
+public class Tupple<E1, E2> {
+ public Tupple(E1 e1, E2 e2) { ... }
+ public E1 getE1() { ... }
+ public E2 getE2() { ... }
+}</pre></div>
+
+ <p>You want templates to see this as a sequence of length 2, so
+ that you can do things like <code class="inline-code">someTupple[1]</code>,
+ <code class="inline-code"><#list someTupple
+ <em class="code-color">...</em>></code>, or
+ <code class="inline-code">someTupple?size</code>. For that you need to create a
+ <code class="inline-code">TemplateSequenceModel</code> implementation that adapts
+ a <code class="inline-code">Tupple</code> to the
+ <code class="inline-code">TempateSequenceMoldel</code> interface:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">package com.example.myapp.freemarker;
+
+...
+
+public class TuppleAdapter extends WrappingTemplateModel implements TemplateSequenceModel,
+ AdapterTemplateModel {
+
+ private final Tupple<?, ?> tupple;
+
+ public TuppleAdapter(Tupple<?, ?> tupple, ObjectWrapper ow) {
+ super(ow); // coming from WrappingTemplateModel
+ this.tupple = tupple;
+ }
+
+ @Override // coming from TemplateSequenceModel
+ public int size() throws TemplateModelException {
+ return 2;
+ }
+
+ @Override // coming from TemplateSequenceModel
+ public TemplateModel get(int index) throws TemplateModelException {
+ switch (index) {
+ case 0: return wrap(tupple.getE1());
+ case 1: return wrap(tupple.getE2());
+ default: return null;
+ }
+ }
+
+ @Override // coming from AdapterTemplateModel
+ public Object getAdaptedObject(Class hint) {
+ return tupple;
+ }
+
+}</pre></div>
+
+ <p>Regarding the classes and interfaces:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">TemplateSequenceModel</code>: This is why the
+ template will see this as a sequence</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">WrappingTemplateModel</code>: Just a
+ convenience class, used for <code class="inline-code">TemplateModel</code>-s
+ that do object wrapping themselves. That's normally only needed
+ for objects that contain other objects. See the
+ <code class="inline-code">wrap(<em class="code-color">...</em>)</code> calls
+ above.</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">AdapterTemplateModel</code>: Indicates that
+ this template model adapts an already existing object to a
+ <code class="inline-code">TemplateModel</code> interface, thus unwrapping
+ should give back that original object.</p>
+ </li>
+ </ul>
+
+ <p>Lastly, we tell FreeMarker to wrap <code class="inline-code">Tupple</code>-s
+ with the <code class="inline-code">TuppleAdapter</code> (alternatively, you could
+ wrap them manually before passing them to FreeMarker). For that,
+ first we create a custom object wrapper:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">package com.example.myapp.freemarker;
+
+...
+
+public class MyAppObjectWrapper extends DefaultObjectWrapper {
+
+ public MyAppObjectWrapper(Version incompatibleImprovements) {
+ super(incompatibleImprovements);
+ }
+
+ @Override
+ protected TemplateModel handleUnknownType(final Object obj) throws TemplateModelException {
+ if (obj instanceof Tupple) {
+ return new TuppleAdapter((Tupple<?, ?>) obj, this);
+ }
+
+ return super.handleUnknownType(obj);
+ }
+
+}</pre></div>
+
+ <p>and then where you configure FreeMarker (<a href="pgui_config.html">about configuring, see here...</a>) we plug
+ our object wrapper in:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">// Where you initialize the cfg *singleton* (happens just once in the application life-cycle):
+cfg = new Configuration(Configuration.VERSION_2_3_25);
+...
+cfg.setObjectWrapper(new MyAppObjectWrapper(cfg.getIncompatibleImprovements()));</pre></div>
+
+ <p>or if you are configuring FreeMarker with
+ <code class="inline-code">java.util.Properties</code> instead (and let's say it's
+ also a <code class="inline-code">.properties</code> file):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">object_wrapper=com.example.myapp.freemarker.MyAppObjectWrapper(2.3.25)</pre></div>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_datamodel_node.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_config.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="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">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></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href
="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://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="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 </p>
+<p class="copyright">
+� <span itemprop="copyrightYear">1999</span>\u20132017
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. </p>
+</div></div></div></body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/pgui_datamodel_parent.html
----------------------------------------------------------------------
diff --git a/builds/2.3.26-nightly/pgui_datamodel_parent.html b/builds/2.3.26-nightly/pgui_datamodel_parent.html
new file mode 100644
index 0000000..6c91a9b
--- /dev/null
+++ b/builds/2.3.26-nightly/pgui_datamodel_parent.html
@@ -0,0 +1,129 @@
+<!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>Containers - 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="Containers">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://freemarker.org/docs/pgui_datamodel_parent.html">
+<link rel="canonical" href="http://freemarker.org/docs/pgui_datamodel_parent.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="http://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?1489402528979">
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-55420501-1', 'auto');
+ga('send', 'pageview');
+</script>
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://freemarker.org/docs/">
+ <meta itemprop="name" content="Apache FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker">
+</a><ul class="tabs"><li><a href="http://freemarker.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="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.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="searc
h-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"><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="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel.html"><span itemprop="name">The Data Model</span></a></li><li class="step-3" itempr
op="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_datamodel_parent.html"><span itemprop="name">Containers</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><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","Programmer\'s Guide","The Data Model","Containers"];</script>
+ <script src="toc.js?1489402528979"></script>
+ <script src="docgen-resources/main.min.js?1489402528979"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_datamodel_scalar.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_method.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="pgui_datamodel_parent" itemprop="headline">Containers</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#autoid_32" data-menu-target="autoid_32">Hashes</a></li><li><a class="page-menu-link" href="#autoid_33" data-menu-target="autoid_33">Sequences</a></li><li><a class="page-menu-link" href="#autoid_34" data-menu-target="autoid_34">Collections</a></li></ul> </div><p>These are hashes, sequences, and collections.</p>
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_32">Hashes</h2>
+
+
+
+
+ <p>Hashes are java objects that implement
+ <code class="inline-code">TemplateHashModel</code> interface.
+ <code class="inline-code">TemplateHashModel</code> contains two methods:
+ <code class="inline-code">TemplateModel get(String key)</code>, which returns the
+ subvariable of the given name, and <code class="inline-code">boolean
+ isEmpty()</code>, which indicates if the hash has zero
+ subvariable or not. The <code class="inline-code">get</code> method returns null
+ if no subvariable with the given name exists.</p>
+
+ <p>The <code class="inline-code">TemplateHashModelEx</code> interface extends
+ <code class="inline-code">TemplateHashModel</code>. It adds methods by which <a href="ref_builtins_hash.html#ref_builtin_values">values</a> and <a href="ref_builtins_hash.html#ref_builtin_keys">keys</a> built-ins can enumerate the
+ sub variables of the hash.</p>
+
+ <p>The commonly used implementation is
+ <code class="inline-code">SimpleHash</code>, which implements
+ <code class="inline-code">TemplateHashModelEx</code>. Internally it uses a
+ <code class="inline-code">java.util.Hash</code> to store the sub variables.
+ <code class="inline-code">SimpleHash</code> has methods by which you can add and
+ remove subvariable. These methods should be used to initialize the
+ variable directly after its creation.</p>
+
+ <p>Containers are immutable within FTL. That is, you can't add,
+ replace or remove the sub variables they contain.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_33">Sequences</h2>
+
+
+
+
+ <p>Sequences are java objects that implement
+ <code class="inline-code">TemplateSequenceModel</code>. It contains two methods:
+ <code class="inline-code">TemplateModel get(int index)</code> and <code class="inline-code">int
+ size()</code>.</p>
+
+ <p>The commonly used implementation is
+ <code class="inline-code">SimpleSequence</code>. It uses internally a
+ <code class="inline-code">java.util.List</code> to store its sub variables.
+ <code class="inline-code">SimpleSequence</code> has methods by which you can add
+ sub variables. These methods should be used to populate the sequence
+ directly after its creation.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_34">Collections</h2>
+
+
+
+
+ <p>Collections are java objects that implement the
+ <code class="inline-code">TemplateCollectionModel</code> interface. That interface
+ has one method: <code class="inline-code">TemplateModelIterator iterator()</code>.
+ The <code class="inline-code">TemplateModelIterator</code> interface is similar to
+ <code class="inline-code">java.util.Iterator</code>, but it returns
+ <code class="inline-code">TemplateModels</code> instead of
+ <code class="inline-code">Object</code>-s, and it can throw
+ <code class="inline-code">TemplateModelException</code>s.</p>
+
+ <p>The commonly used implementation is
+ <code class="inline-code">SimpleCollection</code>.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_datamodel_scalar.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_datamodel_method.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="http://freemarker.org/">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">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></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href
="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://issues.apache.org/jira/browse/FREEMARKER/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://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="2017-03-13T10:55:28Z" title="Monday, March 13, 2017 10:55:28 AM GMT">2017-03-13 10:55:28 GMT</time>, for Freemarker 2.3.26 </p>
+<p class="copyright">
+� <span itemprop="copyrightYear">1999</span>\u20132017
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. </p>
+</div></div></div></body>
+</html>