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 2015/12/20 14:06:07 UTC
[1/5] incubator-freemarker git commit: Made place for the Chinese
manual.
Repository: incubator-freemarker
Updated Branches:
refs/heads/2.3-gae 41b6f8342 -> 731be2c28
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-help/editors-readme.txt
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-help/editors-readme.txt b/src/manual/en_US/docgen-help/editors-readme.txt
new file mode 100644
index 0000000..5280d97
--- /dev/null
+++ b/src/manual/en_US/docgen-help/editors-readme.txt
@@ -0,0 +1,105 @@
+Guide to FreeMarker Manual for Editors
+======================================
+
+Non-technical
+-------------
+
+- The Template Author's Guide is for Web designers. Assume that a
+ designer is not a programmer, (s)he doesn't even know what is Java.
+ Forget that FM is implemented in Java when you edit the Template
+ Author's Guide. Try to avoid technical writing.
+
+- In the Guide chapters, be careful not to mention things that were
+ not explained earlier. The Guide chapters should be understandable
+ if you read them continuously.
+
+- If you add a new topic or term, don't forget to add it to the Index.
+ Also, consider adding entries for it to the Glossary.
+
+- Don't use too sophisticated English. Use basic words and grammar.
+
+
+Technical
+---------
+
+- For the editing use XXE (XMLmind XML Editor), with its default XML
+ *source* formatting settings (identation, max line length and like).
+ You should install the "DocBook 5 for Freemarker" addon, which you can
+ find inside the "docgen" top-level SVN module.
+
+- The HTML is generated with Docgen (docgen.jar), which will check some
+ of the rules described here. To invoke it, issue "ant manual" from
+ the root of the "freemarker" module. (Note: you may need to check out
+ and build "docgen" first.)
+
+- Understand all document conventions in the Preface chapter. Note that
+ all "programlisting"-s should have a "role" attribute with a value that
+ is either: "template", "dataModel", "output", "metaTemplate" or
+ "unspecified". (If you miss this, the XXE addon will show the
+ "programlisting" in red.)
+
+- Verbatim content in flow text:
+
+ * In flow text, all data object names, class names, FTL fragments,
+ HTML fragments, and all other verbatim content is inside "literal"
+ element.
+
+ * Use replaceable element inside literal element for replaceable
+ parts and meta-variables like:
+ <literal<if <replaceable>condition</replaceable>></literal>
+ <literal><replaceable>templateDir</replaceable>/copyright.ftl</literal>
+
+- Hierarchy:
+
+ * The hierarchy should look like:
+
+ book -> part -> chapter -> section -> section -> section -> section
+
+ where the "part" and the "section"-s are optional.
+ Instead of chapter you may have "preface" or "appendix".
+
+ * Don't use "sect1", "sect2", etc. Instead nest "section"-s into each other,
+ but not deeper than 3 levels.
+
+ * Use "simplesect" if you want to divide up something visually, but
+ you don't want those sections to appear in the ToC, or go into their own
+ HTML page. "simplesect"-s can appear under all "section" nesting
+ levels, and they always look the same regardless of the "section"
+ nesting levels.
+
+- Lists:
+
+ * When you have list where the list items are short (a few words),
+ you should give spacing="compact" to the "itemizedlist" or
+ "orderedlist" element.
+
+ * Don't putting listings inside "para"-s. Put them between "para"-s instead.
+
+- Xrefs, id-s, links:
+
+ * id-s of parts, chapters, sections and similar elements must
+ contain US-ASCII lower case letters, US-ASCII numbers, and
+ underscore only. id-s of parts and chapters are used as the
+ filenames of HTML-s generated for that block.
+ When you find out the id, deduce it from the position in the ToC
+ hierarchy. The underscore is used as the separator between the path
+ steps.
+
+ * All other id-s must use prefix:
+ - example: E.g.: id="example.foreach"
+ - ref: Reference information...
+ * directive: about a directive. E.g.: "ref.directive.foreach"
+ * builtin
+ - gloss: Term in the Glossary
+ - topic: The recommended point of document in a certain topic
+ * designer: for designers.
+ E.g.: id="topic.designer.methodDataObject"
+ * programmer: for programmers
+ * or omit the secondary category if it is for everybody
+ - misc: Anything doesn't fit in the above categories
+
+ * When you refer to a part, chapter or section, often you should use
+ xref, not link. The xreflabel attribute of the link-end should not be set;
+ then it's deduced from the titles.
+
+- The "book" element must have this attribute: conformance="docgen"
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-misc/googleAnalytics.html
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-misc/googleAnalytics.html b/src/manual/en_US/docgen-misc/googleAnalytics.html
new file mode 100644
index 0000000..bf440f2
--- /dev/null
+++ b/src/manual/en_US/docgen-misc/googleAnalytics.html
@@ -0,0 +1,9 @@
+<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>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-originals/figures/model2sketch_with_alpha.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-originals/figures/model2sketch_with_alpha.png b/src/manual/en_US/docgen-originals/figures/model2sketch_with_alpha.png
new file mode 100644
index 0000000..ce120cc
Binary files /dev/null and b/src/manual/en_US/docgen-originals/figures/model2sketch_with_alpha.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-originals/figures/odg-convert-howto.txt
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-originals/figures/odg-convert-howto.txt b/src/manual/en_US/docgen-originals/figures/odg-convert-howto.txt
new file mode 100644
index 0000000..1db294c
--- /dev/null
+++ b/src/manual/en_US/docgen-originals/figures/odg-convert-howto.txt
@@ -0,0 +1,24 @@
+Converting to SVG:
+1. Open the ODG file with Libeoffice/OpenOffice Draw
+2. Ctrl+A to select all objects
+3. File/Export..., chose SVG format, and then tick "Selection"
+4. Check the result. If contour lines at the right and bottom edge of the
+ figure are partically clipped (stroke width is halved), set a stroke with
+ other than 0 for all shapes.
+
+Converting to a decent quality (though non-transparent) PNG:
+1. Open the ODG file with Libeoffice/OpenOffice Draw
+2. Export to PDF
+3. Open PDF in Adobe Acrobat Reader
+4. Go to Adobe Acrobat Reader preferences and set it to not use subpixel
+ anti-aliasing, just normal anti-aliasing. They used to call this LCD vs
+ Monitor mode.
+5. Zoom in/out until you get the desired size in pixels, take a
+ screen shot, crop it in some image editor, save it as PNG.
+
+Converting to transparent but somewhat ugly PNG:
+1. Convert to SVG as described earlier
+2. Use Apache Batik Rasterizer command line utility like:
+ $BARIK_INSTALLATION\batik-rasterizer-1.8.jar -dpi 72 -m image/png ${FIGURE}.svg
+ If Batik fails (as it doesn't support all SVG features), use Inkscape.
+ Of course avoid supixel anti-aliasing, as it's not device independent.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-originals/figures/overview.odg
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-originals/figures/overview.odg b/src/manual/en_US/docgen-originals/figures/overview.odg
new file mode 100644
index 0000000..0533b7c
Binary files /dev/null and b/src/manual/en_US/docgen-originals/figures/overview.odg differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen-originals/figures/tree_with_alpha.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen-originals/figures/tree_with_alpha.png b/src/manual/en_US/docgen-originals/figures/tree_with_alpha.png
new file mode 100644
index 0000000..dc4fba8
Binary files /dev/null and b/src/manual/en_US/docgen-originals/figures/tree_with_alpha.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/docgen.cjson
----------------------------------------------------------------------
diff --git a/src/manual/en_US/docgen.cjson b/src/manual/en_US/docgen.cjson
new file mode 100644
index 0000000..221f349
--- /dev/null
+++ b/src/manual/en_US/docgen.cjson
@@ -0,0 +1,112 @@
+//charset: UTF-8
+
+deployUrl: "http://freemarker.org/docs/"
+onlineTrackerHTML: "docgen-misc/googleAnalytics.html"
+searchKey: "014728049242975963158:8awjt03uofm"
+validation: {
+ programlistingsRequireRole
+ // programlistingsRequireLanguage
+ maximumProgramlistingWidth: 100
+}
+showXXELogo
+generateEclipseTOC
+// eclipse: {
+// link_to: "freemarker-toc.xml#ManualLink"
+// }
+
+removeNodesWhenOnline: [ "preface" ]
+
+copyrightHolder: "The FreeMarker Project"
+copyrightStartYear: 1999
+
+seoMeta: {
+ "dgui_quickstart": {
+ "title": "Getting Started with template writing"
+ }
+ "pgui_quickstart": {
+ "title": "Getting Started with the Java API"
+ }
+}
+
+logo: {
+ href: "http://freemarker.org"
+ src: logo.png,
+ alt: "FreeMarker"
+}
+
+olinks: {
+ homepage: "http://freemarker.org/"
+ api: "api/index.html"
+
+ // Homepage links:
+ freemarkerdownload: "http://freemarker.org/freemarkerdownload.html"
+ contribute: "http://freemarker.org/contribute.html"
+ history: "http://freemarker.org/history.html"
+ what-is-freemarker: "id:preface"
+ mailing-lists: "http://freemarker.org/mailing-lists.html"
+
+ // External URL-s:
+ onlineTemplateTester: "http://freemarker-online.kenshoo.com/"
+ twitter: "https://twitter.com/freemarker"
+ sourceforgeProject: "https://sourceforge.net/projects/freemarker/"
+ githubProject: "https://github.com/freemarker/freemarker"
+ newBugReport: "https://sourceforge.net/p/freemarker/bugs/new/"
+ newStackOverflowQuestion: "http://stackoverflow.com/questions/ask?tags=freemarker"
+}
+
+internalBookmarks: {
+ "Alpha. index": alphaidx
+ "Glossary": gloss
+ "Expressions": exp_cheatsheet
+ "?builtins": ref_builtins_alphaidx
+ "#directives": ref_directive_alphaidx
+ ".spec_vars": ref_specvar
+ "FAQ": app_faq
+}
+
+tabs: {
+ "Home": "olink:homepage"
+ "Manual": "" // Empty => We are here
+ "Java API": "olink:api"
+}
+
+// Available icons:
+// .icon-heart
+// .icon-bug
+// .icon-download
+// .icon-star
+secondaryTabs: {
+ "Contribute": { class: "icon-heart", href: "olink:contribute" }
+ "Report a Bug": { class: "icon-bug", href: "olink:newBugReport" }
+ "Download": { class: "icon-download", href: "olink:freemarkerdownload" }
+}
+
+footerSiteMap: {
+ "Overview": {
+ "What is FreeMarker?": "olink:what-is-freemarker"
+ "Download": "olink:freemarkerdownload"
+ "Version history": "id:app_versions"
+ "About us": "olink:history"
+ "License": "id:app_license"
+ }
+ "Handy stuff": {
+ "Try template online": "olink:onlineTemplateTester"
+ "Expressions cheatsheet": "id:exp_cheatsheet"
+ "#directives": "id:ref_directive_alphaidx"
+ "?built_ins": "id:ref_builtins_alphaidx"
+ ".special_vars": "id:ref_specvar"
+ }
+ "Community": {
+ "FreeMarker on Github": "olink:githubProject"
+ "Follow us on Twitter": "olink:twitter"
+ "Report a bug": "olink:newBugReport"
+ "Ask a question": "olink:newStackOverflowQuestion"
+ "Mailing lists": "olink:mailing-lists"
+ }
+}
+
+socialLinks: {
+ "Github": { class: "github", href: "olink:githubProject" }
+ "Twitter": { class: "twitter", href: "olink:twitter" }
+ "Stack Overflow": { class: "stack-overflow", href: "olink:newStackOverflowQuestion" }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/favicon.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/favicon.png b/src/manual/en_US/favicon.png
new file mode 100644
index 0000000..ce0de20
Binary files /dev/null and b/src/manual/en_US/favicon.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/figures/model2sketch.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/figures/model2sketch.png b/src/manual/en_US/figures/model2sketch.png
new file mode 100644
index 0000000..93f9a6b
Binary files /dev/null and b/src/manual/en_US/figures/model2sketch.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/figures/overview.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/figures/overview.png b/src/manual/en_US/figures/overview.png
new file mode 100644
index 0000000..b32e0bd
Binary files /dev/null and b/src/manual/en_US/figures/overview.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/figures/tree.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/figures/tree.png b/src/manual/en_US/figures/tree.png
new file mode 100644
index 0000000..dcd9bf3
Binary files /dev/null and b/src/manual/en_US/figures/tree.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/logo.png
----------------------------------------------------------------------
diff --git a/src/manual/en_US/logo.png b/src/manual/en_US/logo.png
new file mode 100644
index 0000000..193dc11
Binary files /dev/null and b/src/manual/en_US/logo.png differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/favicon.png
----------------------------------------------------------------------
diff --git a/src/manual/favicon.png b/src/manual/favicon.png
deleted file mode 100644
index ce0de20..0000000
Binary files a/src/manual/favicon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/figures/model2sketch.png
----------------------------------------------------------------------
diff --git a/src/manual/figures/model2sketch.png b/src/manual/figures/model2sketch.png
deleted file mode 100644
index 93f9a6b..0000000
Binary files a/src/manual/figures/model2sketch.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/figures/overview.png
----------------------------------------------------------------------
diff --git a/src/manual/figures/overview.png b/src/manual/figures/overview.png
deleted file mode 100644
index b32e0bd..0000000
Binary files a/src/manual/figures/overview.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/figures/tree.png
----------------------------------------------------------------------
diff --git a/src/manual/figures/tree.png b/src/manual/figures/tree.png
deleted file mode 100644
index dcd9bf3..0000000
Binary files a/src/manual/figures/tree.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/logo.png
----------------------------------------------------------------------
diff --git a/src/manual/logo.png b/src/manual/logo.png
deleted file mode 100644
index 193dc11..0000000
Binary files a/src/manual/logo.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/zh_CN/placeholder.txt
----------------------------------------------------------------------
diff --git a/src/manual/zh_CN/placeholder.txt b/src/manual/zh_CN/placeholder.txt
new file mode 100644
index 0000000..a83feff
--- /dev/null
+++ b/src/manual/zh_CN/placeholder.txt
@@ -0,0 +1,5 @@
+Add the Chinese Manual here, then delete this file.
+You can use these to test if the Manual is generated succesfully:
+
+ ant manualOffline_zh_CN
+ ant manualFreemarkerOrg_zh_CN
[5/5] incubator-freemarker git commit: Made place for the Chinese
manual.
Posted by dd...@apache.org.
Made place for the Chinese manual.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/731be2c2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/731be2c2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/731be2c2
Branch: refs/heads/2.3-gae
Commit: 731be2c28e51d71e5027c6fd4ddda68c3af81b05
Parents: 41b6f83
Author: ddekany <dd...@apache.org>
Authored: Sun Dec 20 14:05:48 2015 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Dec 20 14:05:48 2015 +0100
----------------------------------------------------------------------
build.xml | 22 +-
src/manual/book.xml | 37479 -----------------
src/manual/docgen-help/editors-readme.txt | 105 -
src/manual/docgen-misc/googleAnalytics.html | 9 -
.../figures/model2sketch_with_alpha.png | Bin 61463 -> 0 bytes
.../figures/odg-convert-howto.txt | 24 -
.../docgen-originals/figures/overview.odg | Bin 11939 -> 0 bytes
.../figures/tree_with_alpha.png | Bin 10304 -> 0 bytes
src/manual/docgen.cjson | 112 -
src/manual/en_US/book.xml | 37479 +++++++++++++++++
src/manual/en_US/docgen-help/editors-readme.txt | 105 +
.../en_US/docgen-misc/googleAnalytics.html | 9 +
.../figures/model2sketch_with_alpha.png | Bin 0 -> 61463 bytes
.../figures/odg-convert-howto.txt | 24 +
.../en_US/docgen-originals/figures/overview.odg | Bin 0 -> 11939 bytes
.../figures/tree_with_alpha.png | Bin 0 -> 10304 bytes
src/manual/en_US/docgen.cjson | 112 +
src/manual/en_US/favicon.png | Bin 0 -> 1291 bytes
src/manual/en_US/figures/model2sketch.png | Bin 0 -> 21425 bytes
src/manual/en_US/figures/overview.png | Bin 0 -> 11837 bytes
src/manual/en_US/figures/tree.png | Bin 0 -> 4699 bytes
src/manual/en_US/logo.png | Bin 0 -> 10134 bytes
src/manual/favicon.png | Bin 1291 -> 0 bytes
src/manual/figures/model2sketch.png | Bin 21425 -> 0 bytes
src/manual/figures/overview.png | Bin 11837 -> 0 bytes
src/manual/figures/tree.png | Bin 4699 -> 0 bytes
src/manual/logo.png | Bin 10134 -> 0 bytes
src/manual/zh_CN/placeholder.txt | 5 +
28 files changed, 37752 insertions(+), 37733 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index 999c88b..aa42db9 100644
--- a/build.xml
+++ b/build.xml
@@ -548,6 +548,7 @@
<macrodef name="manual" uri="http://freemarker.org/util">
<attribute name="offline" />
+ <attribute name="locale" />
<sequential>
<ivy:cachepath conf="manual" pathid="ivy.dep" />
<taskdef resource="org/freemarker/docgen/antlib.properties"
@@ -556,20 +557,28 @@
/>
<docgen:transform
- srcdir="src/manual" destdir="build/manual"
+ srcdir="src/manual/@{locale}" destdir="build/manual/@{locale}"
offline="@{offline}"
/>
</sequential>
</macrodef>
<target name="manualOffline" depends="init" description="Build the Manual for offline use" >
- <u:manual offline="true" />
+ <u:manual offline="true" locale="en_US" />
</target>
<target name="manualFreemarkerOrg" depends="init" description="Build the Manual to be upload to freemarker.org" >
- <u:manual offline="false" />
+ <u:manual offline="false" locale="en_US" />
+ </target>
+
+ <target name="manualOffline_zh_CN" depends="init" description="Build the Manual for offline use" >
+ <u:manual offline="true" locale="zh_CN" />
</target>
+ <target name="manualFreemarkerOrg_zh_CN" depends="init" description="Build the Manual to be upload to freemarker.org" >
+ <u:manual offline="false" locale="zh_CN" />
+ </target>
+
<!-- ====================== -->
<!-- Examples -->
<!-- ====================== -->
@@ -680,8 +689,13 @@
<copy todir="${dist.dir}/">
<fileset dir="src/dist/" />
</copy>
+ <!--
+ The US English Manual is the source of any translations and this it's the
+ only one that is guaranteed to be up to date when doing the release, so we only pack
+ that into it.
+ -->
<copy todir="${dist.dir}/documentation/_html" includeEmptyDirs="no">
- <fileset dir="build/manual" />
+ <fileset dir="build/manual/en-US" />
</copy>
<copy todir="${dist.dir}/documentation/_html/api" includeEmptyDirs="no">
<fileset dir="build/api" />
[4/5] incubator-freemarker git commit: Made place for the Chinese
manual.
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
deleted file mode 100644
index c561322..0000000
--- a/src/manual/book.xml
+++ /dev/null
@@ -1,37479 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<book conformance="docgen" version="5.0" xml:lang="en"
- xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:ns5="http://www.w3.org/1999/xhtml"
- xmlns:ns4="http://www.w3.org/2000/svg"
- xmlns:ns3="http://www.w3.org/1998/Math/MathML"
- xmlns:ns="http://docbook.org/ns/docbook">
- <info>
- <title>FreeMarker Manual</title>
-
- <titleabbrev>Manual</titleabbrev>
-
- <productname>Freemarker 2.3.24 Preview 1</productname>
- </info>
-
- <preface role="index.html" xml:id="preface">
- <title>What is FreeMarker?</title>
-
- <para>FreeMarker is a <emphasis>template engine</emphasis>: a generic tool
- to generate text output (HTML web pages, e-mails, configuration files,
- source code, etc.) based on templates and changing data. It's not an
- application for end-users in itself, but a Java library, a component that
- programmers can embed into their products.</para>
-
- <para>Templates are written in the FreeMarker Template Language (FTL).
- It's a simple, specialized language, <emphasis>not</emphasis> a full-blown
- programming language like PHP. You meant to prepare the data to display in
- a real programming language, like issue database queries and do business
- calculations, and then the template displays that already prepared data.
- In the template you are focusing on how to present the data, and outside
- the template you are focusing on what data to present.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="figures/overview.png"/>
- </imageobject>
- </mediaobject>
-
- <para>This approach is often referred to as the <link
- linkend="gloss.MVC">MVC (Model View Controller) pattern</link>, and is
- particularly popular for dynamic Web pages. It helps in separating the Web
- page designers (HTML authors) from the developers (Java programmers
- usually). Designers won't face complicated logic in templates, and can
- change the appearance of a page without programmers having to change or
- recompile code.</para>
-
- <para>While FreeMarker was originally created for generating HTML pages in
- MVC web application frameworks, it isn't bound to servlets or HTML or
- anything Web-related. It's used in non-web application environments as
- well.</para>
-
- <para>FreeMarker is <link
- xlink:href="http://www.fsf.org/philosophy/free-sw.html">Free</link>,
- released under the Apache License, Version 2.0.</para>
- </preface>
-
- <part xml:id="dgui">
- <title>Template Author's Guide</title>
-
- <chapter xml:id="dgui_quickstart">
- <title>Getting Started</title>
-
- <para>This chapter is a very rough introduction to FreeMarker. The
- chapters after this will go over things in much greater detail.
- Nonetheless, once you have read this chapter, you will be able to write
- simple but useful FreeMarker templates.</para>
-
- <section xml:id="dgui_quickstart_basics">
- <title>Template + data-model = output</title>
-
- <para>Let's assume that you need a HTML page in a Web shop, similar to
- this:</para>
-
- <programlisting role="output"><html>
-<head>
- <title>Welcome!</title>
-</head>
-<body>
- <h1>Welcome <emphasis>John Doe</emphasis>!</h1>
- <p>Our latest product:
- <a href="<emphasis>products/greenmouse.html</emphasis>"><emphasis>green mouse</emphasis></a>!
-</body>
-</html></programlisting>
-
- <para>But the user name ("John Doe" above) should depend on who the
- logged in Web page visitor is, and the latest product should come from
- a database and thus it potentially changes too. Thus you can't enter
- these into the HTML directly, you can't use static HTML. Instead, you
- can use a <emphasis role="term">template</emphasis> of the desired
- output. The template is the same as the static HTML would be, except
- that it contains some instructions to FreeMarker that makes it
- dynamic:</para>
-
- <programlisting role="template" xml:id="example.first"><html>
-<head>
- <title>Welcome!</title>
-</head>
-<body>
- <h1>Welcome <emphasis>${user}</emphasis>!</h1>
- <p>Our latest product:
- <a href="<emphasis>${latestProduct.url}</emphasis>"><emphasis>${latestProduct.name}</emphasis></a>!
-</body>
-</html></programlisting>
-
- <para>The template is stored on the Web server, usually just like the
- static HTML page would be. But whenever someone visits this page,
- FreeMarker will step in and transform the template on-the-fly to plain
- HTML by replacing the
- <literal>${<replaceable>...</replaceable>}</literal>-s with up-to-date
- content, and send the result to the visitor's Web browser. So the
- visitor's Web browser will receive something like the first example
- HTML (i.e., plain HTML without FreeMarker instructions), and it will
- not perceive that FreeMarker is used on the server. (Of course, the
- template file stored on the Web server is not changed by this; the
- substitutions only appear in the Web server's response.)</para>
-
- <para>Note that the template doesn't contain the programming logic to
- find out who the current visitor is, or to query the database to get
- the latest product. The data to be displayed is prepared outside
- FreeMarker, usually by parts written in some <quote>real</quote>
- programming language like Java. The template author needn't know how
- these values were calculated. In fact, the way these values are
- calculated can be completely changed while the templates can remain
- exactly the same, and also, the look of the page can be completely
- changed without touching anything but the template. This separation of
- presentation logic and business logic can be especially useful when
- the template authors (designers) and the programmers are different
- individuals, but also helps managing application complexity if they
- are the same person. Keeping templates focused on presentation issues
- (visual design, layout and formatting) is a key for using template
- engines like FreeMarker efficiently.</para>
-
- <para><indexterm>
- <primary>data-model</primary>
- </indexterm>The totality of data that was prepared for the template
- is called the <emphasis role="term">data-model</emphasis>. As far as
- the template author is concerned, the data-model is a tree-like
- structure (like folders and files on your hard disk), which, in this
- case, could be visualized as:</para>
-
- <programlisting role="dataModel">(root)
- |
- +- <emphasis>user</emphasis> = "Big Joe"
- |
- +- <emphasis>latestProduct</emphasis>
- |
- +- <emphasis>url</emphasis> = "products/greenmouse.html"
- |
- +- <emphasis>name</emphasis> = "green mouse"</programlisting>
-
- <note>
- <para>The above is just a visualization; the data-model is not in a
- textual format, it's from Java objects. For the Java programmers,
- the root is perhaps a Java object with <literal>getUser()</literal>
- and <literal>getLatestProduct()</literal> methods, or maybe a Java
- <literal>Map</literal> with <literal>"user"</literal> and
- <literal>"latestProducts"</literal> keys. Similarly,
- <literal>latestProduct</literal> is perhaps a Java Object with
- <literal>getUrl()</literal> and <literal>getName()</literal>
- methods.</para>
- </note>
-
- <para>Earlier, you have picked values from this data-model, with the
- <literal>user</literal> and <literal>latestProduct.name</literal>
- expressions. If we go on with the analogy that the data model is like
- a file system, then <quote>(root)</quote> and
- <literal>latestProduct</literal> correspond to directories (folders),
- and <literal>user</literal>, <literal>url</literal> and
- <literal>name</literal> are files in those directories.</para>
-
- <para>To recapitulate, a template and a data-model is needed for
- FreeMarker to generate the output (like the HTML shown first):</para>
-
- <para><phrase role="markedTemplate">Template</phrase> + <phrase
- role="markedDataModel">data-model</phrase> = <phrase
- role="markedOutput">output</phrase></para>
- </section>
-
- <section xml:id="dgui_quickstart_datamodel">
- <title>The data-model at a glance</title>
-
- <para>As you have seen, the data-model is basically a tree. This tree
- can be arbitrarily complicated and deep, for example:</para>
-
- <programlisting role="dataModel"
- xml:id="example.qStart.dataModelWithHashes">(root)
- |
- +- animals
- | |
- | +- mouse
- | | |
- | | +- size = "small"
- | | |
- | | +- price = 50
- | |
- | +- elephant
- | | |
- | | +- size = "large"
- | | |
- | | +- price = 5000
- | |
- | +- python
- | |
- | +- size = "medium"
- | |
- | +- price = 4999
- |
- +- message = "It is a test"
- |
- +- misc
- |
- +- foo = "Something"</programlisting>
-
- <para>The variables that act like directories (the root,
- <literal>animals</literal>, <literal>mouse</literal>,
- <literal>elephant</literal>, <literal>python</literal>,
- <literal>misc</literal>) are called <emphasis
- role="term">hashes</emphasis>. Hashes store other variables (the so
- called <anchor xml:id="topic.dataModel.subVar"/><emphasis>sub
- variables</emphasis>) by a lookup name (e.g., <quote>animals</quote>,
- <quote>mouse</quote> or <quote>price</quote>).</para>
-
- <para>The variables that store a single value
- (<literal>size</literal>, <literal>price</literal>,
- <literal>message</literal> and <literal>foo</literal>) are called
- <emphasis role="term">scalars</emphasis>.</para>
-
- <para><anchor xml:id="topic.qStart.accessVariables"/>When you want to
- use a subvariable in a template, you specify its path from the root,
- and separate the steps with dots. To access the
- <literal>price</literal> of a <literal>mouse</literal>, you start from
- the root and go into <literal>animals</literal>, and then go into
- <literal>mouse</literal> then go into <literal>price</literal>. So you
- write <literal>animals.mouse.price</literal>.</para>
-
- <para>Another important kind of variables are <emphasis
- role="term">sequences</emphasis>. They store subvariables like hashes,
- but here subvariables doesn't have a name, they are just items in a
- list. For example, in this data-model, <literal>animals</literal> and
- <literal>misc.fruits</literal> are sequences:</para>
-
- <programlisting role="dataModel"
- xml:id="example.qStart.dataModelWithSequences">(root)
- |
- +- animals
- | |
- | +- (1st)
- | | |
- | | +- name = "mouse"
- | | |
- | | +- size = "small"
- | | |
- | | +- price = 50
- | |
- | +- (2nd)
- | | |
- | | +- name = "elephant"
- | | |
- | | +- size = "large"
- | | |
- | | +- price = 5000
- | |
- | +- (3rd)
- | |
- | +- name = "python"
- | |
- | +- size = "medium"
- | |
- | +- price = 4999
- |
- +- misc
- |
- +- fruits
- |
- +- (1st) = "orange"
- |
- +- (2nd) = "banana"</programlisting>
-
- <para>To access a subvariable of a sequence you use a numerical index
- in square brackets. Indexes start from 0 (it's a programmer tradition
- to start with 0), thus the index of the 1st item is 0, the index of
- the 2nd item is 1, and so on. So to get the name of the first animal
- you write <literal>animals[0].name</literal>. To get the second item
- in <literal>misc.fruits</literal> (the string
- <literal>"banana"</literal>) you write
- <literal>misc.fruits[1]</literal>. (In practice, you usually just walk
- through sequences in order, not caring about the index, but that will
- be <link linkend="topic.tutorial.list">shown later</link>.)</para>
-
- <para>Scalars can be further divided into these categories:</para>
-
- <itemizedlist>
- <listitem>
- <para>String: Text, that is, an arbitrary sequence of characters
- such as ''m'', ''o'', ''u'', ''s'', ''e'' above. For example the
- <literal>name</literal>-s and <literal>size</literal>-s are
- strings above.</para>
- </listitem>
-
- <listitem>
- <para>Number: It's a numerical value, like the
- <literal>price</literal>-s above. The string
- <literal>"50"</literal> and the number <literal>50</literal> are
- two totally different things in FreeMarker. The former is just a
- sequence of two characters (which happens to be readable as a
- number for humans), while the latter is a numerical value that you
- can use in arithmetical calculations.</para>
- </listitem>
-
- <listitem>
- <para>Date-like: Either a date-time (stores a date with time of
- the day), or a date (no time of day), or a time (time of day, no
- date).</para>
- </listitem>
-
- <listitem>
- <para>Boolean: A true/false (yes/no, on/off, etc.) thing. Like
- animals could have a <literal>protected</literal> subvariable,
- which store if the animal is protected or not.</para>
- </listitem>
- </itemizedlist>
-
- <para>Summary:</para>
-
- <itemizedlist>
- <listitem>
- <para>The data-model can be visualized as a tree.</para>
- </listitem>
-
- <listitem>
- <para>Scalars store a single value. The value can be a string or a
- number or a date-time/date/time or a boolean.</para>
- </listitem>
-
- <listitem>
- <para>Hashes are containers that store other variables and
- associate them with a unique lookup name.</para>
- </listitem>
-
- <listitem>
- <para>Sequences are containers that store other variables in an
- ordered sequence. The stored variables can be retrieved via their
- numerical index, starting from 0.</para>
- </listitem>
- </itemizedlist>
-
- <note>
- <para>There are other, more advanced value types that we don't cover
- here, such as methods and directives.</para>
- </note>
- </section>
-
- <section xml:id="dgui_quickstart_template">
- <title>The template at a glance</title>
-
- <para>The simplest template is a plain HTML file (or whatever text
- file; FreeMarker is not confined to HTML). When the client visits that
- page, FreeMarker will send that HTML to the client as is. However if
- you want that page to be more dynamic then you begin to put special
- parts into the HTML which will be understood by FreeMarker:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>${<replaceable>...</replaceable>}</literal>:
- FreeMarker will replace it in the output with the actual value of
- the expression inside the curly brackets. They are called
- <emphasis role="term">interpolation</emphasis>s.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="term">FTL tags</emphasis> (for FreeMarker
- Template Language tags): FTL tags are a bit similar to HTML tags,
- but they are instructions to FreeMarker and will not be printed to
- the output. The name of these tags start with
- <literal>#</literal>. (User-defined FTL tags use
- <literal>@</literal> instead of <literal>#</literal>, but they are
- an advanced topic.)</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="term">Comments:</emphasis> Comments are
- similar to HTML comments, but they are delimited by
- <literal><#--</literal> and <literal>--></literal>. Unlike
- HTML comments, FTL comments won't get into the output (won't be
- visible in the page source for the visitor), because FreeMarker
- skips them.</para>
- </listitem>
- </itemizedlist>
-
- <para>Anything not an FTL tag or an interpolation or comment is
- considered as static text, and will not be interpreted by FreeMarker;
- it is just printed to the output as is.</para>
-
- <para>With FTL tags you refer to so-called <emphasis
- role="term">directives</emphasis>. This is the same kind of
- relationship as between HTML tags (e.g.:
- <literal><table></literal> and
- <literal></table></literal>) and HTML elements (e.g., the
- <literal>table</literal> element) to which you refer to with the HTML
- tags. (If you don't feel this difference then just take "FTL tag" and
- "directive" as synonyms.)</para>
-
- <note>
- <para>You can easily try writing templates on <link
- xlink:href="http://freemarker-online.kenshoo.com/">http://freemarker-online.kenshoo.com/</link></para>
- </note>
-
- <section>
- <title>Some basic directives</title>
-
- <para>Here we will look at some of the most commonly used directives
- (<link linkend="ref_directives">but there are much
- more</link>).</para>
-
- <section>
- <title>The if directive</title>
-
- <para>With the <literal>if</literal> directive you can
- conditionally skip a section of the template. For example, assume
- that in the <link linkend="example.first">very first
- example</link> you want to greet your boss, Big Joe, differently
- than other users:</para>
-
- <programlisting role="template"><html>
-<head>
- <title>Welcome!</title>
-</head>
-<body>
- <h1>
- Welcome ${user}<emphasis><#if user == "Big Joe"></emphasis>, our beloved leader<emphasis></#if></emphasis>!
- </h1>
- <p>Our latest product:
- <a href="${latestProduct.url}">${latestProduct.name}</a>!
-</body>
-</html></programlisting>
-
- <para>Here you have told FreeMarker that the <quote>, our beloved
- leader</quote> should be there only if the value of the variable
- <literal>user</literal> is equal to the string <literal>"Big
- Joe"</literal>. In general, things between <literal><#if
- <replaceable>condition</replaceable>></literal> and
- <literal></#if></literal> tags are skipped if
- <literal><replaceable>condition</replaceable></literal> is false
- (the boolean value).</para>
-
- <para>Let's look at
- <literal><replaceable>condition</replaceable></literal> more
- closely: <literal>==</literal> is an operator that tests if the
- values at its left and right side are equivalent, and the results
- is a boolean value, true or false accordingly. On the left side of
- <literal>==</literal> I have <link
- linkend="topic.qStart.accessVariables">referenced a
- variable</link> with the syntax that should be already familiar;
- this will be replaced with the value of the variable. In general,
- unquoted words inside directives or interpolations are treated as
- references to variables. On the right side I have specified a
- literal string. Literal strings in templates must
- <emphasis>always</emphasis> be put inside quotation marks.</para>
-
- <para>This will print <quote>Pythons are free today!</quote> if
- their price is 0:</para>
-
- <programlisting role="template"><#if animals.python.price == <emphasis>0</emphasis>>
- Pythons are free today!
-</#if></programlisting>
-
- <para>Similarly as earlier when a string was specified directly,
- here a number is specified directly (<literal>0</literal>). Note
- that the number is <emphasis>not</emphasis> quoted. If you quoted
- it (<literal>"0"</literal>), FreeMarker were misinterpret it as a
- string literal, and because the price to compare it to is number,
- you get an error.</para>
-
- <para>This will print "Pythons are not free today!" if their price
- is not 0:</para>
-
- <programlisting role="template"><#if animals.python.price <emphasis>!=</emphasis> 0>
- Pythons are not free today!
-</#if></programlisting>
-
- <para>As you probably guessed, <literal>!=</literal> means
- <quote>not equals</quote>.</para>
-
- <para>You can write things like this too (using <link
- linkend="example.qStart.dataModelWithHashes">the data-model used
- to demonstrate hashes</link>):</para>
-
- <programlisting role="template"><#if <emphasis>animals.python.price < animals.elephant.price</emphasis>>
- Pythons are cheaper than elephants today.
-</#if></programlisting>
-
- <para>With the <literal><#else></literal> tag you can
- specify what to do if the condition is false. For example:</para>
-
- <programlisting role="template"><#if animals.python.price < animals.elephant.price>
- Pythons are cheaper than elephants today.
-<emphasis><#else></emphasis>
- Pythons are not cheaper than elephants today.
-</#if></programlisting>
-
- <para>This prints <quote>Pythons are cheaper than elephants
- today.</quote> if the price of python is less than the price of
- elephant, or else it prints <quote>Pythons are not cheaper than
- elephants today.</quote> You can refine this further by using
- <literal>elseif</literal>:</para>
-
- <programlisting role="template"><#if animals.python.price < animals.elephant.price>
- Pythons are cheaper than elephants today.
-<emphasis><#elseif animals.elephant.price < animals.python.price></emphasis>
- Elephants are cheaper than pythons today.
-<#else>
- Elephants and pythons cost the same today.
-</#if></programlisting>
-
- <para>If you have a variable with boolean value (a true/false
- thing) then you can use it directly as the
- <literal><replaceable>condition</replaceable></literal> of
- <literal>if</literal>:</para>
-
- <programlisting role="template"><#if animals.python.protected>
- Pythons are protected animals!
-</#if></programlisting>
- </section>
-
- <section>
- <title>The list directive</title>
-
- <anchor xml:id="topic.tutorial.list"/>
-
- <para>This is needed when you want to list something. For example
- if you merge this template with the <link
- linkend="example.qStart.dataModelWithSequences">data-model used
- earlier to demonstrate sequences</link>:</para>
-
- <programlisting role="template"><p>We have these animals:
-<table border=1>
- <emphasis><#list animals as animal></emphasis>
- <tr><td>${<emphasis>animal</emphasis>.name}<td>${<emphasis>animal</emphasis>.price} Euros
- <emphasis></#list></emphasis>
-</table></programlisting>
-
- <para>then the output will be:</para>
-
- <programlisting role="output"><p>We have these animals:
-<table border=1>
- <emphasis><tr><td>mouse<td>50 Euros
- <tr><td>elephant<td>5000 Euros
- <tr><td>python<td>4999 Euros</emphasis>
-</table></programlisting>
-
- <para>The generic form of the <literal>list</literal> directive
- is:<literal> <#list <replaceable>sequence</replaceable> as
- <replaceable>loopVariable</replaceable>><replaceable>repeatThis</replaceable></#list></literal>.
- The <literal><replaceable>repeatThis</replaceable></literal> part
- will be repeated for each item in the sequence that you have
- specified with
- <literal><replaceable>sequence</replaceable></literal>, one after
- the other, starting from the first item. In all repetitions
- <literal><replaceable>loopVariable</replaceable></literal> will
- hold the value of the current item. This variable exists only
- between the <literal><#list
- <replaceable>...</replaceable>></literal> and
- <literal></#list></literal> tags.</para>
-
- <para>The <literal><replaceable>sequence</replaceable></literal>
- can be any kind of expression, like we could list the fruits of
- the example data model like this:</para>
-
- <programlisting role="template"><ul>
-<emphasis><#list misc.fruits as fruit></emphasis>
- <li>${fruit}
-<emphasis></#list></emphasis>
-</ul></programlisting>
-
- <para>The <literal>misc.fruits</literal> expression should be
- familiar to you; it <link
- linkend="topic.qStart.accessVariables">references a variable in
- the data-model</link>.</para>
-
- <para>A problem with the above example is that if we happen to
- have 0 fruits, it will still print an empty
- <literal><ul></ul></literal> instead of just nothing.
- To avoid that, you can use this form of
- <literal>list</literal>:</para>
-
- <programlisting role="template"><#list misc.fruits>
- <ul>
- <emphasis> <#items as fruit></emphasis>
- <li>${fruit}
- <emphasis> </#items></emphasis>
- </ul>
-</#list></programlisting>
-
- <para>Here, the <literal>list</literal> directive represents the
- listing as a whole, and only the part inside the
- <literal>items</literal> directive is repeated for each fruit. If
- we have 0 fruits, everything inside <literal>list</literal> is
- skipped, hence we will not have <literal>ul</literal> tags in
- case.</para>
-
- <para>Another frequent listing-related task: let's list the fruits
- separating them with something, like comma:</para>
-
- <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<emphasis><#sep>, </emphasis></#list></programlisting>
-
- <programlisting role="output"><p>Fruits: orange, banana</programlisting>
-
- <para>The section covered by <literal>sep</literal> (which we
- could be written like this too:
- <literal><replaceable>...</replaceable><#sep>,
- </#sep></#list></literal>) will be only executed when
- there will be a next item. Hence there's no comma after the last
- fruit.</para>
-
- <para>Here again, what's if we have 0 fruits? Just printing
- <quote>Fruits:</quote> and then nothing is awkward. A
- <literal>list</literal>, just like an <literal>if</literal>, can
- have an <literal>else</literal>, which is executed if there were 0
- list items:</para>
-
- <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, <emphasis><#else>None</emphasis></#list></programlisting>
-
- <note>
- <para>As a matter of fact, this simplistic example could be
- written like this, but it uses language devices that are off
- topic here:</para>
-
- <programlisting role="template"><p>Fruits: ${fruits?join(", ", "None")}</programlisting>
- </note>
-
- <para>All these directives (<literal>list</literal>,
- <literal>items</literal>, <literal>sep</literal>,
- <literal>else</literal>) can be used together:</para>
-
- <programlisting role="template"><#list misc.fruits>
- <p>Fruits:
- <ul>
- <#items as fruit>
- <li>${fruit}<#sep> and</#sep>
- </#items>
- </ul>
-<#else>
- <p>We have no fruits.
-</#list></programlisting>
-
- <note>
- <para>You can read more about these directives <link
- linkend="ref_directive_list">in the Reference</link>.</para>
- </note>
- </section>
-
- <section>
- <title>The include directive</title>
-
- <para>With the <literal>include</literal> directive you can insert
- the content of another file into the template.</para>
-
- <para>Suppose you have to show the same copyright notice on
- several pages. You can create a file that contains the copyright
- notice only, and insert that file everywhere where you need that
- copyright notice. Say, you store this copyright notice in
- <literal>copyright_footer.html</literal>:</para>
-
- <programlisting role="template"><hr>
-<i>
-Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
-<br>
-All Rights Reserved.
-</i></programlisting>
-
- <para>Whenever you need that file you simply insert it with the
- <literal>include</literal> directive:</para>
-
- <programlisting role="template"><html>
-<head>
- <title>Test page</title>
-</head>
-<body>
- <h1>Test page</h1>
- <p>Blah blah...
-<emphasis> <#include "/copyright_footer.html"></emphasis>
-</body>
-</html></programlisting>
-
- <para>and the output will be:</para>
-
- <programlisting role="output"><html>
-<head>
- <title>Test page</title>
-</head>
-<body>
- <h1>Test page</h1>
- <p>Blah blah...
-<emphasis><hr>
-<i>
-Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
-<br>
-All Rights Reserved.
-</i></emphasis>
-</body>
-</html></programlisting>
-
- <para>If you change the <literal>copyright_footer.html</literal>,
- then the visitor will see the new copyright notice on all
- pages.</para>
-
- <note>
- <para>A much more powerful way of reusing snippets is using
- macros, but that's an advanced topic <link
- linkend="dgui_misc_userdefdir">discussed later</link>.</para>
- </note>
- </section>
- </section>
-
- <section>
- <title>Using directives together</title>
-
- <para>You can use directives as many times on a page as you want,
- and you can nest directives into each other freely. For example,
- here you nest <literal>if</literal> directive inside a
- <literal>list</literal> directive:</para>
-
- <programlisting role="template"><emphasis><#list animals as animal></emphasis>
- <div<emphasis><#if animal.protected></emphasis><emphasis> </emphasis>class="protected"<emphasis></#if></emphasis>>
- ${animal.name} for ${animal.price} Euros
- </div>
-<emphasis></#list></emphasis></programlisting>
-
- <para>Note that since FreeMarker does not interpret text outside FTL
- tags, interpolations and FTL comments, above you could use the FTL
- tags inside a HTML attributes without problem.</para>
- </section>
-
- <section>
- <title>Using built-ins</title>
-
- <para>The so called built-ins are like subvariables (or rather like
- methods, if you know that Java term) that aren't coming coming from
- the data-model, but added by FreeMarker to the values. To make it
- unambiguous where the subvarable comes from, to access them you have
- to use <literal>?</literal> (question mark) instead of
- <literal>.</literal> (dot). <anchor
- xml:id="topic.commonlyUsedBuiltIns"/>Examples with some of the most
- commonly used built-ins:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>user?upper_case</literal> gives the upper case
- version of the value of <literal>user</literal> (like
- <quote>JOHN DOE</quote> instead of <quote>John
- Doe</quote>)</para>
- </listitem>
-
- <listitem>
- <para><literal>animal.name?cap_first</literal> give the
- <literal>animal.name</literal> with its first letter converted
- to upper case (like <quote>Mouse</quote> instead of
- <quote>mouse</quote>)</para>
- </listitem>
-
- <listitem>
- <para><literal>user?length</literal> gives the number of
- <emphasis>characters</emphasis> in the value of
- <literal>user</literal> (8 for <quote>John Doe</quote>)</para>
- </listitem>
-
- <listitem>
- <para><literal>animals?size</literal> gives the number of
- <emphasis>items</emphasis> in the <literal>animals</literal>
- sequence (3 in our example data-model)</para>
- </listitem>
-
- <listitem>
- <para>If you are between <literal><#list animals as
- animal></literal> and the corresponding
- <literal></#list></literal> tag:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>animal?index</literal> gives the 0-based
- index of <literal>animal</literal> inside
- <literal>animals</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>animal?counter</literal> is like
- <literal>index</literal>, but gives the 1-based index</para>
- </listitem>
-
- <listitem>
- <para><literal>animal?item_parity</literal> gives the
- strings <quote>odd</quote> or <quote>even</quote>, depending
- on the current counter parity. This is commonly used for
- coloring rows with alternating colors, like in
- <literal><td
- class="${animal?item_parity}Row"></literal>.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- <para>Some built-ins require parameters to specify the behavior
- more, for example:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>animal.protected?string("Y", "N")</literal>
- return the string <quote>Y</quote> or <quote>N</quote> depending
- on the boolean value of
- <literal>animal.protected</literal>.</para>
- </listitem>
-
- <listitem>
- <para><literal>animal?item_cycle('lightRow',
- 'darkRow')</literal> is the more generic variant of
- <literal>item_parity</literal> from earlier.</para>
- </listitem>
-
- <listitem>
- <para><literal>fruits?join(", ")</literal>: converts the list to
- a string by concatenating items, and inserting the parameter
- separator between each items (like <quote>orange,
- banana</quote>)</para>
- </listitem>
-
- <listitem>
- <para><literal>user?starts_with("J")</literal> gives boolean
- true of false depending on if <literal>user</literal> starts
- with the letter <quote>J</quote> or not.</para>
- </listitem>
- </itemizedlist>
-
- <para>Built-in applications can be chained, like
- <literal>fruits?join(", ")?upper_case</literal> will first convert
- the list a to a string, then converts it to upper case. (This is
- just like you can chain <literal>.</literal>-s (dots) too.)</para>
-
- <para>You can find the <link linkend="ref_builtins">full set of
- built-ins in the Reference</link>.</para>
- </section>
-
- <section>
- <title>Dealing with missing variables</title>
-
- <para>The data-model often has variables that are optional (i.e.,
- sometimes missing). To spot some typical human mistakes, FreeMarker
- doesn't tolerate the referring to missing variables, unless you tell
- explicitly what to do if the variable is missing. Here we will show
- the two most typical ways of doing that.</para>
-
- <para><phrase role="forProgrammers">Note for programmers: A
- non-existent variable and a variable with <literal>null</literal>
- value is the same for FreeMarker, so the "missing" term used here
- covers both cases.</phrase></para>
-
- <para>Wherever you refer to a variable, you can specify a default
- value for the case the variable is missing, by following the
- variable name with a <literal>!</literal> and the default value.
- Like in the following example, when <literal>user</literal> is
- missing from data model, the template will behave like if
- <literal>user</literal>'s value were the string
- <literal>"visitor"</literal>. (When <literal>user</literal> isn't
- missing, this template behaves exactly like with
- <literal>${user}</literal>):</para>
-
- <programlisting role="template"><h1>Welcome ${user<emphasis>!"visitor"</emphasis>}!</h1></programlisting>
-
- <para>You can ask whether a variable isn't missing by putting
- <literal>??</literal> after its name. Combining this with the
- already introduced <literal>if</literal> directive you can skip the
- whole greeting if the <literal>user</literal> variable is
- missing:</para>
-
- <programlisting role="template"><#if <emphasis>user??</emphasis>><h1>Welcome ${user}!</h1></#if></programlisting>
-
- <para>Regarding variable accessing with multiple steps, like
- <literal>animals.python.price</literal>, writing
- <literal>animals.python.price!0</literal> is correct only if
- <literal>animals.python</literal> is never missing and only the last
- subvariable, <literal>price</literal>, is possibly missing (in which
- case here we assume it's <literal>0</literal>). If
- <literal>animals</literal> or <literal>python</literal> is missing,
- the template processing will stop with an "undefined variable"
- error. To prevent that, you have to write
- <literal>(animals.python.price)!0</literal>. In that case the
- expression will be <literal>0</literal> even if
- <literal>animals</literal> or <literal>python</literal> is missing.
- Same logic goes for <literal>??</literal>;
- <literal>animals.python.price??</literal> versus
- <literal>(animals.python.price)??</literal>.</para>
- </section>
-
- <section xml:id="dgui_quickstart_template_autoescaping">
- <title>Escaping for HTML, XML and other markup</title>
-
- <para>Let's say the template generates HTML, and you insert values
- with <literal>${<replaceable>...</replaceable>}</literal> that are
- plain text (not HTML), like company names coming from a database.
- Characters that has special meaning in HTML must be
- <emphasis>escaped</emphasis> in such values, like if
- <literal>name</literal> is <quote>Someone & Co.</quote> then
- <literal>${name}</literal> should print <quote>Someone
- <emphasis>&amp;</emphasis> Co.</quote>.</para>
-
- <para>FreeMarker automatically escapes all values printed with
- <literal>${<replaceable>...</replaceable>}</literal> <emphasis>if
- it's properly configured</emphasis> (that's the responsibility of
- the programmers; <link
- linkend="pgui_config_outputformatsautoesc">see here how</link>). The
- recommended practice is using <literal>ftlh</literal> file extension
- to activate HTML auto-escaping, and <literal>ftlx</literal> file
- extension to activate XML auto-escaping.</para>
-
- <para>You can try if auto-escaping is on like
- <literal>${"<"}</literal> (for HTML or XML escaping). If it's
- not, and the configuration won't be adjusted, add this as the very
- first line of the template:</para>
-
- <programlisting role="template"><#ftl output_format="HTML"></programlisting>
-
- <para>(Use <literal>"XML"</literal> instead of
- <literal>"HTML"</literal> above if you generate XML.)</para>
-
- <para>If the string value to print deliberately contains markup,
- auto-escaping must be prevented like
- <literal>${<replaceable>value</replaceable>?no_esc}</literal>.</para>
-
- <para>You can find out much more about auto-escaping and output
- formats <link linkend="dgui_misc_autoescaping">here...</link></para>
-
- <note>
- <para>The kind of automatic escaping described here requires at
- least FreeMarker 2.3.24. If you have to use an earlier version,
- use the deprecated <link
- linkend="ref_directive_escape"><literal>escape</literal>
- directive</link> instead.</para>
- </note>
- </section>
- </section>
- </chapter>
-
- <chapter xml:id="dgui_datamodel">
- <title>Values, Types</title>
-
- <section xml:id="dgui_datamodel_basics">
- <title>Basics</title>
-
- <note>
- <para>It is assumed that you have already read the <xref
- linkend="dgui_quickstart"/> chapter.</para>
- </note>
-
- <para>Understanding the concept of values and types is crucial for the
- understanding of data-models. However, the concept of values and types
- is not confined to data-models, as you will see.</para>
-
- <section xml:id="topic.value">
- <title>What is a value?</title>
-
- <indexterm>
- <primary>value</primary>
- </indexterm>
-
- <para><phrase role="forProgrammers">Real programmers can safely skip
- this section.</phrase></para>
-
- <para>Examples of <emphasis>values</emphasis> as you know the term
- from the everyday math are 16, 0.5, and so on, i.e. numbers. In the
- case of computer languages the value term has a wider meaning, as a
- value needn't be a number. For example, take this data-model:</para>
-
- <programlisting role="dataModel" xml:id="example.stdDataModel">(root)
- |
- +- user = "Big Joe"
- |
- +- today = Jul 6, 2007
- |
- +- todayHoliday = false
- |
- +- lotteryNumbers
- | |
- | +- (1st) = 20
- | |
- | +- (2st) = 14
- | |
- | +- (3rd) = 42
- | |
- | +- (4th) = 8
- | |
- | +- (5th) = 15
- |
- +- cargo
- |
- +- name = "coal"
- |
- +- weight = 40
-</programlisting>
-
- <para>We say that the <emphasis>value</emphasis> of the the
- <literal>user</literal> variable is "Big Joe" (a string), the
- <emphasis>value</emphasis> of <literal>today</literal> is Jul 6,
- 2007 (a date), the <emphasis>value</emphasis> of
- <literal>todayHoliday</literal> is false (a boolean, ie. a yes/no
- thing). The <emphasis>value</emphasis> of
- <literal>lotteryNumbers</literal> is the sequence that contains 20,
- 14, 42, 8, 15. Surely <literal>lotteryNumbers</literal> is multiple
- values in the sense that it <emphasis>contains</emphasis> multiple
- values (for example, the 2nd item in it is a the
- <emphasis>value</emphasis> 14), but still,
- <literal>lotteryNumbers</literal> itself is a single value. It's
- like a box that contains many other items; the whole box can be seen
- as a single item. Last not least we also have the
- <emphasis>value</emphasis> of <literal>cargo</literal>, which is a
- hash (a box-like thing again).So, a value is something that can be
- stored in a variable (e.g., in <literal>user</literal> or
- <literal>cargo</literal> or <literal>cargo.name</literal>). But a
- value need not be stored in a variable to be called a value, for
- example we have the value 100 here:</para>
-
- <programlisting role="template"><#if cargo.weight < <emphasis>100</emphasis>>Light cargo</#if></programlisting>
-
- <para>The temporaly result of a calculations are also called values,
- like 20 and 120 when this template is executed (it will print
- 120):</para>
-
- <programlisting role="template">${cargo.weight / 2 + 100}</programlisting>
-
- <para>Explanation for this last: As the result of dividing the two
- values, 40 (the weight of the cargo) and 2, a new value 20 is
- created. Then 100 is added to it, so the value 120 is created. Then
- 120 is printed
- (<literal>${<replaceable>...</replaceable>}</literal>), and the
- template execution goes on and all these values gone.</para>
-
- <para>Certainly now you feel what the value term means.</para>
- </section>
-
- <section>
- <title>What is type?</title>
-
- <para>Values have an important aspect, their type. For example the
- type of the value of the <literal>user</literal> variable is string,
- and the type of the value of the <literal>lotteryNumbers</literal>
- variable is sequence. The type of a value is important because it
- determines to a large extent how and where you can use the value.
- Like <literal>${user / 2}</literal> is an error, but
- <literal>${cargo.weight / 2}</literal> works and prints 20, since
- division only does make sense for a number, but not for a string.
- Or, using dot like in <literal>cargo.name</literal> does make sense
- only if <literal>cargo</literal> is a hash. Or, you can list with
- <literal><#list <replaceable>...</replaceable>></literal>
- sequences only. Or, the condition of <literal><#if
- ...></literal> must be a boolean. And so on.</para>
-
- <note>
- <para>A little terminology... Saying "a boolean" or "a boolean
- value" or "a value of type boolean" are all the same.</para>
- </note>
-
- <para xml:id="topic.multitype"><indexterm>
- <primary>Multi-typed value</primary>
- </indexterm>A value can have multiple types at the same time,
- although it's rarely utilized. For example in the data-model below
- <literal>mouse</literal> is both a string and a hash:</para>
-
- <programlisting role="dataModel">(root)
- |
- +- mouse = "Yerri"
- |
- +- age = 12
- |
- +- color = "brown"</programlisting>
-
- <para>If you merge this template with the above data-model:</para>
-
- <programlisting role="template">${mouse} <#-- uses mouse as a string -->
-${mouse.age} <#-- uses mouse as a hash -->
-${mouse.color} <#-- uses mouse as a hash --></programlisting>
-
- <para>the output will be:</para>
-
- <programlisting role="output">Yerri
-12
-brown</programlisting>
- </section>
-
- <section>
- <title>The data-model is a hash</title>
-
- <para>Looking at the various data-model examples you may already
- realized: the thing marked as "(root)" is just a value of type hash.
- When you write something like <literal>user</literal>, that means
- that you want the "user" variable stored in the root hash. Like if
- you were writing <literal>root.user</literal>, except that there is
- no variable called "root" so that wouldn't work.</para>
-
- <para>Some may get confused by the fact that our example data-model,
- that is, the root hash, contains further hashes and sequences
- (<literal>lotteryNumbers</literal> and <literal>cargo</literal>).
- There is nothing special in that. A hash contains other variables,
- and those variables have a value, which can be a string, a number,
- etc., and of course it can be a hash or sequence as well. Because,
- as it was explained earlier, a sequence or a hash is just a value,
- like a string or a number is.</para>
- </section>
- </section>
-
- <section xml:id="dgui_datamodel_types">
- <title>The types</title>
-
- <para>The suppored types are:</para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para><link linkend="dgui_datamodel_scalar"
- os="">Scalars:</link></para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para>String</para>
- </listitem>
-
- <listitem>
- <para>Number</para>
- </listitem>
-
- <listitem>
- <para>Boolean</para>
- </listitem>
-
- <listitem>
- <para>Date-like (date, time, or date-time)</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><link
- linkend="dgui_datamodel_container">Containers:</link></para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para>Hash</para>
- </listitem>
-
- <listitem>
- <para>Sequence</para>
- </listitem>
-
- <listitem>
- <para>Collection</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Subroutines:</para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para><link linkend="dgui_datamodel_method">Methods and
- functions</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="dgui_datamodel_userdefdir">User-defined
- directives</link></para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Miscellaneous/seldom used:</para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para><link linkend="dgui_datamodel_node">Node</link></para>
- </listitem>
-
- <listitem>
- <para><link linkend="dgui_datamodel_markupoutput">Markup
- output</link></para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- <section xml:id="dgui_datamodel_scalar">
- <title>Scalars</title>
-
- <anchor xml:id="topic.designer.scalarVariable"/>
-
- <para>These are the basic, simple kind of values. They can
- be:</para>
-
- <itemizedlist>
- <listitem>
- <para><indexterm>
- <primary>string</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>String: It is simple text, e.g., the name of a
- product.</para>
-
- <para>If you want to give a string value directly in the
- template, rather than use a variable that comes from the data
- model, you write the text between quotation marks, e.g.,
- <literal>"green mouse"</literal> or <literal>'green
- mouse'</literal>. (More details regarding the syntax can be
- found <link linkend="dgui_template_exp_direct_string"
- xml:lang="">later</link>.)</para>
- </listitem>
-
- <listitem>
- <para><indexterm>
- <primary>number</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Number: For example the price of a product.
- <phrase role="forProgrammers">Whole numbers and non-whole
- numbers are not distinguished; there is only a single number
- type. So for example 3/2 will be always 1.5, and never 1. Just
- like if you are using a calculator.</phrase></para>
-
- <para>If you want to give a numerical value directly in the
- template, then you write for example: <literal>150</literal> or
- <literal>-90.05</literal> or <literal>0.001</literal>. (More
- details regarding the syntax can be found <link
- linkend="dgui_template_exp_direct_number"
- xml:lang="">later</link>.)</para>
- </listitem>
-
- <listitem>
- <para><indexterm>
- <primary>boolean</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Boolean: A boolean value represents a logical true
- or false (yes or no). For example, if a the visitor has been
- logged in or not. Typically you use booleans as the condition of
- the <literal>if</literal> directive, like <literal><#if
- loggedIn
- ><replaceable>...</replaceable></#if></literal> or
- <literal><#if price ==
- 0><replaceable>...</replaceable></#if></literal>; in
- the last case the result of the <literal>price == 0</literal>
- part is a boolean value.</para>
-
- <para>In the templates you can directly specify a boolean with
- the reserved words <literal>true</literal> and
- <literal>false</literal>.</para>
- </listitem>
-
- <listitem>
- <para><indexterm>
- <primary>date</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm><indexterm>
- <primary>time</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm><indexterm>
- <primary>date-time</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Date: A date-like value stores date/time related
- data. It has three variations:</para>
-
- <itemizedlist>
- <listitem>
- <para>Date: Like April 4, 2003. Day precision, no time of
- day part.</para>
- </listitem>
-
- <listitem>
- <para>Time: Like 10:19:18 PM. Millisecond precision, no date
- part.</para>
- </listitem>
-
- <listitem>
- <para>Date-time (sometimes called "time stamp") as April 4,
- 2003 10:19:18 PM. Both date and time, with millisecond
- precision.</para>
- </listitem>
- </itemizedlist>
-
- <para>Unfortunately, because of the limitations of the Java
- platform, FreeMarker sometimes can't decide which parts of the
- date are in use (i.e., if it is date-time, a date or a time).
- The solution for this problem is an advanced topic that will be
- discussed <link
- linkend="ref_builtin_date_datetype">later</link>.</para>
-
- <para>It is possible to define date-like values directly in
- templates, but this is an advanced topic that will be explained
- <link linkend="ref_builtin_string_date">later</link>.</para>
- </listitem>
- </itemizedlist>
-
- <para>Bear in mind that FreeMarker distinguishes strings from
- numbers, booleans and date-like values. For example, while the
- string <literal>"150"</literal> looks like the number
- <literal>150</literal>, a string is still just arbitrary sequence of
- characters, and you can't do arithmetic with it, can't compare it
- with another number, etc.</para>
- </section>
-
- <section xml:id="dgui_datamodel_container">
- <title>Containers</title>
-
- <remark>Re-explanation of hashes and sequences from a more
- ''professional'' viewpoint as earlier, and some meditation about
- them.</remark>
-
- <para>These are the values whose purpose is to contain other
- variables; they are just containers. The contained variables are
- often referred as <emphasis>sub variables</emphasis>. The container
- types are:</para>
-
- <itemizedlist>
- <listitem>
- <para><indexterm>
- <primary>hash</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Hash: Associates a unique lookup name with each of
- its sub variables. The name is an unrestricted string. A hash
- <emphasis>doesn't define an ordering</emphasis> for the sub
- variables in it. That is, there is no such thing as the first
- subvariable, and the second subvariable, etc.; the variables are
- just accessed by name.</para>
- </listitem>
-
- <listitem>
- <para><indexterm>
- <primary>sequence</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Sequence: Associates an integer number with each
- of its sub variables. The first subvariable is associated with
- 0, the second with 1, the third to 2, and so on; the sub
- variables are ordered. These numbers are often called the
- <emphasis>indexes</emphasis> of the sub variables. Sequences are
- usually dense, i.e., all indexes up to the index of the last
- subvariable have an associated subvariable, but it's not
- strictly necessary. The type of the subvariable values need not
- be the same.</para>
- </listitem>
-
- <listitem>
- <para><indexterm>
- <primary>collection</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>Collection: A collection, from the viewpoint of
- the template author, is a restricted sequence. You cannot access
- its size or retrieve its sub variables by index, but they can be
- still listed with the <link
- linkend="ref.directive.list"><literal>list</literal>
- directive</link>.</para>
- </listitem>
- </itemizedlist>
-
- <para>Note that since <link linkend="topic.multitype">a value can
- have multiple types</link>, it is possible for a value to be both a
- hash and a sequence, in which case it would support index-based
- access as well as access by lookup name. However, typically a
- container will be either a hash or a sequence, not both.</para>
-
- <para>As the value of the variables stored in hashes and sequences
- (and collections) can be anything, it can be a hash or sequence (or
- collection) as well. This way you can build arbitrarily deep
- structures.</para>
-
- <para>The data-model itself (or better said the root of it) is a
- hash.</para>
- </section>
-
- <section>
- <title>Subroutines</title>
-
- <section xml:id="dgui_datamodel_method">
- <title>Methods and functions</title>
-
- <anchor xml:id="topic.designer.methodVariable"/>
-
- <indexterm>
- <primary>method</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <para>A value that is a method or a function is used to calculate
- another value, influenced by the parameters you give to it.</para>
-
- <para><phrase role="forProgrammers">For programmer types:
- Methods/functions are first-class values, just like in functional
- programming languages. This means that functions/methods can be
- the parameters or return values of other functions/methods, you
- can assign them to variables, and so on.</phrase></para>
-
- <para>Suppose that programmers have put the method variable
- <literal>avg</literal> in the data-model that can be used to
- calculate the average of numbers. If you give the 3 and 5 as
- parameters when you access <literal>avg</literal>, then you get
- the value 4.</para>
-
- <para>The usage of methods will be explained <link
- linkend="dgui_template_exp_methodcall">later</link>, but perhaps
- this example helps to understand what methods are:</para>
-
- <programlisting role="template">The average of 3 and 5 is: ${avg(3, 5)}
-The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
-The average of the price of a python and an elephant is:
-${avg(animals.python.price, animals.elephant.price)}</programlisting>
-
- <para>this will output:</para>
-
- <programlisting role="output">The average of 3 and 5 is: 4
-The average of 6 and 10 and 20 is: 12
-The average of the price of a python and an elephant is:
-4999.5</programlisting>
-
- <para>What is the difference between a method and a function? As
- far as the template author is concerned, nothing. Well not really
- nothing, as methods typically come from the data-model (<phrase
- role="forProgrammers">as they reflect the methods of Java
- objects</phrase>), and functions are defined in templates (with
- the <link
- linkend="ref.directive.function"><literal>function</literal>
- directive</link> -- an advanced topic), but both can be used on
- the same way.</para>
- </section>
-
- <section xml:id="dgui_datamodel_userdefdir">
- <title>User-defined directives</title>
-
- <indexterm>
- <primary>macro</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <indexterm>
- <primary>directive</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <indexterm>
- <primary>user-defined directive</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <para>A value of this type can be used as user-defined directive
- (with other words, as FreeMarker tag). An user-defined directive
- is a subroutine, something like a little reusable template
- fragment. But this is an advanced topic that will be explained
- <link linkend="dgui_misc_userdefdir">later</link> in its own
- chapter.</para>
-
- <para><phrase role="forProgrammers">For programmer types:
- user-defined directives (such as macros), are first-class values
- too, just like functions/methods are.</phrase></para>
-
- <para>Just to get an idea about user-defined directives (so just
- ignore this if you won't understand), assume we have a variable,
- <literal>box</literal>, whose value is a user-defined directive
- that prints some kind of fancy HTML message box with a title bar
- and a message in it. The <literal>box</literal> variable could be
- used in the template like this (for example):</para>
-
- <programlisting role="template"><@<emphasis>box</emphasis> title="Attention!">
- Too much copy-pasting may leads to
- maintenance headaches.
-</@<emphasis>box</emphasis>></programlisting>
- </section>
-
- <section>
- <title>Function/method versus user-defined directive</title>
-
- <para>This is for advanced users again (so ignore it if you don't
- understand). It's a frequent dilemma if you should use a
- function/method or an user-defined directive to implement
- something. The rule of thumb is: Implement the facility as
- user-defined directive instead of as function/method if:</para>
-
- <itemizedlist>
- <listitem>
- <para>... the purpose of it is generating a piece of the
- output that's not just a single value, and typically involves
- markup. The template language was designed for printing to the
- output directly, piece by piece, as it goes though
- <literal>list</literal> loops, <literal>if</literal>-s, etc.
- Building up a string value in a variable then returning it is
- much less convenient.</para>
- </listitem>
-
- <listitem>
- <para>... it's the side-effect that is important and not the
- return value. For example, a directive whose purpose is to add
- an entry to the server log is like that. (In fact you can't
- have a return value for a user-defined directive, but some
- kind of feedback is still possible by setting non-local
- variables.)</para>
- </listitem>
-
- <listitem>
- <para>... it will do flow control on the caller side (like for
- example <literal>list</literal> or <literal>if</literal>
- directives do). You just can't do that with a
- function/method.</para>
- </listitem>
-
- <listitem>
- <para>... you are using legacy escaping via the
- <literal>escape</literal> directive (instead of <link
- linkend="dgui_misc_autoescaping">auto-escaping</link>), and
- the result contains markup. When you print the result with
- <literal>${<replaceable>...</replaceable>}</literal>, the
- markup will be escaped and thus ruined, but if it's printed by
- a directive call
- (<literal><@<replaceable>...</replaceable>></literal>),
- it won't be.</para>
- </listitem>
- </itemizedlist>
-
- <para>The Java methods of FreeMarker-unaware Java objects are
- normally visible as methods in templates, regardless of the nature
- of the Java method; you have no choice there.</para>
- </section>
- </section>
-
- <section>
- <title>Miscellaneous</title>
-
- <section xml:id="dgui_datamodel_node">
- <title>Nodes</title>
-
- <indexterm>
- <primary>node</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <para>Node variables represent a node in a tree structure, and are
- used mostly with <link linkend="xgui">XML processing</link>, which
- is an advanced, and specialized topic.</para>
-
- <para>Still, a quick overview <emphasis>for advanced
- users</emphasis>: A node is similar to a sequence that stores
- other nodes, which are often referred as the children nodes. A
- node stores a reference to its container node, which is often
- referred as the parent node. The main point of being a node is the
- topological information; other data must be stored by utilizing
- that a value can have multiple types. Like, a value may be both a
- node and a number, in which case it can store a number as the
- "pay-load". Apart from the topological information, a node can
- store some metainformation as well: a node name, a node type
- (string), and a node namespace (string). For example, if the node
- symbolizes a <literal>h1</literal> element in an XHTML document,
- then its name could be <literal>"h1"</literal>, it's node type
- could be <literal>"element"</literal>, and it's namespace could be
- <literal>"http://www.w3.org/1999/xhtml"</literal>. But it's up to
- the designer of the data-model if what meaning these
- metainformations have, and if they are used at all. The way of
- retrieving the topological and metainformations is described <link
- linkend="ref_builtins_node">in a later chapter</link> (that you
- don't have to understand at this point).</para>
- </section>
-
- <section xml:id="dgui_datamodel_markupoutput">
- <title>Markup output</title>
-
- <indexterm>
- <primary>markup output</primary>
-
- <secondary>the FTL value type</secondary>
- </indexterm>
-
- <para>This type is related to <link
- linkend="dgui_misc_autoescaping">auto-escaping mechanism</link>
- introduced FreeMarker 2.3.24; you can <link
- linkend="dgui_misc_autoescaping_movalues">read about this type
- there</link>. But in short, this is a value that stores text
- that's already in the output markup format (like HTML, XML, RTF,
- etc.), and hence must not be auto-escaped.</para>
-
- <para>Values of this type are usually produced inside the
- templates (like with <link
- linkend="ref_builtin_no_esc"><literal>no_esc</literal>
- built-in</link> or <link linkend="ref_directive_assign">output
- capturing assignments</link>), but can also be part of the
- data-model. Such values in the data-model are useful for example
- if you have message resources that sometimes contain the message
- in HTML format, rather than in plain text. If the data-model uses
- HTML markup output values for those messages instead of strings,
- then the template author need not know which messages contain HTML
- and which plain text, as double escaping will be avoided
- automatically when the message is inserted with
- <literal>${<replaceable>...</replaceable>}</literal>.</para>
- </section>
- </section>
- </section>
- </chapter>
-
- <chapter xml:id="dgui_template">
- <title>The Template</title>
-
- <indexterm>
- <primary>template</primary>
- </indexterm>
-
- <note>
- <para>It is assumed that you have already read the <xref
- linkend="dgui_quickstart"/> and the <xref linkend="dgui_datamodel"/>
- chapter.</para>
- </note>
-
- <section xml:id="dgui_template_overallstructure">
- <title>Overall structure</title>
-
- <para>Templates are in fact programs you write in a language called
- <indexterm>
- <primary>FTL</primary>
- </indexterm><emphasis role="term">FTL</emphasis> (for FreeMarker
- Template Language). This is a quite simple programming language
- designed for writing templates and nothing else.</para>
-
- <para>A template (= FTL program) is a mix of the following
- sections:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis role="term">Text</emphasis><indexterm>
- <primary>text</primary>
- </indexterm>: Text that will be printed to the output as
- is.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="term">Interpolation</emphasis><indexterm>
- <primary>interpolation</primary>
- </indexterm>: These sections will be replaced with a calculated
- value in the output. Interpolations are delimited by
- <literal>${</literal> and <literal>}</literal> (or with
- <literal>#{</literal> and <literal>}</literal>, but that shouldn't
- be used anymore; <link
- linkend="ref_depr_numerical_interpolation">see more
- here</link>).</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="term">FTL tags</emphasis><indexterm>
- <primary>FTL tag</primary>
- </indexterm>: FTL tags are a bit similar to HTML tags, but they
- are instructions to FreeMarker and will not be printed to the
- output.</para>
- </listitem>
-
- <listitem>
- <para><emphasis role="term">Comments</emphasis><indexterm>
- <primary>comment</primary>
- </indexterm><indexterm>
- <primary><#--...--></primary>
- </indexterm><indexterm>
- <primary>#</primary>
- </indexterm>: Comments are similar to HTML comments, but they
- are delimited by <literal><#--</literal> and
- <literal>--></literal>. Comments will be ignored by FreeMarker,
- and will not be written to the output.</para>
- </listitem>
- </itemizedlist>
-
- <para>Let's see a concrete template. I have marked the template's
- components with colors: <phrase role="markedText">text</phrase>,
- <phrase role="markedInterpolation">interpolation</phrase>, <phrase
- role="markedFTLTag">FTL tag</phrase>, <phrase
- role="markedComment">comment</phrase>. With the <phrase
- role="markedInvisibleText">[BR]</phrase>-s I intend to visualize the
- <link linkend="gloss.lineBreak">line breaks</link>.</para>
-
- <programlisting role="template"><phrase role="markedText"><html><phrase
- role="markedInvisibleText">[BR]</phrase>
-<head><phrase role="markedInvisibleText">[BR]</phrase>
- <title>Welcome!</title><phrase role="markedInvisibleText">[BR]</phrase>
-</head><phrase role="markedInvisibleText">[BR]</phrase>
-<body><phrase role="markedInvisibleText">[BR]</phrase>
- <phrase role="markedComment"><#-- Greet the user with his/her name --></phrase><phrase
- role="markedInvisibleText">[BR]</phrase>
- <h1>Welcome <phrase role="markedInterpolation">${user}</phrase>!</h1><phrase
- role="markedInvisibleText">[BR]</phrase>
- <p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
- <ul><phrase role="markedInvisibleText">[BR]</phrase>
- <phrase role="markedFTLTag"><#list animals as animal></phrase><phrase
- role="markedInvisibleText">[BR]</phrase>
- <li><phrase role="markedInterpolation">${animal.name}</phrase> for <phrase
- role="markedInterpolation">${animal.price}</phrase> Euros<phrase
- role="markedInvisibleText">[BR]</phrase>
- <phrase role="markedFTLTag"></#list></phrase><phrase
- role="markedInvisibleText">[BR]</phrase>
- </ul><phrase role="markedInvisibleText">[BR]</phrase>
-</body><phrase role="markedInvisibleText">[BR]</phrase>
-</html></phrase></programlisting>
-
- <para>FTL distinguishes upper case and lower case letters. So
- <literal>list</literal> is good directive name, while
- <literal>List</literal> is not. Similarly <literal>${name}</literal>
- is not the same as <literal>${Name}</literal> or
- <literal>${NAME}</literal></para>
-
- <para>It is important to realize that <phrase
- role="markedInterpolation">interpolations</phrase> can be used in
- <phrase role="markedText">text</phrase> (and in string literal
- expressions; see <link
- linkend="dgui_template_exp_stringop_interpolation">later</link>)
- only.</para>
-
- <para>An <phrase role="markedFTLTag">FTL tag</phrase> can't be inside
- another <phrase role="markedFTLTag">FTL tag</phrase> nor inside an
- <phrase role="markedInterpolation">interpolation</phrase>. For example
- this is <emphasis>WRONG</emphasis>: <literal><#if <#include
- 'foo'>='bar'>...</#if></literal></para>
-
- <para><phrase role="markedComment">Comments</phrase> can be placed
- inside <phrase role="markedFTLTag">FTL tags</phrase> and <phrase
- role="markedInterpolation">interpolations</phrase>. For
- example:</para>
-
- <programlisting role="template"><phrase role="markedText"><h1>Welcome <phrase
- role="markedInterpolation">${user <phrase role="markedComment"><#-- The name of user --></phrase>}</phrase>!</h1><phrase
- role="markedInvisibleText">[BR]</phrase>
-<p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
-<ul><phrase role="markedInvisibleText">[BR]</phrase>
-<phrase role="markedFTLTag"><#list <phrase role="markedComment"><#-- some comment... --></phrase> animals as <phrase
- role="markedComment"><#-- again... --></phrase> animal></phrase><phrase
- role="markedInvisibleText">[BR]</phrase></phrase>
-<replaceable>...</replaceable></programlisting>
-
- <note>
- <para>For those of you who have tried the above examples: You may
- notice that some of spaces, tabs and line breaks are missing from
- the template output, even though we said that <phrase
- role="markedText">text</phrase> is printed as is. Don't bother with
- it now. This is because the feature called ''white-space stripping''
- is turned on, and that automatically removes some superfluous
- spaces, tabs and line breaks. This will be explained <link
- linkend="dgui_misc_whitespace">later</link>.</para>
- </note>
- </section>
-
- <section xml:id="dgui_template_directives">
- <title>Directives</title>
-
- <indexterm>
- <primary><#...></primary>
- </indexterm>
-
- <indexterm>
- <primary>#</primary>
- </indexterm>
-
- <anchor xml:id="term.designer.directive"/>
-
- <remark>Note that the Expressions chapter depends on this chapter, and
- Interpolations chapter depends on Expressions chapter. Thus Directives
- must be the first chapter after Basics.</remark>
-
- <para><indexterm>
- <primary>directive</primary>
- </indexterm>You use FTL tags to call <emphasis
- role="term">directives</emphasis>. In the example you have called the
- <literal>list</literal> directive. Syntactically you have done it with
- two tags: <literal><#list animals as animal></literal> and
- <literal></#list></literal>.</para>
-
- <para><indexterm>
- <primary>FTL tag</primary>
- </indexterm>There are two kind of FTL tags:</para>
-
- <itemizedlist>
- <listitem>
- <para>Start-tag:
- <literal><#<replaceable>directivename</replaceable>
- <replaceable>parameters</replaceable>></literal></para>
- </listitem>
-
- <listitem>
- <para>End-tag:
- <literal></#<replaceable>directivename</replaceable>></literal></para>
- </listitem>
- </itemizedlist>
-
- <para>This is similar to HTML or XML syntax, except that the tag name
- starts with <literal>#</literal>. If the directive doesn't have nested
- content (content between the start-tag and the end-tag), you must use
- the start-tag with no end-tag. For example you write <literal><#if
- <replaceable>something</replaceable>><replaceable>...</replaceable></#if></literal>,
- but just <literal><#include
- <replaceable>something</replaceable>></literal> as FreeMarker knows
- that the <literal>include</literal> directive can't have nested
- content.</para>
-
- <para>The format of the
- <literal><replaceable>parameters</replaceable></literal> depends on
- the
- <literal><replaceable>directivename</replaceable></literal>.</para>
-
- <para>In fact there are two types of directives: <link
- linkend="gloss.predefinedDirective">predefined directives</link> and
- <link linkend="gloss.userDefinedDirective">user-defined
- directives</link>. For user-defined directives you use
- <literal>@</literal> instead of <literal>#</literal>, for example
- <literal><@mydirective
- <replaceable>parameters</replaceable>><replaceable>...</replaceable></@mydirective></literal>.
- Further difference is that if the directive has no nested content, you
- must use a tag like <literal><@mydirective
- <replaceable>parameters</replaceable> /></literal>, similarly as in
- XML (e.g. <literal><img <replaceable>...</replaceable>
- /></literal>). But user-defined directives is an advanced topic
- that will be discussed <link
- linkend="dgui_misc_userdefdir">later</link>.</para>
-
- <para>FTL tags, like HTML tags, must be properly nested. So the code
- below is wrong, as the <literal>if</literal> directive is both inside
- and outside of the nested content of the <literal>list</literal>
- directive:</para>
-
- <programlisting role="template"><ul>
-<emphasis><#list animals as animal></emphasis>
- <li>${animal.name} for ${animal.price} Euros
- <emphasis><#if user == "Big Joe"></emphasis>
- (except for you)
-<emphasis></#list></emphasis> <#-- WRONG! The "if" has to be closed first. -->
-<emphasis></#if></emphasis>
-</ul></programlisting>
-
- <para>Note that FreeMarker doesn't care about the nesting of HTML
- tags, only about the nesting of FTL tags. It just sees HTML as flat
- text, it doesn't interpret it in any way.</para>
-
- <para>If you try to use a non-existing directive (e.g., you mistype
- the directive name), FreeMarker will decline to use the template and
- produce an error message.</para>
-
- <para>FreeMarker ignores superfluous <link
- linkend="gloss.whiteSpace">white-space</link> inside FTL tags. So you
- can write this:</para>
-
- <programlisting role="template"><phrase role="markedText"><phrase
- role="markedFTLTag"><#list<phrase role="markedInvisibleText">[BR]</phrase>
- animals as<phrase role="markedInvisibleText">[BR]</phrase>
- animal<phrase role="markedInvisibleText">[BR]</phrase>
-></phrase><phrase role="markedInvisibleText">[BR]</phrase>
-<phrase role="markedInterpolation">${animal.name}</phrase> for <phrase
- role="markedInterpolation">${animal.price}</phrase> Euros<phrase
- role="markedInvisibleText">[BR]</phrase>
-<phrase role="markedFTLTag"></#list ></phrase></phrase></programlisting>
-
- <para>You may not, however, insert white-space between the
- <literal><</literal> or <literal></</literal> and the directive
- name.</para>
-
- <para>The complete list and description of all directives can be found
- in the <xref linkend="ref_directives"/> (but I recommend that you look
- at the chapter about expressions first).</para>
-
- <note>
- <para>FreeMarker can be configured to use <literal>[</literal> and
- <literal>]</literal> instead of <literal><</literal> and
- <literal>></literal> in the FTL tags and FTL comments, like
- <literal>[#if user == "Big
- Joe"]<replaceable>...</replaceable>[/#if]</literal>. For more
- information read: <xref
- linkend="dgui_misc_alternativesyntax"/>.</para>
- </note>
-
- <note>
- <para>FreeMarker can be configured so that it understands predefined
- directives without <literal>#</literal> (like <literal><if user
- == "Big
- Joe"><replaceable>...</replaceable></if></literal>).
- However we don't recommend the usage of this mode. For more
- information read: <xref linkend="ref_depr_oldsyntax"/></para>
- </note>
- </section>
-
- <section xml:id="dgui_template_exp">
- <title>Expressions</title>
-
- <para><indexterm>
- <primary>expression</primary>
- </indexterm>When you supply values for interpolations or directive
- parameters you can use variables or more complex expressions. For
- example, if x is the number 8 and y is 5, the value of <literal>(x +
- y)/2</literal> resolves to the numerical value 6.5.</para>
-
- <para>Before we go into details, let's see some concrete
- examples:</para>
-
- <itemizedlist>
- <listitem>
- <para>When you supply value for interpolations: The usage of
- interpolations is
- <literal>${<replaceable>expression</replaceable>}</literal> where
- expression gives the value you want to insert into the output as
- text. So <literal>${(5 + 8)/2}</literal> prints ``6.5'' to the
- output (or possibly ``6,5'' if the language of your output is not
- US English).</para>
- </listitem>
-
- <listitem>
- <para>When you supply a value for the directive parameter: You
- have already seen the <literal>if</literal> directive in the
- Getting Started section. The syntax of this directive is:
- <literal><#if
- <replaceable>expression</replaceable>><replaceable>...</replaceable></#if></literal>.
- The expression here must evaluate to a boolean value. For example
- in <literal><#if 2 < 3></literal> the <literal>2 <
- 3</literal> (2 is less than 3) is an expression which evaluates to
- <literal>true</literal>.</para>
- </listitem>
- </itemizedlist>
-
- <section xml:id="exp_cheatsheet">
- <title>Quick overview (cheat sheet)</title>
-
- <para>This is a reminder for those of you who already know
- FreeMarker or are just experienced programmers:</para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para><link linkend="dgui_template_exp_direct">Specify values
- directly</link></para>
-
- <itemizedlist spacing="compact">
- <listitem>
- <para><link
- linkend="dgui_template_exp_direct_string">Strings</link>:
- <literal>"Foo"</literal> or <literal>'Foo'</literal> or
- <literal>"It's \"quoted\""</literal> or <literal>'It\'s
- "quoted"'</literal> or
- <literal>r"C:\raw\string"</literal></para>
- </listitem>
-
- <listitem>
- <para><link
- linkend="dgui_template_exp_dir
<TRUNCATED>
[2/5] incubator-freemarker git commit: Made place for the Chinese
manual.
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
new file mode 100644
index 0000000..c561322
--- /dev/null
+++ b/src/manual/en_US/book.xml
@@ -0,0 +1,37479 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<book conformance="docgen" version="5.0" xml:lang="en"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ns5="http://www.w3.org/1999/xhtml"
+ xmlns:ns4="http://www.w3.org/2000/svg"
+ xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+ xmlns:ns="http://docbook.org/ns/docbook">
+ <info>
+ <title>FreeMarker Manual</title>
+
+ <titleabbrev>Manual</titleabbrev>
+
+ <productname>Freemarker 2.3.24 Preview 1</productname>
+ </info>
+
+ <preface role="index.html" xml:id="preface">
+ <title>What is FreeMarker?</title>
+
+ <para>FreeMarker is a <emphasis>template engine</emphasis>: a generic tool
+ to generate text output (HTML web pages, e-mails, configuration files,
+ source code, etc.) based on templates and changing data. It's not an
+ application for end-users in itself, but a Java library, a component that
+ programmers can embed into their products.</para>
+
+ <para>Templates are written in the FreeMarker Template Language (FTL).
+ It's a simple, specialized language, <emphasis>not</emphasis> a full-blown
+ programming language like PHP. You meant to prepare the data to display in
+ a real programming language, like issue database queries and do business
+ calculations, and then the template displays that already prepared data.
+ In the template you are focusing on how to present the data, and outside
+ the template you are focusing on what data to present.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="figures/overview.png"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>This approach is often referred to as the <link
+ linkend="gloss.MVC">MVC (Model View Controller) pattern</link>, and is
+ particularly popular for dynamic Web pages. It helps in separating the Web
+ page designers (HTML authors) from the developers (Java programmers
+ usually). Designers won't face complicated logic in templates, and can
+ change the appearance of a page without programmers having to change or
+ recompile code.</para>
+
+ <para>While FreeMarker was originally created for generating HTML pages in
+ MVC web application frameworks, it isn't bound to servlets or HTML or
+ anything Web-related. It's used in non-web application environments as
+ well.</para>
+
+ <para>FreeMarker is <link
+ xlink:href="http://www.fsf.org/philosophy/free-sw.html">Free</link>,
+ released under the Apache License, Version 2.0.</para>
+ </preface>
+
+ <part xml:id="dgui">
+ <title>Template Author's Guide</title>
+
+ <chapter xml:id="dgui_quickstart">
+ <title>Getting Started</title>
+
+ <para>This chapter is a very rough introduction to FreeMarker. The
+ chapters after this will go over things in much greater detail.
+ Nonetheless, once you have read this chapter, you will be able to write
+ simple but useful FreeMarker templates.</para>
+
+ <section xml:id="dgui_quickstart_basics">
+ <title>Template + data-model = output</title>
+
+ <para>Let's assume that you need a HTML page in a Web shop, similar to
+ this:</para>
+
+ <programlisting role="output"><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>Welcome <emphasis>John Doe</emphasis>!</h1>
+ <p>Our latest product:
+ <a href="<emphasis>products/greenmouse.html</emphasis>"><emphasis>green mouse</emphasis></a>!
+</body>
+</html></programlisting>
+
+ <para>But the user name ("John Doe" above) should depend on who the
+ logged in Web page visitor is, and the latest product should come from
+ a database and thus it potentially changes too. Thus you can't enter
+ these into the HTML directly, you can't use static HTML. Instead, you
+ can use a <emphasis role="term">template</emphasis> of the desired
+ output. The template is the same as the static HTML would be, except
+ that it contains some instructions to FreeMarker that makes it
+ dynamic:</para>
+
+ <programlisting role="template" xml:id="example.first"><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>Welcome <emphasis>${user}</emphasis>!</h1>
+ <p>Our latest product:
+ <a href="<emphasis>${latestProduct.url}</emphasis>"><emphasis>${latestProduct.name}</emphasis></a>!
+</body>
+</html></programlisting>
+
+ <para>The template is stored on the Web server, usually just like the
+ static HTML page would be. But whenever someone visits this page,
+ FreeMarker will step in and transform the template on-the-fly to plain
+ HTML by replacing the
+ <literal>${<replaceable>...</replaceable>}</literal>-s with up-to-date
+ content, and send the result to the visitor's Web browser. So the
+ visitor's Web browser will receive something like the first example
+ HTML (i.e., plain HTML without FreeMarker instructions), and it will
+ not perceive that FreeMarker is used on the server. (Of course, the
+ template file stored on the Web server is not changed by this; the
+ substitutions only appear in the Web server's response.)</para>
+
+ <para>Note that the template doesn't contain the programming logic to
+ find out who the current visitor is, or to query the database to get
+ the latest product. The data to be displayed is prepared outside
+ FreeMarker, usually by parts written in some <quote>real</quote>
+ programming language like Java. The template author needn't know how
+ these values were calculated. In fact, the way these values are
+ calculated can be completely changed while the templates can remain
+ exactly the same, and also, the look of the page can be completely
+ changed without touching anything but the template. This separation of
+ presentation logic and business logic can be especially useful when
+ the template authors (designers) and the programmers are different
+ individuals, but also helps managing application complexity if they
+ are the same person. Keeping templates focused on presentation issues
+ (visual design, layout and formatting) is a key for using template
+ engines like FreeMarker efficiently.</para>
+
+ <para><indexterm>
+ <primary>data-model</primary>
+ </indexterm>The totality of data that was prepared for the template
+ is called the <emphasis role="term">data-model</emphasis>. As far as
+ the template author is concerned, the data-model is a tree-like
+ structure (like folders and files on your hard disk), which, in this
+ case, could be visualized as:</para>
+
+ <programlisting role="dataModel">(root)
+ |
+ +- <emphasis>user</emphasis> = "Big Joe"
+ |
+ +- <emphasis>latestProduct</emphasis>
+ |
+ +- <emphasis>url</emphasis> = "products/greenmouse.html"
+ |
+ +- <emphasis>name</emphasis> = "green mouse"</programlisting>
+
+ <note>
+ <para>The above is just a visualization; the data-model is not in a
+ textual format, it's from Java objects. For the Java programmers,
+ the root is perhaps a Java object with <literal>getUser()</literal>
+ and <literal>getLatestProduct()</literal> methods, or maybe a Java
+ <literal>Map</literal> with <literal>"user"</literal> and
+ <literal>"latestProducts"</literal> keys. Similarly,
+ <literal>latestProduct</literal> is perhaps a Java Object with
+ <literal>getUrl()</literal> and <literal>getName()</literal>
+ methods.</para>
+ </note>
+
+ <para>Earlier, you have picked values from this data-model, with the
+ <literal>user</literal> and <literal>latestProduct.name</literal>
+ expressions. If we go on with the analogy that the data model is like
+ a file system, then <quote>(root)</quote> and
+ <literal>latestProduct</literal> correspond to directories (folders),
+ and <literal>user</literal>, <literal>url</literal> and
+ <literal>name</literal> are files in those directories.</para>
+
+ <para>To recapitulate, a template and a data-model is needed for
+ FreeMarker to generate the output (like the HTML shown first):</para>
+
+ <para><phrase role="markedTemplate">Template</phrase> + <phrase
+ role="markedDataModel">data-model</phrase> = <phrase
+ role="markedOutput">output</phrase></para>
+ </section>
+
+ <section xml:id="dgui_quickstart_datamodel">
+ <title>The data-model at a glance</title>
+
+ <para>As you have seen, the data-model is basically a tree. This tree
+ can be arbitrarily complicated and deep, for example:</para>
+
+ <programlisting role="dataModel"
+ xml:id="example.qStart.dataModelWithHashes">(root)
+ |
+ +- animals
+ | |
+ | +- mouse
+ | | |
+ | | +- size = "small"
+ | | |
+ | | +- price = 50
+ | |
+ | +- elephant
+ | | |
+ | | +- size = "large"
+ | | |
+ | | +- price = 5000
+ | |
+ | +- python
+ | |
+ | +- size = "medium"
+ | |
+ | +- price = 4999
+ |
+ +- message = "It is a test"
+ |
+ +- misc
+ |
+ +- foo = "Something"</programlisting>
+
+ <para>The variables that act like directories (the root,
+ <literal>animals</literal>, <literal>mouse</literal>,
+ <literal>elephant</literal>, <literal>python</literal>,
+ <literal>misc</literal>) are called <emphasis
+ role="term">hashes</emphasis>. Hashes store other variables (the so
+ called <anchor xml:id="topic.dataModel.subVar"/><emphasis>sub
+ variables</emphasis>) by a lookup name (e.g., <quote>animals</quote>,
+ <quote>mouse</quote> or <quote>price</quote>).</para>
+
+ <para>The variables that store a single value
+ (<literal>size</literal>, <literal>price</literal>,
+ <literal>message</literal> and <literal>foo</literal>) are called
+ <emphasis role="term">scalars</emphasis>.</para>
+
+ <para><anchor xml:id="topic.qStart.accessVariables"/>When you want to
+ use a subvariable in a template, you specify its path from the root,
+ and separate the steps with dots. To access the
+ <literal>price</literal> of a <literal>mouse</literal>, you start from
+ the root and go into <literal>animals</literal>, and then go into
+ <literal>mouse</literal> then go into <literal>price</literal>. So you
+ write <literal>animals.mouse.price</literal>.</para>
+
+ <para>Another important kind of variables are <emphasis
+ role="term">sequences</emphasis>. They store subvariables like hashes,
+ but here subvariables doesn't have a name, they are just items in a
+ list. For example, in this data-model, <literal>animals</literal> and
+ <literal>misc.fruits</literal> are sequences:</para>
+
+ <programlisting role="dataModel"
+ xml:id="example.qStart.dataModelWithSequences">(root)
+ |
+ +- animals
+ | |
+ | +- (1st)
+ | | |
+ | | +- name = "mouse"
+ | | |
+ | | +- size = "small"
+ | | |
+ | | +- price = 50
+ | |
+ | +- (2nd)
+ | | |
+ | | +- name = "elephant"
+ | | |
+ | | +- size = "large"
+ | | |
+ | | +- price = 5000
+ | |
+ | +- (3rd)
+ | |
+ | +- name = "python"
+ | |
+ | +- size = "medium"
+ | |
+ | +- price = 4999
+ |
+ +- misc
+ |
+ +- fruits
+ |
+ +- (1st) = "orange"
+ |
+ +- (2nd) = "banana"</programlisting>
+
+ <para>To access a subvariable of a sequence you use a numerical index
+ in square brackets. Indexes start from 0 (it's a programmer tradition
+ to start with 0), thus the index of the 1st item is 0, the index of
+ the 2nd item is 1, and so on. So to get the name of the first animal
+ you write <literal>animals[0].name</literal>. To get the second item
+ in <literal>misc.fruits</literal> (the string
+ <literal>"banana"</literal>) you write
+ <literal>misc.fruits[1]</literal>. (In practice, you usually just walk
+ through sequences in order, not caring about the index, but that will
+ be <link linkend="topic.tutorial.list">shown later</link>.)</para>
+
+ <para>Scalars can be further divided into these categories:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>String: Text, that is, an arbitrary sequence of characters
+ such as ''m'', ''o'', ''u'', ''s'', ''e'' above. For example the
+ <literal>name</literal>-s and <literal>size</literal>-s are
+ strings above.</para>
+ </listitem>
+
+ <listitem>
+ <para>Number: It's a numerical value, like the
+ <literal>price</literal>-s above. The string
+ <literal>"50"</literal> and the number <literal>50</literal> are
+ two totally different things in FreeMarker. The former is just a
+ sequence of two characters (which happens to be readable as a
+ number for humans), while the latter is a numerical value that you
+ can use in arithmetical calculations.</para>
+ </listitem>
+
+ <listitem>
+ <para>Date-like: Either a date-time (stores a date with time of
+ the day), or a date (no time of day), or a time (time of day, no
+ date).</para>
+ </listitem>
+
+ <listitem>
+ <para>Boolean: A true/false (yes/no, on/off, etc.) thing. Like
+ animals could have a <literal>protected</literal> subvariable,
+ which store if the animal is protected or not.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Summary:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The data-model can be visualized as a tree.</para>
+ </listitem>
+
+ <listitem>
+ <para>Scalars store a single value. The value can be a string or a
+ number or a date-time/date/time or a boolean.</para>
+ </listitem>
+
+ <listitem>
+ <para>Hashes are containers that store other variables and
+ associate them with a unique lookup name.</para>
+ </listitem>
+
+ <listitem>
+ <para>Sequences are containers that store other variables in an
+ ordered sequence. The stored variables can be retrieved via their
+ numerical index, starting from 0.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>There are other, more advanced value types that we don't cover
+ here, such as methods and directives.</para>
+ </note>
+ </section>
+
+ <section xml:id="dgui_quickstart_template">
+ <title>The template at a glance</title>
+
+ <para>The simplest template is a plain HTML file (or whatever text
+ file; FreeMarker is not confined to HTML). When the client visits that
+ page, FreeMarker will send that HTML to the client as is. However if
+ you want that page to be more dynamic then you begin to put special
+ parts into the HTML which will be understood by FreeMarker:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>${<replaceable>...</replaceable>}</literal>:
+ FreeMarker will replace it in the output with the actual value of
+ the expression inside the curly brackets. They are called
+ <emphasis role="term">interpolation</emphasis>s.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="term">FTL tags</emphasis> (for FreeMarker
+ Template Language tags): FTL tags are a bit similar to HTML tags,
+ but they are instructions to FreeMarker and will not be printed to
+ the output. The name of these tags start with
+ <literal>#</literal>. (User-defined FTL tags use
+ <literal>@</literal> instead of <literal>#</literal>, but they are
+ an advanced topic.)</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="term">Comments:</emphasis> Comments are
+ similar to HTML comments, but they are delimited by
+ <literal><#--</literal> and <literal>--></literal>. Unlike
+ HTML comments, FTL comments won't get into the output (won't be
+ visible in the page source for the visitor), because FreeMarker
+ skips them.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Anything not an FTL tag or an interpolation or comment is
+ considered as static text, and will not be interpreted by FreeMarker;
+ it is just printed to the output as is.</para>
+
+ <para>With FTL tags you refer to so-called <emphasis
+ role="term">directives</emphasis>. This is the same kind of
+ relationship as between HTML tags (e.g.:
+ <literal><table></literal> and
+ <literal></table></literal>) and HTML elements (e.g., the
+ <literal>table</literal> element) to which you refer to with the HTML
+ tags. (If you don't feel this difference then just take "FTL tag" and
+ "directive" as synonyms.)</para>
+
+ <note>
+ <para>You can easily try writing templates on <link
+ xlink:href="http://freemarker-online.kenshoo.com/">http://freemarker-online.kenshoo.com/</link></para>
+ </note>
+
+ <section>
+ <title>Some basic directives</title>
+
+ <para>Here we will look at some of the most commonly used directives
+ (<link linkend="ref_directives">but there are much
+ more</link>).</para>
+
+ <section>
+ <title>The if directive</title>
+
+ <para>With the <literal>if</literal> directive you can
+ conditionally skip a section of the template. For example, assume
+ that in the <link linkend="example.first">very first
+ example</link> you want to greet your boss, Big Joe, differently
+ than other users:</para>
+
+ <programlisting role="template"><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>
+ Welcome ${user}<emphasis><#if user == "Big Joe"></emphasis>, our beloved leader<emphasis></#if></emphasis>!
+ </h1>
+ <p>Our latest product:
+ <a href="${latestProduct.url}">${latestProduct.name}</a>!
+</body>
+</html></programlisting>
+
+ <para>Here you have told FreeMarker that the <quote>, our beloved
+ leader</quote> should be there only if the value of the variable
+ <literal>user</literal> is equal to the string <literal>"Big
+ Joe"</literal>. In general, things between <literal><#if
+ <replaceable>condition</replaceable>></literal> and
+ <literal></#if></literal> tags are skipped if
+ <literal><replaceable>condition</replaceable></literal> is false
+ (the boolean value).</para>
+
+ <para>Let's look at
+ <literal><replaceable>condition</replaceable></literal> more
+ closely: <literal>==</literal> is an operator that tests if the
+ values at its left and right side are equivalent, and the results
+ is a boolean value, true or false accordingly. On the left side of
+ <literal>==</literal> I have <link
+ linkend="topic.qStart.accessVariables">referenced a
+ variable</link> with the syntax that should be already familiar;
+ this will be replaced with the value of the variable. In general,
+ unquoted words inside directives or interpolations are treated as
+ references to variables. On the right side I have specified a
+ literal string. Literal strings in templates must
+ <emphasis>always</emphasis> be put inside quotation marks.</para>
+
+ <para>This will print <quote>Pythons are free today!</quote> if
+ their price is 0:</para>
+
+ <programlisting role="template"><#if animals.python.price == <emphasis>0</emphasis>>
+ Pythons are free today!
+</#if></programlisting>
+
+ <para>Similarly as earlier when a string was specified directly,
+ here a number is specified directly (<literal>0</literal>). Note
+ that the number is <emphasis>not</emphasis> quoted. If you quoted
+ it (<literal>"0"</literal>), FreeMarker were misinterpret it as a
+ string literal, and because the price to compare it to is number,
+ you get an error.</para>
+
+ <para>This will print "Pythons are not free today!" if their price
+ is not 0:</para>
+
+ <programlisting role="template"><#if animals.python.price <emphasis>!=</emphasis> 0>
+ Pythons are not free today!
+</#if></programlisting>
+
+ <para>As you probably guessed, <literal>!=</literal> means
+ <quote>not equals</quote>.</para>
+
+ <para>You can write things like this too (using <link
+ linkend="example.qStart.dataModelWithHashes">the data-model used
+ to demonstrate hashes</link>):</para>
+
+ <programlisting role="template"><#if <emphasis>animals.python.price < animals.elephant.price</emphasis>>
+ Pythons are cheaper than elephants today.
+</#if></programlisting>
+
+ <para>With the <literal><#else></literal> tag you can
+ specify what to do if the condition is false. For example:</para>
+
+ <programlisting role="template"><#if animals.python.price < animals.elephant.price>
+ Pythons are cheaper than elephants today.
+<emphasis><#else></emphasis>
+ Pythons are not cheaper than elephants today.
+</#if></programlisting>
+
+ <para>This prints <quote>Pythons are cheaper than elephants
+ today.</quote> if the price of python is less than the price of
+ elephant, or else it prints <quote>Pythons are not cheaper than
+ elephants today.</quote> You can refine this further by using
+ <literal>elseif</literal>:</para>
+
+ <programlisting role="template"><#if animals.python.price < animals.elephant.price>
+ Pythons are cheaper than elephants today.
+<emphasis><#elseif animals.elephant.price < animals.python.price></emphasis>
+ Elephants are cheaper than pythons today.
+<#else>
+ Elephants and pythons cost the same today.
+</#if></programlisting>
+
+ <para>If you have a variable with boolean value (a true/false
+ thing) then you can use it directly as the
+ <literal><replaceable>condition</replaceable></literal> of
+ <literal>if</literal>:</para>
+
+ <programlisting role="template"><#if animals.python.protected>
+ Pythons are protected animals!
+</#if></programlisting>
+ </section>
+
+ <section>
+ <title>The list directive</title>
+
+ <anchor xml:id="topic.tutorial.list"/>
+
+ <para>This is needed when you want to list something. For example
+ if you merge this template with the <link
+ linkend="example.qStart.dataModelWithSequences">data-model used
+ earlier to demonstrate sequences</link>:</para>
+
+ <programlisting role="template"><p>We have these animals:
+<table border=1>
+ <emphasis><#list animals as animal></emphasis>
+ <tr><td>${<emphasis>animal</emphasis>.name}<td>${<emphasis>animal</emphasis>.price} Euros
+ <emphasis></#list></emphasis>
+</table></programlisting>
+
+ <para>then the output will be:</para>
+
+ <programlisting role="output"><p>We have these animals:
+<table border=1>
+ <emphasis><tr><td>mouse<td>50 Euros
+ <tr><td>elephant<td>5000 Euros
+ <tr><td>python<td>4999 Euros</emphasis>
+</table></programlisting>
+
+ <para>The generic form of the <literal>list</literal> directive
+ is:<literal> <#list <replaceable>sequence</replaceable> as
+ <replaceable>loopVariable</replaceable>><replaceable>repeatThis</replaceable></#list></literal>.
+ The <literal><replaceable>repeatThis</replaceable></literal> part
+ will be repeated for each item in the sequence that you have
+ specified with
+ <literal><replaceable>sequence</replaceable></literal>, one after
+ the other, starting from the first item. In all repetitions
+ <literal><replaceable>loopVariable</replaceable></literal> will
+ hold the value of the current item. This variable exists only
+ between the <literal><#list
+ <replaceable>...</replaceable>></literal> and
+ <literal></#list></literal> tags.</para>
+
+ <para>The <literal><replaceable>sequence</replaceable></literal>
+ can be any kind of expression, like we could list the fruits of
+ the example data model like this:</para>
+
+ <programlisting role="template"><ul>
+<emphasis><#list misc.fruits as fruit></emphasis>
+ <li>${fruit}
+<emphasis></#list></emphasis>
+</ul></programlisting>
+
+ <para>The <literal>misc.fruits</literal> expression should be
+ familiar to you; it <link
+ linkend="topic.qStart.accessVariables">references a variable in
+ the data-model</link>.</para>
+
+ <para>A problem with the above example is that if we happen to
+ have 0 fruits, it will still print an empty
+ <literal><ul></ul></literal> instead of just nothing.
+ To avoid that, you can use this form of
+ <literal>list</literal>:</para>
+
+ <programlisting role="template"><#list misc.fruits>
+ <ul>
+ <emphasis> <#items as fruit></emphasis>
+ <li>${fruit}
+ <emphasis> </#items></emphasis>
+ </ul>
+</#list></programlisting>
+
+ <para>Here, the <literal>list</literal> directive represents the
+ listing as a whole, and only the part inside the
+ <literal>items</literal> directive is repeated for each fruit. If
+ we have 0 fruits, everything inside <literal>list</literal> is
+ skipped, hence we will not have <literal>ul</literal> tags in
+ case.</para>
+
+ <para>Another frequent listing-related task: let's list the fruits
+ separating them with something, like comma:</para>
+
+ <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<emphasis><#sep>, </emphasis></#list></programlisting>
+
+ <programlisting role="output"><p>Fruits: orange, banana</programlisting>
+
+ <para>The section covered by <literal>sep</literal> (which we
+ could be written like this too:
+ <literal><replaceable>...</replaceable><#sep>,
+ </#sep></#list></literal>) will be only executed when
+ there will be a next item. Hence there's no comma after the last
+ fruit.</para>
+
+ <para>Here again, what's if we have 0 fruits? Just printing
+ <quote>Fruits:</quote> and then nothing is awkward. A
+ <literal>list</literal>, just like an <literal>if</literal>, can
+ have an <literal>else</literal>, which is executed if there were 0
+ list items:</para>
+
+ <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, <emphasis><#else>None</emphasis></#list></programlisting>
+
+ <note>
+ <para>As a matter of fact, this simplistic example could be
+ written like this, but it uses language devices that are off
+ topic here:</para>
+
+ <programlisting role="template"><p>Fruits: ${fruits?join(", ", "None")}</programlisting>
+ </note>
+
+ <para>All these directives (<literal>list</literal>,
+ <literal>items</literal>, <literal>sep</literal>,
+ <literal>else</literal>) can be used together:</para>
+
+ <programlisting role="template"><#list misc.fruits>
+ <p>Fruits:
+ <ul>
+ <#items as fruit>
+ <li>${fruit}<#sep> and</#sep>
+ </#items>
+ </ul>
+<#else>
+ <p>We have no fruits.
+</#list></programlisting>
+
+ <note>
+ <para>You can read more about these directives <link
+ linkend="ref_directive_list">in the Reference</link>.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>The include directive</title>
+
+ <para>With the <literal>include</literal> directive you can insert
+ the content of another file into the template.</para>
+
+ <para>Suppose you have to show the same copyright notice on
+ several pages. You can create a file that contains the copyright
+ notice only, and insert that file everywhere where you need that
+ copyright notice. Say, you store this copyright notice in
+ <literal>copyright_footer.html</literal>:</para>
+
+ <programlisting role="template"><hr>
+<i>
+Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
+<br>
+All Rights Reserved.
+</i></programlisting>
+
+ <para>Whenever you need that file you simply insert it with the
+ <literal>include</literal> directive:</para>
+
+ <programlisting role="template"><html>
+<head>
+ <title>Test page</title>
+</head>
+<body>
+ <h1>Test page</h1>
+ <p>Blah blah...
+<emphasis> <#include "/copyright_footer.html"></emphasis>
+</body>
+</html></programlisting>
+
+ <para>and the output will be:</para>
+
+ <programlisting role="output"><html>
+<head>
+ <title>Test page</title>
+</head>
+<body>
+ <h1>Test page</h1>
+ <p>Blah blah...
+<emphasis><hr>
+<i>
+Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
+<br>
+All Rights Reserved.
+</i></emphasis>
+</body>
+</html></programlisting>
+
+ <para>If you change the <literal>copyright_footer.html</literal>,
+ then the visitor will see the new copyright notice on all
+ pages.</para>
+
+ <note>
+ <para>A much more powerful way of reusing snippets is using
+ macros, but that's an advanced topic <link
+ linkend="dgui_misc_userdefdir">discussed later</link>.</para>
+ </note>
+ </section>
+ </section>
+
+ <section>
+ <title>Using directives together</title>
+
+ <para>You can use directives as many times on a page as you want,
+ and you can nest directives into each other freely. For example,
+ here you nest <literal>if</literal> directive inside a
+ <literal>list</literal> directive:</para>
+
+ <programlisting role="template"><emphasis><#list animals as animal></emphasis>
+ <div<emphasis><#if animal.protected></emphasis><emphasis> </emphasis>class="protected"<emphasis></#if></emphasis>>
+ ${animal.name} for ${animal.price} Euros
+ </div>
+<emphasis></#list></emphasis></programlisting>
+
+ <para>Note that since FreeMarker does not interpret text outside FTL
+ tags, interpolations and FTL comments, above you could use the FTL
+ tags inside a HTML attributes without problem.</para>
+ </section>
+
+ <section>
+ <title>Using built-ins</title>
+
+ <para>The so called built-ins are like subvariables (or rather like
+ methods, if you know that Java term) that aren't coming coming from
+ the data-model, but added by FreeMarker to the values. To make it
+ unambiguous where the subvarable comes from, to access them you have
+ to use <literal>?</literal> (question mark) instead of
+ <literal>.</literal> (dot). <anchor
+ xml:id="topic.commonlyUsedBuiltIns"/>Examples with some of the most
+ commonly used built-ins:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>user?upper_case</literal> gives the upper case
+ version of the value of <literal>user</literal> (like
+ <quote>JOHN DOE</quote> instead of <quote>John
+ Doe</quote>)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>animal.name?cap_first</literal> give the
+ <literal>animal.name</literal> with its first letter converted
+ to upper case (like <quote>Mouse</quote> instead of
+ <quote>mouse</quote>)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>user?length</literal> gives the number of
+ <emphasis>characters</emphasis> in the value of
+ <literal>user</literal> (8 for <quote>John Doe</quote>)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>animals?size</literal> gives the number of
+ <emphasis>items</emphasis> in the <literal>animals</literal>
+ sequence (3 in our example data-model)</para>
+ </listitem>
+
+ <listitem>
+ <para>If you are between <literal><#list animals as
+ animal></literal> and the corresponding
+ <literal></#list></literal> tag:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>animal?index</literal> gives the 0-based
+ index of <literal>animal</literal> inside
+ <literal>animals</literal></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>animal?counter</literal> is like
+ <literal>index</literal>, but gives the 1-based index</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>animal?item_parity</literal> gives the
+ strings <quote>odd</quote> or <quote>even</quote>, depending
+ on the current counter parity. This is commonly used for
+ coloring rows with alternating colors, like in
+ <literal><td
+ class="${animal?item_parity}Row"></literal>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>Some built-ins require parameters to specify the behavior
+ more, for example:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>animal.protected?string("Y", "N")</literal>
+ return the string <quote>Y</quote> or <quote>N</quote> depending
+ on the boolean value of
+ <literal>animal.protected</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>animal?item_cycle('lightRow',
+ 'darkRow')</literal> is the more generic variant of
+ <literal>item_parity</literal> from earlier.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>fruits?join(", ")</literal>: converts the list to
+ a string by concatenating items, and inserting the parameter
+ separator between each items (like <quote>orange,
+ banana</quote>)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>user?starts_with("J")</literal> gives boolean
+ true of false depending on if <literal>user</literal> starts
+ with the letter <quote>J</quote> or not.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Built-in applications can be chained, like
+ <literal>fruits?join(", ")?upper_case</literal> will first convert
+ the list a to a string, then converts it to upper case. (This is
+ just like you can chain <literal>.</literal>-s (dots) too.)</para>
+
+ <para>You can find the <link linkend="ref_builtins">full set of
+ built-ins in the Reference</link>.</para>
+ </section>
+
+ <section>
+ <title>Dealing with missing variables</title>
+
+ <para>The data-model often has variables that are optional (i.e.,
+ sometimes missing). To spot some typical human mistakes, FreeMarker
+ doesn't tolerate the referring to missing variables, unless you tell
+ explicitly what to do if the variable is missing. Here we will show
+ the two most typical ways of doing that.</para>
+
+ <para><phrase role="forProgrammers">Note for programmers: A
+ non-existent variable and a variable with <literal>null</literal>
+ value is the same for FreeMarker, so the "missing" term used here
+ covers both cases.</phrase></para>
+
+ <para>Wherever you refer to a variable, you can specify a default
+ value for the case the variable is missing, by following the
+ variable name with a <literal>!</literal> and the default value.
+ Like in the following example, when <literal>user</literal> is
+ missing from data model, the template will behave like if
+ <literal>user</literal>'s value were the string
+ <literal>"visitor"</literal>. (When <literal>user</literal> isn't
+ missing, this template behaves exactly like with
+ <literal>${user}</literal>):</para>
+
+ <programlisting role="template"><h1>Welcome ${user<emphasis>!"visitor"</emphasis>}!</h1></programlisting>
+
+ <para>You can ask whether a variable isn't missing by putting
+ <literal>??</literal> after its name. Combining this with the
+ already introduced <literal>if</literal> directive you can skip the
+ whole greeting if the <literal>user</literal> variable is
+ missing:</para>
+
+ <programlisting role="template"><#if <emphasis>user??</emphasis>><h1>Welcome ${user}!</h1></#if></programlisting>
+
+ <para>Regarding variable accessing with multiple steps, like
+ <literal>animals.python.price</literal>, writing
+ <literal>animals.python.price!0</literal> is correct only if
+ <literal>animals.python</literal> is never missing and only the last
+ subvariable, <literal>price</literal>, is possibly missing (in which
+ case here we assume it's <literal>0</literal>). If
+ <literal>animals</literal> or <literal>python</literal> is missing,
+ the template processing will stop with an "undefined variable"
+ error. To prevent that, you have to write
+ <literal>(animals.python.price)!0</literal>. In that case the
+ expression will be <literal>0</literal> even if
+ <literal>animals</literal> or <literal>python</literal> is missing.
+ Same logic goes for <literal>??</literal>;
+ <literal>animals.python.price??</literal> versus
+ <literal>(animals.python.price)??</literal>.</para>
+ </section>
+
+ <section xml:id="dgui_quickstart_template_autoescaping">
+ <title>Escaping for HTML, XML and other markup</title>
+
+ <para>Let's say the template generates HTML, and you insert values
+ with <literal>${<replaceable>...</replaceable>}</literal> that are
+ plain text (not HTML), like company names coming from a database.
+ Characters that has special meaning in HTML must be
+ <emphasis>escaped</emphasis> in such values, like if
+ <literal>name</literal> is <quote>Someone & Co.</quote> then
+ <literal>${name}</literal> should print <quote>Someone
+ <emphasis>&amp;</emphasis> Co.</quote>.</para>
+
+ <para>FreeMarker automatically escapes all values printed with
+ <literal>${<replaceable>...</replaceable>}</literal> <emphasis>if
+ it's properly configured</emphasis> (that's the responsibility of
+ the programmers; <link
+ linkend="pgui_config_outputformatsautoesc">see here how</link>). The
+ recommended practice is using <literal>ftlh</literal> file extension
+ to activate HTML auto-escaping, and <literal>ftlx</literal> file
+ extension to activate XML auto-escaping.</para>
+
+ <para>You can try if auto-escaping is on like
+ <literal>${"<"}</literal> (for HTML or XML escaping). If it's
+ not, and the configuration won't be adjusted, add this as the very
+ first line of the template:</para>
+
+ <programlisting role="template"><#ftl output_format="HTML"></programlisting>
+
+ <para>(Use <literal>"XML"</literal> instead of
+ <literal>"HTML"</literal> above if you generate XML.)</para>
+
+ <para>If the string value to print deliberately contains markup,
+ auto-escaping must be prevented like
+ <literal>${<replaceable>value</replaceable>?no_esc}</literal>.</para>
+
+ <para>You can find out much more about auto-escaping and output
+ formats <link linkend="dgui_misc_autoescaping">here...</link></para>
+
+ <note>
+ <para>The kind of automatic escaping described here requires at
+ least FreeMarker 2.3.24. If you have to use an earlier version,
+ use the deprecated <link
+ linkend="ref_directive_escape"><literal>escape</literal>
+ directive</link> instead.</para>
+ </note>
+ </section>
+ </section>
+ </chapter>
+
+ <chapter xml:id="dgui_datamodel">
+ <title>Values, Types</title>
+
+ <section xml:id="dgui_datamodel_basics">
+ <title>Basics</title>
+
+ <note>
+ <para>It is assumed that you have already read the <xref
+ linkend="dgui_quickstart"/> chapter.</para>
+ </note>
+
+ <para>Understanding the concept of values and types is crucial for the
+ understanding of data-models. However, the concept of values and types
+ is not confined to data-models, as you will see.</para>
+
+ <section xml:id="topic.value">
+ <title>What is a value?</title>
+
+ <indexterm>
+ <primary>value</primary>
+ </indexterm>
+
+ <para><phrase role="forProgrammers">Real programmers can safely skip
+ this section.</phrase></para>
+
+ <para>Examples of <emphasis>values</emphasis> as you know the term
+ from the everyday math are 16, 0.5, and so on, i.e. numbers. In the
+ case of computer languages the value term has a wider meaning, as a
+ value needn't be a number. For example, take this data-model:</para>
+
+ <programlisting role="dataModel" xml:id="example.stdDataModel">(root)
+ |
+ +- user = "Big Joe"
+ |
+ +- today = Jul 6, 2007
+ |
+ +- todayHoliday = false
+ |
+ +- lotteryNumbers
+ | |
+ | +- (1st) = 20
+ | |
+ | +- (2st) = 14
+ | |
+ | +- (3rd) = 42
+ | |
+ | +- (4th) = 8
+ | |
+ | +- (5th) = 15
+ |
+ +- cargo
+ |
+ +- name = "coal"
+ |
+ +- weight = 40
+</programlisting>
+
+ <para>We say that the <emphasis>value</emphasis> of the the
+ <literal>user</literal> variable is "Big Joe" (a string), the
+ <emphasis>value</emphasis> of <literal>today</literal> is Jul 6,
+ 2007 (a date), the <emphasis>value</emphasis> of
+ <literal>todayHoliday</literal> is false (a boolean, ie. a yes/no
+ thing). The <emphasis>value</emphasis> of
+ <literal>lotteryNumbers</literal> is the sequence that contains 20,
+ 14, 42, 8, 15. Surely <literal>lotteryNumbers</literal> is multiple
+ values in the sense that it <emphasis>contains</emphasis> multiple
+ values (for example, the 2nd item in it is a the
+ <emphasis>value</emphasis> 14), but still,
+ <literal>lotteryNumbers</literal> itself is a single value. It's
+ like a box that contains many other items; the whole box can be seen
+ as a single item. Last not least we also have the
+ <emphasis>value</emphasis> of <literal>cargo</literal>, which is a
+ hash (a box-like thing again).So, a value is something that can be
+ stored in a variable (e.g., in <literal>user</literal> or
+ <literal>cargo</literal> or <literal>cargo.name</literal>). But a
+ value need not be stored in a variable to be called a value, for
+ example we have the value 100 here:</para>
+
+ <programlisting role="template"><#if cargo.weight < <emphasis>100</emphasis>>Light cargo</#if></programlisting>
+
+ <para>The temporaly result of a calculations are also called values,
+ like 20 and 120 when this template is executed (it will print
+ 120):</para>
+
+ <programlisting role="template">${cargo.weight / 2 + 100}</programlisting>
+
+ <para>Explanation for this last: As the result of dividing the two
+ values, 40 (the weight of the cargo) and 2, a new value 20 is
+ created. Then 100 is added to it, so the value 120 is created. Then
+ 120 is printed
+ (<literal>${<replaceable>...</replaceable>}</literal>), and the
+ template execution goes on and all these values gone.</para>
+
+ <para>Certainly now you feel what the value term means.</para>
+ </section>
+
+ <section>
+ <title>What is type?</title>
+
+ <para>Values have an important aspect, their type. For example the
+ type of the value of the <literal>user</literal> variable is string,
+ and the type of the value of the <literal>lotteryNumbers</literal>
+ variable is sequence. The type of a value is important because it
+ determines to a large extent how and where you can use the value.
+ Like <literal>${user / 2}</literal> is an error, but
+ <literal>${cargo.weight / 2}</literal> works and prints 20, since
+ division only does make sense for a number, but not for a string.
+ Or, using dot like in <literal>cargo.name</literal> does make sense
+ only if <literal>cargo</literal> is a hash. Or, you can list with
+ <literal><#list <replaceable>...</replaceable>></literal>
+ sequences only. Or, the condition of <literal><#if
+ ...></literal> must be a boolean. And so on.</para>
+
+ <note>
+ <para>A little terminology... Saying "a boolean" or "a boolean
+ value" or "a value of type boolean" are all the same.</para>
+ </note>
+
+ <para xml:id="topic.multitype"><indexterm>
+ <primary>Multi-typed value</primary>
+ </indexterm>A value can have multiple types at the same time,
+ although it's rarely utilized. For example in the data-model below
+ <literal>mouse</literal> is both a string and a hash:</para>
+
+ <programlisting role="dataModel">(root)
+ |
+ +- mouse = "Yerri"
+ |
+ +- age = 12
+ |
+ +- color = "brown"</programlisting>
+
+ <para>If you merge this template with the above data-model:</para>
+
+ <programlisting role="template">${mouse} <#-- uses mouse as a string -->
+${mouse.age} <#-- uses mouse as a hash -->
+${mouse.color} <#-- uses mouse as a hash --></programlisting>
+
+ <para>the output will be:</para>
+
+ <programlisting role="output">Yerri
+12
+brown</programlisting>
+ </section>
+
+ <section>
+ <title>The data-model is a hash</title>
+
+ <para>Looking at the various data-model examples you may already
+ realized: the thing marked as "(root)" is just a value of type hash.
+ When you write something like <literal>user</literal>, that means
+ that you want the "user" variable stored in the root hash. Like if
+ you were writing <literal>root.user</literal>, except that there is
+ no variable called "root" so that wouldn't work.</para>
+
+ <para>Some may get confused by the fact that our example data-model,
+ that is, the root hash, contains further hashes and sequences
+ (<literal>lotteryNumbers</literal> and <literal>cargo</literal>).
+ There is nothing special in that. A hash contains other variables,
+ and those variables have a value, which can be a string, a number,
+ etc., and of course it can be a hash or sequence as well. Because,
+ as it was explained earlier, a sequence or a hash is just a value,
+ like a string or a number is.</para>
+ </section>
+ </section>
+
+ <section xml:id="dgui_datamodel_types">
+ <title>The types</title>
+
+ <para>The suppored types are:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><link linkend="dgui_datamodel_scalar"
+ os="">Scalars:</link></para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>String</para>
+ </listitem>
+
+ <listitem>
+ <para>Number</para>
+ </listitem>
+
+ <listitem>
+ <para>Boolean</para>
+ </listitem>
+
+ <listitem>
+ <para>Date-like (date, time, or date-time)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><link
+ linkend="dgui_datamodel_container">Containers:</link></para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Hash</para>
+ </listitem>
+
+ <listitem>
+ <para>Sequence</para>
+ </listitem>
+
+ <listitem>
+ <para>Collection</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Subroutines:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><link linkend="dgui_datamodel_method">Methods and
+ functions</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="dgui_datamodel_userdefdir">User-defined
+ directives</link></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Miscellaneous/seldom used:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><link linkend="dgui_datamodel_node">Node</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="dgui_datamodel_markupoutput">Markup
+ output</link></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <section xml:id="dgui_datamodel_scalar">
+ <title>Scalars</title>
+
+ <anchor xml:id="topic.designer.scalarVariable"/>
+
+ <para>These are the basic, simple kind of values. They can
+ be:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><indexterm>
+ <primary>string</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>String: It is simple text, e.g., the name of a
+ product.</para>
+
+ <para>If you want to give a string value directly in the
+ template, rather than use a variable that comes from the data
+ model, you write the text between quotation marks, e.g.,
+ <literal>"green mouse"</literal> or <literal>'green
+ mouse'</literal>. (More details regarding the syntax can be
+ found <link linkend="dgui_template_exp_direct_string"
+ xml:lang="">later</link>.)</para>
+ </listitem>
+
+ <listitem>
+ <para><indexterm>
+ <primary>number</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Number: For example the price of a product.
+ <phrase role="forProgrammers">Whole numbers and non-whole
+ numbers are not distinguished; there is only a single number
+ type. So for example 3/2 will be always 1.5, and never 1. Just
+ like if you are using a calculator.</phrase></para>
+
+ <para>If you want to give a numerical value directly in the
+ template, then you write for example: <literal>150</literal> or
+ <literal>-90.05</literal> or <literal>0.001</literal>. (More
+ details regarding the syntax can be found <link
+ linkend="dgui_template_exp_direct_number"
+ xml:lang="">later</link>.)</para>
+ </listitem>
+
+ <listitem>
+ <para><indexterm>
+ <primary>boolean</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Boolean: A boolean value represents a logical true
+ or false (yes or no). For example, if a the visitor has been
+ logged in or not. Typically you use booleans as the condition of
+ the <literal>if</literal> directive, like <literal><#if
+ loggedIn
+ ><replaceable>...</replaceable></#if></literal> or
+ <literal><#if price ==
+ 0><replaceable>...</replaceable></#if></literal>; in
+ the last case the result of the <literal>price == 0</literal>
+ part is a boolean value.</para>
+
+ <para>In the templates you can directly specify a boolean with
+ the reserved words <literal>true</literal> and
+ <literal>false</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><indexterm>
+ <primary>date</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm><indexterm>
+ <primary>time</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm><indexterm>
+ <primary>date-time</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Date: A date-like value stores date/time related
+ data. It has three variations:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Date: Like April 4, 2003. Day precision, no time of
+ day part.</para>
+ </listitem>
+
+ <listitem>
+ <para>Time: Like 10:19:18 PM. Millisecond precision, no date
+ part.</para>
+ </listitem>
+
+ <listitem>
+ <para>Date-time (sometimes called "time stamp") as April 4,
+ 2003 10:19:18 PM. Both date and time, with millisecond
+ precision.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Unfortunately, because of the limitations of the Java
+ platform, FreeMarker sometimes can't decide which parts of the
+ date are in use (i.e., if it is date-time, a date or a time).
+ The solution for this problem is an advanced topic that will be
+ discussed <link
+ linkend="ref_builtin_date_datetype">later</link>.</para>
+
+ <para>It is possible to define date-like values directly in
+ templates, but this is an advanced topic that will be explained
+ <link linkend="ref_builtin_string_date">later</link>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Bear in mind that FreeMarker distinguishes strings from
+ numbers, booleans and date-like values. For example, while the
+ string <literal>"150"</literal> looks like the number
+ <literal>150</literal>, a string is still just arbitrary sequence of
+ characters, and you can't do arithmetic with it, can't compare it
+ with another number, etc.</para>
+ </section>
+
+ <section xml:id="dgui_datamodel_container">
+ <title>Containers</title>
+
+ <remark>Re-explanation of hashes and sequences from a more
+ ''professional'' viewpoint as earlier, and some meditation about
+ them.</remark>
+
+ <para>These are the values whose purpose is to contain other
+ variables; they are just containers. The contained variables are
+ often referred as <emphasis>sub variables</emphasis>. The container
+ types are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><indexterm>
+ <primary>hash</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Hash: Associates a unique lookup name with each of
+ its sub variables. The name is an unrestricted string. A hash
+ <emphasis>doesn't define an ordering</emphasis> for the sub
+ variables in it. That is, there is no such thing as the first
+ subvariable, and the second subvariable, etc.; the variables are
+ just accessed by name.</para>
+ </listitem>
+
+ <listitem>
+ <para><indexterm>
+ <primary>sequence</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Sequence: Associates an integer number with each
+ of its sub variables. The first subvariable is associated with
+ 0, the second with 1, the third to 2, and so on; the sub
+ variables are ordered. These numbers are often called the
+ <emphasis>indexes</emphasis> of the sub variables. Sequences are
+ usually dense, i.e., all indexes up to the index of the last
+ subvariable have an associated subvariable, but it's not
+ strictly necessary. The type of the subvariable values need not
+ be the same.</para>
+ </listitem>
+
+ <listitem>
+ <para><indexterm>
+ <primary>collection</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>Collection: A collection, from the viewpoint of
+ the template author, is a restricted sequence. You cannot access
+ its size or retrieve its sub variables by index, but they can be
+ still listed with the <link
+ linkend="ref.directive.list"><literal>list</literal>
+ directive</link>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note that since <link linkend="topic.multitype">a value can
+ have multiple types</link>, it is possible for a value to be both a
+ hash and a sequence, in which case it would support index-based
+ access as well as access by lookup name. However, typically a
+ container will be either a hash or a sequence, not both.</para>
+
+ <para>As the value of the variables stored in hashes and sequences
+ (and collections) can be anything, it can be a hash or sequence (or
+ collection) as well. This way you can build arbitrarily deep
+ structures.</para>
+
+ <para>The data-model itself (or better said the root of it) is a
+ hash.</para>
+ </section>
+
+ <section>
+ <title>Subroutines</title>
+
+ <section xml:id="dgui_datamodel_method">
+ <title>Methods and functions</title>
+
+ <anchor xml:id="topic.designer.methodVariable"/>
+
+ <indexterm>
+ <primary>method</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <para>A value that is a method or a function is used to calculate
+ another value, influenced by the parameters you give to it.</para>
+
+ <para><phrase role="forProgrammers">For programmer types:
+ Methods/functions are first-class values, just like in functional
+ programming languages. This means that functions/methods can be
+ the parameters or return values of other functions/methods, you
+ can assign them to variables, and so on.</phrase></para>
+
+ <para>Suppose that programmers have put the method variable
+ <literal>avg</literal> in the data-model that can be used to
+ calculate the average of numbers. If you give the 3 and 5 as
+ parameters when you access <literal>avg</literal>, then you get
+ the value 4.</para>
+
+ <para>The usage of methods will be explained <link
+ linkend="dgui_template_exp_methodcall">later</link>, but perhaps
+ this example helps to understand what methods are:</para>
+
+ <programlisting role="template">The average of 3 and 5 is: ${avg(3, 5)}
+The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
+The average of the price of a python and an elephant is:
+${avg(animals.python.price, animals.elephant.price)}</programlisting>
+
+ <para>this will output:</para>
+
+ <programlisting role="output">The average of 3 and 5 is: 4
+The average of 6 and 10 and 20 is: 12
+The average of the price of a python and an elephant is:
+4999.5</programlisting>
+
+ <para>What is the difference between a method and a function? As
+ far as the template author is concerned, nothing. Well not really
+ nothing, as methods typically come from the data-model (<phrase
+ role="forProgrammers">as they reflect the methods of Java
+ objects</phrase>), and functions are defined in templates (with
+ the <link
+ linkend="ref.directive.function"><literal>function</literal>
+ directive</link> -- an advanced topic), but both can be used on
+ the same way.</para>
+ </section>
+
+ <section xml:id="dgui_datamodel_userdefdir">
+ <title>User-defined directives</title>
+
+ <indexterm>
+ <primary>macro</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>directive</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>user-defined directive</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <para>A value of this type can be used as user-defined directive
+ (with other words, as FreeMarker tag). An user-defined directive
+ is a subroutine, something like a little reusable template
+ fragment. But this is an advanced topic that will be explained
+ <link linkend="dgui_misc_userdefdir">later</link> in its own
+ chapter.</para>
+
+ <para><phrase role="forProgrammers">For programmer types:
+ user-defined directives (such as macros), are first-class values
+ too, just like functions/methods are.</phrase></para>
+
+ <para>Just to get an idea about user-defined directives (so just
+ ignore this if you won't understand), assume we have a variable,
+ <literal>box</literal>, whose value is a user-defined directive
+ that prints some kind of fancy HTML message box with a title bar
+ and a message in it. The <literal>box</literal> variable could be
+ used in the template like this (for example):</para>
+
+ <programlisting role="template"><@<emphasis>box</emphasis> title="Attention!">
+ Too much copy-pasting may leads to
+ maintenance headaches.
+</@<emphasis>box</emphasis>></programlisting>
+ </section>
+
+ <section>
+ <title>Function/method versus user-defined directive</title>
+
+ <para>This is for advanced users again (so ignore it if you don't
+ understand). It's a frequent dilemma if you should use a
+ function/method or an user-defined directive to implement
+ something. The rule of thumb is: Implement the facility as
+ user-defined directive instead of as function/method if:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>... the purpose of it is generating a piece of the
+ output that's not just a single value, and typically involves
+ markup. The template language was designed for printing to the
+ output directly, piece by piece, as it goes though
+ <literal>list</literal> loops, <literal>if</literal>-s, etc.
+ Building up a string value in a variable then returning it is
+ much less convenient.</para>
+ </listitem>
+
+ <listitem>
+ <para>... it's the side-effect that is important and not the
+ return value. For example, a directive whose purpose is to add
+ an entry to the server log is like that. (In fact you can't
+ have a return value for a user-defined directive, but some
+ kind of feedback is still possible by setting non-local
+ variables.)</para>
+ </listitem>
+
+ <listitem>
+ <para>... it will do flow control on the caller side (like for
+ example <literal>list</literal> or <literal>if</literal>
+ directives do). You just can't do that with a
+ function/method.</para>
+ </listitem>
+
+ <listitem>
+ <para>... you are using legacy escaping via the
+ <literal>escape</literal> directive (instead of <link
+ linkend="dgui_misc_autoescaping">auto-escaping</link>), and
+ the result contains markup. When you print the result with
+ <literal>${<replaceable>...</replaceable>}</literal>, the
+ markup will be escaped and thus ruined, but if it's printed by
+ a directive call
+ (<literal><@<replaceable>...</replaceable>></literal>),
+ it won't be.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The Java methods of FreeMarker-unaware Java objects are
+ normally visible as methods in templates, regardless of the nature
+ of the Java method; you have no choice there.</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Miscellaneous</title>
+
+ <section xml:id="dgui_datamodel_node">
+ <title>Nodes</title>
+
+ <indexterm>
+ <primary>node</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <para>Node variables represent a node in a tree structure, and are
+ used mostly with <link linkend="xgui">XML processing</link>, which
+ is an advanced, and specialized topic.</para>
+
+ <para>Still, a quick overview <emphasis>for advanced
+ users</emphasis>: A node is similar to a sequence that stores
+ other nodes, which are often referred as the children nodes. A
+ node stores a reference to its container node, which is often
+ referred as the parent node. The main point of being a node is the
+ topological information; other data must be stored by utilizing
+ that a value can have multiple types. Like, a value may be both a
+ node and a number, in which case it can store a number as the
+ "pay-load". Apart from the topological information, a node can
+ store some metainformation as well: a node name, a node type
+ (string), and a node namespace (string). For example, if the node
+ symbolizes a <literal>h1</literal> element in an XHTML document,
+ then its name could be <literal>"h1"</literal>, it's node type
+ could be <literal>"element"</literal>, and it's namespace could be
+ <literal>"http://www.w3.org/1999/xhtml"</literal>. But it's up to
+ the designer of the data-model if what meaning these
+ metainformations have, and if they are used at all. The way of
+ retrieving the topological and metainformations is described <link
+ linkend="ref_builtins_node">in a later chapter</link> (that you
+ don't have to understand at this point).</para>
+ </section>
+
+ <section xml:id="dgui_datamodel_markupoutput">
+ <title>Markup output</title>
+
+ <indexterm>
+ <primary>markup output</primary>
+
+ <secondary>the FTL value type</secondary>
+ </indexterm>
+
+ <para>This type is related to <link
+ linkend="dgui_misc_autoescaping">auto-escaping mechanism</link>
+ introduced FreeMarker 2.3.24; you can <link
+ linkend="dgui_misc_autoescaping_movalues">read about this type
+ there</link>. But in short, this is a value that stores text
+ that's already in the output markup format (like HTML, XML, RTF,
+ etc.), and hence must not be auto-escaped.</para>
+
+ <para>Values of this type are usually produced inside the
+ templates (like with <link
+ linkend="ref_builtin_no_esc"><literal>no_esc</literal>
+ built-in</link> or <link linkend="ref_directive_assign">output
+ capturing assignments</link>), but can also be part of the
+ data-model. Such values in the data-model are useful for example
+ if you have message resources that sometimes contain the message
+ in HTML format, rather than in plain text. If the data-model uses
+ HTML markup output values for those messages instead of strings,
+ then the template author need not know which messages contain HTML
+ and which plain text, as double escaping will be avoided
+ automatically when the message is inserted with
+ <literal>${<replaceable>...</replaceable>}</literal>.</para>
+ </section>
+ </section>
+ </section>
+ </chapter>
+
+ <chapter xml:id="dgui_template">
+ <title>The Template</title>
+
+ <indexterm>
+ <primary>template</primary>
+ </indexterm>
+
+ <note>
+ <para>It is assumed that you have already read the <xref
+ linkend="dgui_quickstart"/> and the <xref linkend="dgui_datamodel"/>
+ chapter.</para>
+ </note>
+
+ <section xml:id="dgui_template_overallstructure">
+ <title>Overall structure</title>
+
+ <para>Templates are in fact programs you write in a language called
+ <indexterm>
+ <primary>FTL</primary>
+ </indexterm><emphasis role="term">FTL</emphasis> (for FreeMarker
+ Template Language). This is a quite simple programming language
+ designed for writing templates and nothing else.</para>
+
+ <para>A template (= FTL program) is a mix of the following
+ sections:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="term">Text</emphasis><indexterm>
+ <primary>text</primary>
+ </indexterm>: Text that will be printed to the output as
+ is.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="term">Interpolation</emphasis><indexterm>
+ <primary>interpolation</primary>
+ </indexterm>: These sections will be replaced with a calculated
+ value in the output. Interpolations are delimited by
+ <literal>${</literal> and <literal>}</literal> (or with
+ <literal>#{</literal> and <literal>}</literal>, but that shouldn't
+ be used anymore; <link
+ linkend="ref_depr_numerical_interpolation">see more
+ here</link>).</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="term">FTL tags</emphasis><indexterm>
+ <primary>FTL tag</primary>
+ </indexterm>: FTL tags are a bit similar to HTML tags, but they
+ are instructions to FreeMarker and will not be printed to the
+ output.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis role="term">Comments</emphasis><indexterm>
+ <primary>comment</primary>
+ </indexterm><indexterm>
+ <primary><#--...--></primary>
+ </indexterm><indexterm>
+ <primary>#</primary>
+ </indexterm>: Comments are similar to HTML comments, but they
+ are delimited by <literal><#--</literal> and
+ <literal>--></literal>. Comments will be ignored by FreeMarker,
+ and will not be written to the output.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Let's see a concrete template. I have marked the template's
+ components with colors: <phrase role="markedText">text</phrase>,
+ <phrase role="markedInterpolation">interpolation</phrase>, <phrase
+ role="markedFTLTag">FTL tag</phrase>, <phrase
+ role="markedComment">comment</phrase>. With the <phrase
+ role="markedInvisibleText">[BR]</phrase>-s I intend to visualize the
+ <link linkend="gloss.lineBreak">line breaks</link>.</para>
+
+ <programlisting role="template"><phrase role="markedText"><html><phrase
+ role="markedInvisibleText">[BR]</phrase>
+<head><phrase role="markedInvisibleText">[BR]</phrase>
+ <title>Welcome!</title><phrase role="markedInvisibleText">[BR]</phrase>
+</head><phrase role="markedInvisibleText">[BR]</phrase>
+<body><phrase role="markedInvisibleText">[BR]</phrase>
+ <phrase role="markedComment"><#-- Greet the user with his/her name --></phrase><phrase
+ role="markedInvisibleText">[BR]</phrase>
+ <h1>Welcome <phrase role="markedInterpolation">${user}</phrase>!</h1><phrase
+ role="markedInvisibleText">[BR]</phrase>
+ <p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
+ <ul><phrase role="markedInvisibleText">[BR]</phrase>
+ <phrase role="markedFTLTag"><#list animals as animal></phrase><phrase
+ role="markedInvisibleText">[BR]</phrase>
+ <li><phrase role="markedInterpolation">${animal.name}</phrase> for <phrase
+ role="markedInterpolation">${animal.price}</phrase> Euros<phrase
+ role="markedInvisibleText">[BR]</phrase>
+ <phrase role="markedFTLTag"></#list></phrase><phrase
+ role="markedInvisibleText">[BR]</phrase>
+ </ul><phrase role="markedInvisibleText">[BR]</phrase>
+</body><phrase role="markedInvisibleText">[BR]</phrase>
+</html></phrase></programlisting>
+
+ <para>FTL distinguishes upper case and lower case letters. So
+ <literal>list</literal> is good directive name, while
+ <literal>List</literal> is not. Similarly <literal>${name}</literal>
+ is not the same as <literal>${Name}</literal> or
+ <literal>${NAME}</literal></para>
+
+ <para>It is important to realize that <phrase
+ role="markedInterpolation">interpolations</phrase> can be used in
+ <phrase role="markedText">text</phrase> (and in string literal
+ expressions; see <link
+ linkend="dgui_template_exp_stringop_interpolation">later</link>)
+ only.</para>
+
+ <para>An <phrase role="markedFTLTag">FTL tag</phrase> can't be inside
+ another <phrase role="markedFTLTag">FTL tag</phrase> nor inside an
+ <phrase role="markedInterpolation">interpolation</phrase>. For example
+ this is <emphasis>WRONG</emphasis>: <literal><#if <#include
+ 'foo'>='bar'>...</#if></literal></para>
+
+ <para><phrase role="markedComment">Comments</phrase> can be placed
+ inside <phrase role="markedFTLTag">FTL tags</phrase> and <phrase
+ role="markedInterpolation">interpolations</phrase>. For
+ example:</para>
+
+ <programlisting role="template"><phrase role="markedText"><h1>Welcome <phrase
+ role="markedInterpolation">${user <phrase role="markedComment"><#-- The name of user --></phrase>}</phrase>!</h1><phrase
+ role="markedInvisibleText">[BR]</phrase>
+<p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
+<ul><phrase role="markedInvisibleText">[BR]</phrase>
+<phrase role="markedFTLTag"><#list <phrase role="markedComment"><#-- some comment... --></phrase> animals as <phrase
+ role="markedComment"><#-- again... --></phrase> animal></phrase><phrase
+ role="markedInvisibleText">[BR]</phrase></phrase>
+<replaceable>...</replaceable></programlisting>
+
+ <note>
+ <para>For those of you who have tried the above examples: You may
+ notice that some of spaces, tabs and line breaks are missing from
+ the template output, even though we said that <phrase
+ role="markedText">text</phrase> is printed as is. Don't bother with
+ it now. This is because the feature called ''white-space stripping''
+ is turned on, and that automatically removes some superfluous
+ spaces, tabs and line breaks. This will be explained <link
+ linkend="dgui_misc_whitespace">later</link>.</para>
+ </note>
+ </section>
+
+ <section xml:id="dgui_template_directives">
+ <title>Directives</title>
+
+ <indexterm>
+ <primary><#...></primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>#</primary>
+ </indexterm>
+
+ <anchor xml:id="term.designer.directive"/>
+
+ <remark>Note that the Expressions chapter depends on this chapter, and
+ Interpolations chapter depends on Expressions chapter. Thus Directives
+ must be the first chapter after Basics.</remark>
+
+ <para><indexterm>
+ <primary>directive</primary>
+ </indexterm>You use FTL tags to call <emphasis
+ role="term">directives</emphasis>. In the example you have called the
+ <literal>list</literal> directive. Syntactically you have done it with
+ two tags: <literal><#list animals as animal></literal> and
+ <literal></#list></literal>.</para>
+
+ <para><indexterm>
+ <primary>FTL tag</primary>
+ </indexterm>There are two kind of FTL tags:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Start-tag:
+ <literal><#<replaceable>directivename</replaceable>
+ <replaceable>parameters</replaceable>></literal></para>
+ </listitem>
+
+ <listitem>
+ <para>End-tag:
+ <literal></#<replaceable>directivename</replaceable>></literal></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This is similar to HTML or XML syntax, except that the tag name
+ starts with <literal>#</literal>. If the directive doesn't have nested
+ content (content between the start-tag and the end-tag), you must use
+ the start-tag with no end-tag. For example you write <literal><#if
+ <replaceable>something</replaceable>><replaceable>...</replaceable></#if></literal>,
+ but just <literal><#include
+ <replaceable>something</replaceable>></literal> as FreeMarker knows
+ that the <literal>include</literal> directive can't have nested
+ content.</para>
+
+ <para>The format of the
+ <literal><replaceable>parameters</replaceable></literal> depends on
+ the
+ <literal><replaceable>directivename</replaceable></literal>.</para>
+
+ <para>In fact there are two types of directives: <link
+ linkend="gloss.predefinedDirective">predefined directives</link> and
+ <link linkend="gloss.userDefinedDirective">user-defined
+ directives</link>. For user-defined directives you use
+ <literal>@</literal> instead of <literal>#</literal>, for example
+ <literal><@mydirective
+ <replaceable>parameters</replaceable>><replaceable>...</replaceable></@mydirective></literal>.
+ Further difference is that if the directive has no nested content, you
+ must use a tag like <literal><@mydirective
+ <replaceable>parameters</replaceable> /></literal>, similarly as in
+ XML (e.g. <literal><img <replaceable>...</replaceable>
+ /></literal>). But user-defined directives is an advanced topic
+ that will be discussed <link
+ linkend="dgui_misc_userdefdir">later</link>.</para>
+
+ <para>FTL tags, like HTML tags, must be properly nested. So the code
+ below is wrong, as the <literal>if</literal> directive is both inside
+ and outside of the nested content of the <literal>list</literal>
+ directive:</para>
+
+ <programlisting role="template"><ul>
+<emphasis><#list animals as animal></emphasis>
+ <li>${animal.name} for ${animal.price} Euros
+ <emphasis><#if user == "Big Joe"></emphasis>
+ (except for you)
+<emphasis></#list></emphasis> <#-- WRONG! The "if" has to be closed first. -->
+<emphasis></#if></emphasis>
+</ul></programlisting>
+
+ <para>Note that FreeMarker doesn't care about the nesting of HTML
+ tags, only about the nesting of FTL tags. It just sees HTML as flat
+ text, it doesn't interpret it in any way.</para>
+
+ <para>If you try to use a non-existing directive (e.g., you mistype
+ the directive name), FreeMarker will decline to use the template and
+ produce an error message.</para>
+
+ <para>FreeMarker ignores superfluous <link
+ linkend="gloss.whiteSpace">white-space</link> inside FTL tags. So you
+ can write this:</para>
+
+ <programlisting role="template"><phrase role="markedText"><phrase
+ role="markedFTLTag"><#list<phrase role="markedInvisibleText">[BR]</phrase>
+ animals as<phrase role="markedInvisibleText">[BR]</phrase>
+ animal<phrase role="markedInvisibleText">[BR]</phrase>
+></phrase><phrase role="markedInvisibleText">[BR]</phrase>
+<phrase role="markedInterpolation">${animal.name}</phrase> for <phrase
+ role="markedInterpolation">${animal.price}</phrase> Euros<phrase
+ role="markedInvisibleText">[BR]</phrase>
+<phrase role="markedFTLTag"></#list ></phrase></phrase></programlisting>
+
+ <para>You may not, however, insert white-space between the
+ <literal><</literal> or <literal></</literal> and the directive
+ name.</para>
+
+ <para>The complete list and description of all directives can be found
+ in the <xref linkend="ref_directives"/> (but I recommend that you look
+ at the chapter about expressions first).</para>
+
+ <note>
+ <para>FreeMarker can be configured to use <literal>[</literal> and
+ <literal>]</literal> instead of <literal><</literal> and
+ <literal>></literal> in the FTL tags and FTL comments, like
+ <literal>[#if user == "Big
+ Joe"]<replaceable>...</replaceable>[/#if]</literal>. For more
+ information read: <xref
+ linkend="dgui_misc_alternativesyntax"/>.</para>
+ </note>
+
+ <note>
+ <para>FreeMarker can be configured so that it understands predefined
+ directives without <literal>#</literal> (like <literal><if user
+ == "Big
+ Joe"><replaceable>...</replaceable></if></literal>).
+ However we don't recommend the usage of this mode. For more
+ information read: <xref linkend="ref_depr_oldsyntax"/></para>
+ </note>
+ </section>
+
+ <section xml:id="dgui_template_exp">
+ <title>Expressions</title>
+
+ <para><indexterm>
+ <primary>expression</primary>
+ </indexterm>When you supply values for interpolations or directive
+ parameters you can use variables or more complex expressions. For
+ example, if x is the number 8 and y is 5, the value of <literal>(x +
+ y)/2</literal> resolves to the numerical value 6.5.</para>
+
+ <para>Before we go into details, let's see some concrete
+ examples:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>When you supply value for interpolations: The usage of
+ interpolations is
+ <literal>${<replaceable>expression</replaceable>}</literal> where
+ expression gives the value you want to insert into the output as
+ text. So <literal>${(5 + 8)/2}</literal> prints ``6.5'' to the
+ output (or possibly ``6,5'' if the language of your output is not
+ US English).</para>
+ </listitem>
+
+ <listitem>
+ <para>When you supply a value for the directive parameter: You
+ have already seen the <literal>if</literal> directive in the
+ Getting Started section. The syntax of this directive is:
+ <literal><#if
+ <replaceable>expression</replaceable>><replaceable>...</replaceable></#if></literal>.
+ The expression here must evaluate to a boolean value. For example
+ in <literal><#if 2 < 3></literal> the <literal>2 <
+ 3</literal> (2 is less than 3) is an expression which evaluates to
+ <literal>true</literal>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <section xml:id="exp_cheatsheet">
+ <title>Quick overview (cheat sheet)</title>
+
+ <para>This is a reminder for those of you who already know
+ FreeMarker or are just experienced programmers:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><link linkend="dgui_template_exp_direct">Specify values
+ directly</link></para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><link
+ linkend="dgui_template_exp_direct_string">Strings</link>:
+ <literal>"Foo"</literal> or <literal>'Foo'</literal> or
+ <literal>"It's \"quoted\""</literal> or <literal>'It\'s
+ "quoted"'</literal> or
+ <literal>r"C:\raw\string"</literal></para>
+ </listitem>
+
+ <listitem>
+ <para><link
+ linkend="d
<TRUNCATED>
[3/5] incubator-freemarker git commit: Made place for the Chinese
manual.
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-help/editors-readme.txt
----------------------------------------------------------------------
diff --git a/src/manual/docgen-help/editors-readme.txt b/src/manual/docgen-help/editors-readme.txt
deleted file mode 100644
index 5280d97..0000000
--- a/src/manual/docgen-help/editors-readme.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-Guide to FreeMarker Manual for Editors
-======================================
-
-Non-technical
--------------
-
-- The Template Author's Guide is for Web designers. Assume that a
- designer is not a programmer, (s)he doesn't even know what is Java.
- Forget that FM is implemented in Java when you edit the Template
- Author's Guide. Try to avoid technical writing.
-
-- In the Guide chapters, be careful not to mention things that were
- not explained earlier. The Guide chapters should be understandable
- if you read them continuously.
-
-- If you add a new topic or term, don't forget to add it to the Index.
- Also, consider adding entries for it to the Glossary.
-
-- Don't use too sophisticated English. Use basic words and grammar.
-
-
-Technical
----------
-
-- For the editing use XXE (XMLmind XML Editor), with its default XML
- *source* formatting settings (identation, max line length and like).
- You should install the "DocBook 5 for Freemarker" addon, which you can
- find inside the "docgen" top-level SVN module.
-
-- The HTML is generated with Docgen (docgen.jar), which will check some
- of the rules described here. To invoke it, issue "ant manual" from
- the root of the "freemarker" module. (Note: you may need to check out
- and build "docgen" first.)
-
-- Understand all document conventions in the Preface chapter. Note that
- all "programlisting"-s should have a "role" attribute with a value that
- is either: "template", "dataModel", "output", "metaTemplate" or
- "unspecified". (If you miss this, the XXE addon will show the
- "programlisting" in red.)
-
-- Verbatim content in flow text:
-
- * In flow text, all data object names, class names, FTL fragments,
- HTML fragments, and all other verbatim content is inside "literal"
- element.
-
- * Use replaceable element inside literal element for replaceable
- parts and meta-variables like:
- <literal<if <replaceable>condition</replaceable>></literal>
- <literal><replaceable>templateDir</replaceable>/copyright.ftl</literal>
-
-- Hierarchy:
-
- * The hierarchy should look like:
-
- book -> part -> chapter -> section -> section -> section -> section
-
- where the "part" and the "section"-s are optional.
- Instead of chapter you may have "preface" or "appendix".
-
- * Don't use "sect1", "sect2", etc. Instead nest "section"-s into each other,
- but not deeper than 3 levels.
-
- * Use "simplesect" if you want to divide up something visually, but
- you don't want those sections to appear in the ToC, or go into their own
- HTML page. "simplesect"-s can appear under all "section" nesting
- levels, and they always look the same regardless of the "section"
- nesting levels.
-
-- Lists:
-
- * When you have list where the list items are short (a few words),
- you should give spacing="compact" to the "itemizedlist" or
- "orderedlist" element.
-
- * Don't putting listings inside "para"-s. Put them between "para"-s instead.
-
-- Xrefs, id-s, links:
-
- * id-s of parts, chapters, sections and similar elements must
- contain US-ASCII lower case letters, US-ASCII numbers, and
- underscore only. id-s of parts and chapters are used as the
- filenames of HTML-s generated for that block.
- When you find out the id, deduce it from the position in the ToC
- hierarchy. The underscore is used as the separator between the path
- steps.
-
- * All other id-s must use prefix:
- - example: E.g.: id="example.foreach"
- - ref: Reference information...
- * directive: about a directive. E.g.: "ref.directive.foreach"
- * builtin
- - gloss: Term in the Glossary
- - topic: The recommended point of document in a certain topic
- * designer: for designers.
- E.g.: id="topic.designer.methodDataObject"
- * programmer: for programmers
- * or omit the secondary category if it is for everybody
- - misc: Anything doesn't fit in the above categories
-
- * When you refer to a part, chapter or section, often you should use
- xref, not link. The xreflabel attribute of the link-end should not be set;
- then it's deduced from the titles.
-
-- The "book" element must have this attribute: conformance="docgen"
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-misc/googleAnalytics.html
----------------------------------------------------------------------
diff --git a/src/manual/docgen-misc/googleAnalytics.html b/src/manual/docgen-misc/googleAnalytics.html
deleted file mode 100644
index bf440f2..0000000
--- a/src/manual/docgen-misc/googleAnalytics.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<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>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-originals/figures/model2sketch_with_alpha.png
----------------------------------------------------------------------
diff --git a/src/manual/docgen-originals/figures/model2sketch_with_alpha.png b/src/manual/docgen-originals/figures/model2sketch_with_alpha.png
deleted file mode 100644
index ce120cc..0000000
Binary files a/src/manual/docgen-originals/figures/model2sketch_with_alpha.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-originals/figures/odg-convert-howto.txt
----------------------------------------------------------------------
diff --git a/src/manual/docgen-originals/figures/odg-convert-howto.txt b/src/manual/docgen-originals/figures/odg-convert-howto.txt
deleted file mode 100644
index 1db294c..0000000
--- a/src/manual/docgen-originals/figures/odg-convert-howto.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Converting to SVG:
-1. Open the ODG file with Libeoffice/OpenOffice Draw
-2. Ctrl+A to select all objects
-3. File/Export..., chose SVG format, and then tick "Selection"
-4. Check the result. If contour lines at the right and bottom edge of the
- figure are partically clipped (stroke width is halved), set a stroke with
- other than 0 for all shapes.
-
-Converting to a decent quality (though non-transparent) PNG:
-1. Open the ODG file with Libeoffice/OpenOffice Draw
-2. Export to PDF
-3. Open PDF in Adobe Acrobat Reader
-4. Go to Adobe Acrobat Reader preferences and set it to not use subpixel
- anti-aliasing, just normal anti-aliasing. They used to call this LCD vs
- Monitor mode.
-5. Zoom in/out until you get the desired size in pixels, take a
- screen shot, crop it in some image editor, save it as PNG.
-
-Converting to transparent but somewhat ugly PNG:
-1. Convert to SVG as described earlier
-2. Use Apache Batik Rasterizer command line utility like:
- $BARIK_INSTALLATION\batik-rasterizer-1.8.jar -dpi 72 -m image/png ${FIGURE}.svg
- If Batik fails (as it doesn't support all SVG features), use Inkscape.
- Of course avoid supixel anti-aliasing, as it's not device independent.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-originals/figures/overview.odg
----------------------------------------------------------------------
diff --git a/src/manual/docgen-originals/figures/overview.odg b/src/manual/docgen-originals/figures/overview.odg
deleted file mode 100644
index 0533b7c..0000000
Binary files a/src/manual/docgen-originals/figures/overview.odg and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen-originals/figures/tree_with_alpha.png
----------------------------------------------------------------------
diff --git a/src/manual/docgen-originals/figures/tree_with_alpha.png b/src/manual/docgen-originals/figures/tree_with_alpha.png
deleted file mode 100644
index dc4fba8..0000000
Binary files a/src/manual/docgen-originals/figures/tree_with_alpha.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/docgen.cjson
----------------------------------------------------------------------
diff --git a/src/manual/docgen.cjson b/src/manual/docgen.cjson
deleted file mode 100644
index 221f349..0000000
--- a/src/manual/docgen.cjson
+++ /dev/null
@@ -1,112 +0,0 @@
-//charset: UTF-8
-
-deployUrl: "http://freemarker.org/docs/"
-onlineTrackerHTML: "docgen-misc/googleAnalytics.html"
-searchKey: "014728049242975963158:8awjt03uofm"
-validation: {
- programlistingsRequireRole
- // programlistingsRequireLanguage
- maximumProgramlistingWidth: 100
-}
-showXXELogo
-generateEclipseTOC
-// eclipse: {
-// link_to: "freemarker-toc.xml#ManualLink"
-// }
-
-removeNodesWhenOnline: [ "preface" ]
-
-copyrightHolder: "The FreeMarker Project"
-copyrightStartYear: 1999
-
-seoMeta: {
- "dgui_quickstart": {
- "title": "Getting Started with template writing"
- }
- "pgui_quickstart": {
- "title": "Getting Started with the Java API"
- }
-}
-
-logo: {
- href: "http://freemarker.org"
- src: logo.png,
- alt: "FreeMarker"
-}
-
-olinks: {
- homepage: "http://freemarker.org/"
- api: "api/index.html"
-
- // Homepage links:
- freemarkerdownload: "http://freemarker.org/freemarkerdownload.html"
- contribute: "http://freemarker.org/contribute.html"
- history: "http://freemarker.org/history.html"
- what-is-freemarker: "id:preface"
- mailing-lists: "http://freemarker.org/mailing-lists.html"
-
- // External URL-s:
- onlineTemplateTester: "http://freemarker-online.kenshoo.com/"
- twitter: "https://twitter.com/freemarker"
- sourceforgeProject: "https://sourceforge.net/projects/freemarker/"
- githubProject: "https://github.com/freemarker/freemarker"
- newBugReport: "https://sourceforge.net/p/freemarker/bugs/new/"
- newStackOverflowQuestion: "http://stackoverflow.com/questions/ask?tags=freemarker"
-}
-
-internalBookmarks: {
- "Alpha. index": alphaidx
- "Glossary": gloss
- "Expressions": exp_cheatsheet
- "?builtins": ref_builtins_alphaidx
- "#directives": ref_directive_alphaidx
- ".spec_vars": ref_specvar
- "FAQ": app_faq
-}
-
-tabs: {
- "Home": "olink:homepage"
- "Manual": "" // Empty => We are here
- "Java API": "olink:api"
-}
-
-// Available icons:
-// .icon-heart
-// .icon-bug
-// .icon-download
-// .icon-star
-secondaryTabs: {
- "Contribute": { class: "icon-heart", href: "olink:contribute" }
- "Report a Bug": { class: "icon-bug", href: "olink:newBugReport" }
- "Download": { class: "icon-download", href: "olink:freemarkerdownload" }
-}
-
-footerSiteMap: {
- "Overview": {
- "What is FreeMarker?": "olink:what-is-freemarker"
- "Download": "olink:freemarkerdownload"
- "Version history": "id:app_versions"
- "About us": "olink:history"
- "License": "id:app_license"
- }
- "Handy stuff": {
- "Try template online": "olink:onlineTemplateTester"
- "Expressions cheatsheet": "id:exp_cheatsheet"
- "#directives": "id:ref_directive_alphaidx"
- "?built_ins": "id:ref_builtins_alphaidx"
- ".special_vars": "id:ref_specvar"
- }
- "Community": {
- "FreeMarker on Github": "olink:githubProject"
- "Follow us on Twitter": "olink:twitter"
- "Report a bug": "olink:newBugReport"
- "Ask a question": "olink:newStackOverflowQuestion"
- "Mailing lists": "olink:mailing-lists"
- }
-}
-
-socialLinks: {
- "Github": { class: "github", href: "olink:githubProject" }
- "Twitter": { class: "twitter", href: "olink:twitter" }
- "Stack Overflow": { class: "stack-overflow", href: "olink:newStackOverflowQuestion" }
-}