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&#39;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>&lt;@upper&gt;</strong>
+  bar
+  &lt;#-- All kind of FTL is allowed here --&gt;
+  &lt;#list [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;] as color&gt;
+    ${color}
+  &lt;/#list&gt;
+  baaz
+<strong>&lt;/@upper&gt;</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.
+ *
+ *
+ *  &lt;p&gt;&lt;b&gt;Directive info&lt;/b&gt;&lt;/p&gt;
+ *
+ *  &lt;p&gt;Directive parameters: None
+ *  &lt;p&gt;Loop variables: None
+ *  &lt;p&gt;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(
+                    &quot;This directive doesn&#39;t allow parameters.&quot;);
+        }
+        if (loopVars.length != 0) {
+                throw new TemplateModelException(
+                    &quot;This directive doesn&#39;t allow loop variables.&quot;);
+        }
+
+        // If there is non-empty nested content:
+        if (body != null) {
+            // Executes the nested body. Same as &lt;#nested&gt; 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(&quot;missing body&quot;);
+        }
+    }
+
+    /**
+     * 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 &lt; 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 &quot;upper&quot;
+          (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(&quot;upper&quot;, 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">&lt;#-- Maybe you have directives that you have implemented in FTL --&gt;
+&lt;#macro something&gt;
+  ...
+&lt;/#macro&gt;
+
+&lt;#-- Now you can&#39;t use &lt;#macro upper&gt;, but instead you can: --&gt;
+&lt;#assign upper = &quot;com.example.UpperDirective&quot;?new()&gt;</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">&lt;hr&gt;</code>-s.
+          Let&#39;s call this directive &quot;repeat&quot;. Example template:</p>
+
+          
+
+<div class="code-wrapper"><pre class="code-block code-template">&lt;#assign x = 1&gt;
+
+<strong>&lt;@repeat count=4&gt;</strong>
+  Test ${x}
+  &lt;#assign x++&gt;
+<strong>&lt;/@repeat&gt;</strong>
+
+<strong>&lt;@repeat count=3 hr=true&gt;</strong>
+  Test
+<strong>&lt;/@repeat&gt;</strong>
+
+<strong>&lt;@repeat count=3; cnt&gt;</strong>
+  ${cnt}. Test
+<strong>&lt;/@repeat&gt;</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
+&lt;hr&gt;  Test
+&lt;hr&gt;  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
+ * &lt;tt&gt;&amp;lt;hr&gt;&lt;/tt&gt;-s.
+ *
+ *
+ * &lt;p&gt;&lt;b&gt;Directive info&lt;/b&gt;&lt;/p&gt;
+ *
+ * &lt;p&gt;Parameters:
+ * &lt;ul&gt;
+ *   &lt;li&gt;&lt;code&gt;count&lt;/code&gt;: The number of repetations. Required!
+ *       Must be a non-negative number. If it is not a whole number then it will
+ *       be rounded &lt;em&gt;down&lt;/em&gt;.
+ *   &lt;li&gt;&lt;code&gt;hr&lt;/code&gt;: Tells if a HTML &quot;hr&quot; element could be printed between
+ *       repetations. Boolean. Optional, defaults to &lt;code&gt;false&lt;/code&gt;.
+ * &lt;/ul&gt;
+ *
+ * &lt;p&gt;Loop variables: One, optional. It gives the number of the current
+ *    repetation, starting from 1.
+ *
+ * &lt;p&gt;Nested content: Yes
+ */
+public class RepeatDirective implements TemplateDirectiveModel {
+
+    private static final String PARAM_NAME_COUNT = &quot;count&quot;;
+    private static final String PARAM_NAME_HR = &quot;hr&quot;;
+
+    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(
+                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
+                            + &quot;must be a number.&quot;);
+                }
+                countParam = ((TemplateNumberModel) paramValue)
+                        .getAsNumber().intValue();
+                countParamSet = true;
+                if (countParam &lt; 0) {
+                    throw new TemplateModelException(
+                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
+                            + &quot;can&#39;t be negative.&quot;);
+                }
+            } else if (paramName.equals(PARAM_NAME_HR)) {
+                if (!(paramValue instanceof TemplateBooleanModel)) {
+                    throw new TemplateModelException(
+                            &quot;The \&quot;&quot; + PARAM_NAME_HR + &quot;\&quot; parameter &quot;
+                            + &quot;must be a boolean.&quot;);
+                }
+                hrParam = ((TemplateBooleanModel) paramValue)
+                        .getAsBoolean();
+            } else {
+                throw new TemplateModelException(
+                        &quot;Unsupported parameter: &quot; + paramName);
+            }
+        }
+        if (!countParamSet) {
+                throw new TemplateModelException(
+                        &quot;The required \&quot;&quot; + PARAM_NAME_COUNT + &quot;\&quot; paramter&quot;
+                        + &quot;is missing.&quot;);
+        }
+
+        if (loopVars.length &gt; 1) {
+                throw new TemplateModelException(
+                        &quot;At most one loop variable is allowed.&quot;);
+        }
+
+        // Yeah, it was long and boring...
+
+        // ---------------------------------------------------------------------
+        // Do the actual directive execution:
+
+        Writer out = env.getOut();
+        if (body != null) {
+            for (int i = 0; i &lt; countParam; i++) {
+                // Prints a &lt;hr&gt; between all repetations if the &quot;hr&quot; parameter
+                // was true:
+                if (hrParam &amp;&amp; i != 0) {
+                    out.write(&quot;&lt;hr&gt;&quot;);
+                }
+
+                // Set the loop variable, if there is one:
+                if (loopVars.length &gt; 0) {
+                    loopVars[0] = new SimpleNumber(i + 1);
+                }
+
+                // Executes the nested body (same as &lt;#nested&gt; in FTL). In this
+                // case we don&#39;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&#39;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&#39;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&#39;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&#39;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(&quot;Wrong arguments&quot;);
+        }
+        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(&quot;indexOf&quot;, new IndexOfMethod());</pre></div><p>then you can call it in the template:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template">&lt;#assign x = &quot;something&quot;&gt;
+${indexOf(&quot;met&quot;, x)}
+${indexOf(&quot;foo&quot;, 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&#39;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">&quot;element&quot;</code>, <code class="inline-code">&quot;text&quot;</code>,
+                <code class="inline-code">&quot;comment&quot;</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&#39;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&#39;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&#39;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&#39;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&#39;s type system, object wrapper&#39;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>&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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>&#39;s <code class="inline-code">put</code> method (that&#39;s
+        important, so it won&#39;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&#39;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&#39;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&#39;s worth mentioning about
+          <code class="inline-code">DefaultObjectWrapper</code>:</p>
+
+          <ul>
+            <li>
+              <p>You shouldn&#39;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&#39;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&#39;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">&lt;init-param&gt;
+    &lt;param-name&gt;object_wrapper&lt;/param-name&gt;
+    &lt;param-value&gt;DefaultObjectWrapper(2.3.25)&lt;/param-value&gt;
+&lt;/init-param&gt;</pre></div>
+                    </li>
+                  </ul>
+                </li>
+              </ul>
+            </li>
+
+            <li>
+              <p>In new or properly test-covered projects it&#39;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&#39;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&lt;E1, E2&gt; {
+    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">&lt;#list someTupple
+          <em class="code-color">...</em>&gt;</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&lt;?, ?&gt; tupple;
+
+    public TuppleAdapter(Tupple&lt;?, ?&gt; 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&#39;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&lt;?, ?&gt;) 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&#39;s say it&#39;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&#39;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&#39;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>