FreeMarker Design Guide

Source: Internet
Author: User
(1) template + Data Model = Output

FreeMarker is based on the idea that designers and programmers are different individuals with different professional skills. They are Labor Division:
Designers focus on representation-creating HTML files, images, and other web pages for visualization;
The programmer creates a system and generates the data to be displayed on the design page.
The common problem is that the information displayed on Web pages (or other types of documents) is invalid during page design and is based on dynamic data. Here, you can add some specific commands in HTML (or other text to be output). FreeMarker will replace the Code with appropriate data when outputting the page to the end user.

The following is an example:

In this example, we add some {...} Surrounded by specific code. These specific codes are FreeMarker instructions, and files containing FreeMarker instructions are called templates ).
User, latestProduct. url, and latestProduct. name are from the data model ).
Data Models are created by programmers to provide the template with changed information, which is generated directly from databases, files, and even programs.
The template designer does not care about the data from there, but only knows to use the created data model.

The following is a possible data model:

(root)|+- user = "Big Joe"|+- latestProduct|+- url = "products/greenmouse.html"|+- name = "green mouse"

Data Models are similar to computer file systems. latestProduct can be viewed as a directory.

2. Data Model (1) Basics

In the Quick Start, we introduced three basic object types used in the template: scalars, hashes, and sequences. In fact, we can have other capabilities:

  • Scalars: stores a single value
  • Hashes: serves as a container for other objects, each of which is associated with a unique query name.
  • Sequences: serves as a container for other objects and accesses them in order
  • Method: Calculate by passing parameters and return results as new objects
  • User-Defined FTL Tag: Macro and Converter

Generally, each variable has only one of the above capabilities, but one variable can have multiple of the above capabilities, as shown in the following example:

(root)|+- mouse = "Yerri"|+- age = 12|+- color = "brown">

The mouse is both scalars and hashes, and combines the above data model into the following template:

${mouse}       <#-- use mouse as scalar -->${mouse.age}   <#-- use mouse as hash -->${mouse.color} <#-- use mouse as hash -->

The output result is:

Yerri12brown
(2) Scalar variable

Scalar variables store a single value, which can be:

  • String: simple text, enclosed by quotation marks (single or double quotation marks) in the template
  • Number: use numeric values directly in the template
  • Date: stores date/time-related data, which can be date, time, or date-time (Timestamp). Generally, the date value is added to the data model by the programmer, and the designer only needs to display them.
  • Boolean value: true or false, usually in <# if…> Use in tag
(3) hashes, sequences, and set

Some variables do not contain any displayed content, but are used as containers to contain other variables. There are two types:

  • Hashes: it has a unique query name and is associated with every variable it contains.
  • Sequences: associate a number with each variable in it. The index value starts from 0.

Set variables are generally similar to sequences, unless they cannot be accessed or their sub-variables cannot be obtained using indexes. a set can be viewed as only composed of <# list…> Restricted sequences used by commands

(4) Method

The method variable is usually calculated based on the given parameter.

The following example assumes that the programmer has put the method variable avg in the data model to calculate the numerical average value:

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 python and elephant is:${avg(animals.python.price, animals.elephant.price)}
(5) macro and Converter

Macro and converter variables are user-defined commands (custom FTL tags) that will be described later

(6) nodes

The node variable is represented as a node in the tree structure, which is usually used in XML processing.

3. Overall structure of the template (1)

The template is written using FTL (FreeMarker template language). It is a combination of the following parts:

  • Text: Direct output
  • Interpolation: defined by $ {And}, or # {And}. The calculated value replaces the output.
  • FTL Tag: FreeMarker command, similar to HTML Tag. Add # Before the name to differentiate and no output
  • Note: It is limited by <# -- and --> and will not be output.

The following is an example of a specific template:

Note:

  • The FTL is case sensitive, so the list is the correct FTL command, while the List is not; $ {name} and $ {NAME} are different.
  • Interpolation can only be used in text
  • The FTL tag cannot be inside another FTL tag, for example:
<#if <#include 'foo'>='bar'>...</if>
  • Annotations can be placed inside the FTL tag and Interpolation, as shown in the following example:

   
  • The remaining blank characters will be removed when the template is output.
(2) Instructions

In FreeMarker, use FTL to mark the reference command. There are three FTL tags, which are similar to HTML tags:

  • Start Tag: <# directivename parameters>
  • End Tag: </# directivename>
  • Empty content command flag: <# directivename parameters/>

There are two types of commands: pre-defined commands and user-defined commands.

Use @ replace # for user-defined commands, for example, <@ mydirective>... </@ mydireve ve> (which will be described later ).

The FTL tag cannot be crossed, but should be correctly nested. The following code is incorrect:

<ul><#list animals as being><li>${being.name} for ${being.price} Euros<#if use = "Big Joe">(except for you)</#list></#if> <#-- WRONG! --></ul>

If a non-existent command is used, FreeMarker generates an error message instead of template output.

FreeMarker ignores the blank characters in the FTL tag, as shown in the following example:

<#listanimals       asbeing>${being.name} for ${being.price} Euros</#list    >

However, no blank characters are allowed between <, </and commands.

(3) Expression

Specify value directly

  • String

Use single or double quotation marks

If special characters need to be escaped, the following example:

${"It's \"quoted\" andthis is a backslash: \\"}${'It\'s "quoted" andthis is a backslash: \\'}

The output result is:

It's "quoted" andthis is a backslash: \It's "quoted" andthis is a backslash: \

The following are supported escape sequences:

Escape Sequence Description
\" Double quotation marks (u0022)
\' Single quotes (u0027)
Backslash (u005C)
\ N Line feed (u000A)
\ R Return (u000D)
\ T Tab (u0009)
\ B Backspace (u0008)
\ F Form feed (u000C)
\ L <
\ G >
\ &
\{ {
\ XCode 4-bit hexadecimal Unicode code

There is a special type of string called raw string, which is considered plain text. The \ and {strings do not have special meanings. This type of string is preceded by quotation marks with r. The following is an example:

${r"${foo}"}${r"C:\foo\bar"}

The output result is:

${foo}C:\foo\bar
  • Number

Enter directly without quotation marks

Precise numbers are separated by "." And cannot contain group symbols.

The current version does not support scientific notation, so "1E3" is incorrect.

You cannot omit 0 before the decimal point, so ". 5" is incorrect.

The numbers 8, + 8, 08, and 8.00 are the same.

  • Boolean Value

True and false, without quotation marks

  • Sequence

The list of child variables separated by commas (,) is limited by square brackets. The following is an example:

<#list ["winter", "spring", "summer", "autumn"] as x>${x}</#list>

The output result is:

winterspringsummerautumn

The project in the list is an expression, so you can use the following example:

[2 + 2, [1, 2, 3, 4], "whatnot"]

You can use a numerical range to define a numerical sequence. For example, 2. 5 is equivalent to [2, 3, 4, 5], but is more efficient. Note that the numerical range has no square brackets.

You can define a counter-incrementing number range, for example, 5 .. 2.

  • Hash)

A list of keys/values separated by commas (,), which are limited by braces. Keys and values are separated by colons. The following is an example:

{"name":"green mouse", "price":150}

Keys and values are expressions, but keys must be strings.

Get variable

  • Top-level variable: $ {variable}. The variable name can only be a combination of letters, numbers, underscores, $, @, and #, and cannot start with a number.
  • Retrieve data from the hash

You can use the DOT or square brackets syntax, assuming the following data model is available:

(root)|+- book|   ||   +- title = "Breeding green mouses"|   ||   +- author|       ||       +- name = "Julia Smith"|       ||       +- info = "Biologist, 1923-1985, Canada"|+- test = "title"

The following are equivalent values:

book.author.namebook["author"].namebook.author.["name"]book["author"]["name"]

When the dot syntax is used, the variable name has the same limit as the top-level variable, but the square brackets syntax does not. Because the name is the result of any expression

  • Get data from the sequence: The syntax is the same as that of the hashed square brackets, but the expression value in the square brackets must be a number. Note: The index of the first item is 0.

Sequence fragment: Use the [startIndex .. endIndex] syntax to obtain the sequence fragment (also a sequence) from the sequence. startIndex and endIndex are expressions that result in numbers.

  • Special variables: variables defined in FreeMarker are accessed using the. variablename syntax.

String operation

  • Interpolation (or connection Operation)

You can use $ {...} (or # {...}) to insert the expression value in the text section. For example:

${"Hello ${user}!"}${"${user}${user}${user}${user}"}

You can use the + operator to obtain the same result.

${"Hello " + user + "!"}${user + user + user + user}

$ {...} Can only be used for text. The following code is incorrect:

<#if ${isBig}>Wow!</#if><#if "${isBig}">Wow!</#if>

It should be written:

<#if isBig>Wow!</#if>
  • Substring

Example (assume that the user value is "Big Joe "):

${user[0]}${user[4]}${user[1..4]}

The result is (note that the index of the first character is 0 ):

BJig J

Sequential operation

  • Connection operation: Like a string, use +. The following is an example:
<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>- ${user}</#list>

The output result is:

- Joe- Fred- Julia- Kate

Hash operation

  • Join Operation: Like a string, use +. If the key has the same value, the value on the right replaces the value on the left, for example:
<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>- Joe is ${ages.Joe}- Fred is ${ages.Fred}- Julia is ${ages.Julia}

The output result is:

- Joe is 30- Fred is 25- Julia is 18

Arithmetic Operations

  • +,-, ×,/, And %. The following is an example:
${x * x - 100}${x / 2}${12 % 10}

The output result is (assume x is 5 ):

-752.52

The two sides of the operator must be numbers, so the following code is incorrect:

${3 * "5"} <#-- WRONG! -->

When the + operator is used, if one side is a number and the other is a string, the number is automatically converted to a string. For example:

${3 + "5"}

The output result is:

35

Use the built-in int (described later) to obtain the integer, for example:

${(x/2)?int}${1.1?int}${1.999?int}${-1.1?int}${-1.999?int}

The output result is (assume x is 5 ):

211-1-1
  • Comparison operator

Use = (OR =, completely equal) to test whether the two values are equal. Use! = Test whether two values are not equal

= And! = The two sides must be values of the same type; otherwise, an error occurs. For example, <# if 1 = "1"> may cause an error.

Freemarker is accurate, so "x", "x", and "X" are not equal

You can use <, <=,>, and> = for numbers and dates, but cannot use them as strings.

Since Freemarker will interpret> as the ending character of the FTL tag, brackets can be used for> and> = to avoid this situation, for example, <# if (x> y)>

Another alternative is to use lt, lte, gt, and gte to replace <, <=,>, and> =

  • Logical operators

& (And), | (or ),! (Not). It can only be used for boolean values. Otherwise, an error occurs.

Example:

<#if x < 12 && color = "green">We have less than 12 things, and they are green.</#if><#if !hot> <#-- here hot must be a boolean -->It's not hot.</#if>
  • Built-in functions

The usage of built-in functions is similar to accessing the sub-variables in the hashed column, but using "?" Replace ".". Some common functions are listed below.

    • String used:

Html: HTML encoding of strings

Cap_first: capital the first letter of the string

Lower_case: converts a string to lowercase.

Upper_case: converts a string to uppercase.

Trim: removes the spaces before and after the string.

    • Sequence used:

Size: obtains the number of elements in the sequence.

    • Number:

Int: Get the integer part of a number (for example,-1.9? The result of int Is-1)

Example (assume that test saves the string "Tom & Jerry "):

${test?html}${test?upper_case?html}

The output result is:

Tom &amp; JerryTOM &amp; JERRY
  • Operator precedence
Operator Group Operator
Suffix [SubvarName] [subStringRange]. (methodParams)
RMB 1 + Expr,-expr ,!
Built-in ?
Multiplication *,/, %
Addition + ,-
Link <,>, <=,> = (Lt, lte, gt, gte)
Equal = (= ),! =
Logic and &&
Logic or Double vertical bars
Number range ..
(4) Interpolation

Interpolation has two types:

  1. General Interpolation: $ {expr}
  1. Number Interpolation: # {expr} Or # {expr; format}

Note: Interpolation can only be used for text

  • General Interpolation

Insert string value: directly output the expression result

Insert numeric value: Convert the expression result to text output according to the default format (set by the # setting command). You can use the built-in function string to format a single Interpolation. The following is an example:

<#setting number_format="currency"/><#assign answer=42/>${answer}${answer?string}  <#-- the same as ${answer} -->${answer?string.number}${answer?string.currency}${answer?string.percent}

The output result is:

$42.00$42.0042$42.004,200%

Insert date value: Convert the expression result to text output according to the default format (set by the # setting command). You can use the built-in function string to format a single Interpolation. The following is an example of using the format mode:

${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}${lastUpdated?string("EEE, MMM d, ''yy")}${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}

The output result is similar to the following format:

2003-04-08 21:24:44 Pacific Daylight TimeTue, Apr 8, '03Tuesday, April 08, 2003, 09:24:44 PM (PDT)

Insert a Boolean value: Convert the expression result to text output according to the default format (set by the # setting command). You can use the built-in function string to format a single Interpolation. The following is an example:

<#assign foo=true/>${foo?string("yes", "no")}

The output result is:

yes
  • The # {expr; format} format of the number Interpolation can be used to format the number. The format can be:

MX: Minimum X-digit decimal part

MX: the maximum number of digits in the decimal part

Example:

<#-- If the language is US English the output is: --><#assign x=2.582/><#assign y=4/>#{x; M2}   <#-- 2.58 -->#{y; M2}   <#-- 4    -->#{x; m1}   <#-- 2.6 -->#{y; m1}   <#-- 4.0 -->#{x; m1M2} <#-- 2.58 -->#{y; m1M2} <#-- 4.0  -->
4. Miscellaneous (1) user-defined commands

Macros and converter variables are two different types of user-defined commands. The difference between them is that macros are defined using macro commands in the template, while converters are defined by programs outside the template, only macros are introduced here.

  • Basic usage

A macro is a template snippet associated with a variable to use the variable in the template using user-defined instructions. The following is an example:

<#macro greet><font size="+2">Hello Joe!</font></#macro>

When using macro variables as user-defined commands, replace # In the FTL tag #

<@greet></@greet>

If there is no body content, you can also use:

<@greet/>
  • Parameters

In macro commands, you can define parameters after macro variables, for example:

<#macro greet person><font size="+2">Hello ${person}!</font></#macro>

You can use this macro variable as follows:

<@greet person="Fred"/> and <@greet person="Batman"/>

The output result is:

  <font size="+2">Hello Fred!</font>and   <font size="+2">Hello Batman!</font>

Macro parameters are FTL expressions, so the following code has different meanings:

<@greet person=Fred/>

This means to pass the value of the Fred variable to the person parameter. The value is not only a string, but also other types, or even complex expressions.

There can be multiple parameters. The following is an example:

<#macro greet person color><font size="+2" color="${color}">Hello ${person}!</font></#macro>

You can use this macro variable as follows:

<@greet person="Fred" color="black"/>

The order of parameters is irrelevant, so the following is equivalent:

<@greet color="black" person="Fred"/>

Only parameters defined in the macro command can be used and all parameters are assigned values. Therefore, the following code is incorrect:

<@greet person="Fred" color="black" background="green"/><@greet person="Fred"/>

You can specify the default value when defining parameters, for example:

<#macro greet person color="black"><font size="+2" color="${color}">Hello ${person}!</font></#macro>

In this way, <@ greet person = "Fred"/> is correct.

The macro parameter is a local variable and can only be valid in the macro definition.

  • Nested content

User-Defined commands can have nested content. Use the template snippet between the start and end tags of the <# nested> command to execute the command.

Example:

<#macro border><table border=4 cellspacing=0 cellpadding=4><tr><td><#nested></tr></td></table></#macro>

This macro variable is used as follows:

<@border>The bordered text</@border>

Output result:

  <table border=4 cellspacing=0 cellpadding=4><tr><td>The bordered text</tr></td></table>

<# Nested> the command can be called multiple times, for example:

<#macro do_thrice><#nested><#nested><#nested></#macro><@do_thrice>Anything.</@do_thrice>

Output result:

  Anything.Anything.Anything.

The nested content can be a valid FTL. The following is a complex example:<@ Border> <ul> <@ do_thrice> <li> <@ greet person = "Joe"/> </@ do_thrice> </ul> </@ border> }}} output result:

  <table border=4 cellspacing=0 cellpadding=4><tr><td><ul><li><font size="+2">Hello Joe!</font><li><font size="+2">Hello Joe!</font><li><font size="+2">Hello Joe!</font></ul></tr></td></table>

The local variables in the macro definition are invisible to the nested content, for example:

<#macro repeat count><#local y = "test"><#list 1..count as x>${y} ${count}/${x}: <#nested></#list></#macro><@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>

Output result:

    test 3/1: ? ? ?test 3/2: ? ? ?test 3/3: ? ? ?
  • Use cyclic variables in macro definition

User-Defined commands can have cyclic variables, which are usually used to repeat nested content. The basic usage is to pass the actual value of the cyclic variable as a parameter of the nested command. When a user-defined command is called, at <@…> Specify the name of the loop variable after the start parameter

Example:

<#macro repeat count><#list 1..count as x><#nested x, x/2, x==count></#list></#macro><@repeat count=4 ; c, halfc, last>${c}. ${halfc}<#if last> Last!</#if></@repeat>

Output result:

  1. 0.52. 13. 1.54. 2 Last!

The number of specified cyclic variables is different from that specified by starting to mark user-defined commands.

If you specify less cyclic variables during the call, the specified values are invisible.

When the call is performed, specify more cyclic variables. Unused cyclic variables are not created.

(2) define variables in the template

There are three types of variables defined in the template:

  • Plain variable: it can be accessed anywhere in the template, including the template inserted using the include command, which is created and replaced using the assign command.
  • Local variables: valid in the macro definition. Use the local command to create and replace
  • Loop Variable: Nested content that can only exist in commands. It is automatically created by commands (such as list ).

Macro parameters are local variables rather than circular variables; local variables are hidden (rather than overwritten) plain variables with the same name; loop variables are hidden local variables with the same name and plain variables. The following is an example:

<#assign x = "plain">1. ${x}  <#-- we see the plain var. here --><@test/>6. ${x}  <#-- the value of plain var. was not changed --><#list ["loop"] as x>7. ${x}  <#-- now the loop var. hides the plain var. --><#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->8. ${x}  <#-- it still hides the plain var. --></#list>9. ${x}  <#-- the new value of plain var. --><#macro test>2. ${x}  <#-- we still see the plain var. here --><#local x = "local">3. ${x}  <#-- now the local var. hides it --><#list ["loop"] as x>4. ${x}  <#-- now the loop var. hides the local var. --></#list>5. ${x}  <#-- now we see the local var. again --></#macro>

Output result:

1. plain2. plain3. local4. loop5. local6. plain7. loop8. loop9. plain2

Internal Loop variables hide External Loop variables with the same name, such:

<#list ["loop 1"] as x>${x}<#list ["loop 2"] as x>${x}<#list ["loop 3"] as x>${x}</#list>${x}</#list>${x}</#list>

Output result:

  loop 1loop 2loop 3loop 2loop 1

The variables in the template hide (rather than overwrite) the variables with the same name in the data model. To access the variables with the same name in the data model, use the special variable global, the following example assumes that the user value in the data model is Big Joe:

<#assign user = "Joe Hider">${user}          <#-- prints: Joe Hider -->${.globals.user} <#-- prints: Big Joe -->
(3) namespace

Generally, only one namespace is used, which is called the primary namespace.

To create reusable macro, converter, or other variable sets (usually called libraries), multiple namespaces must be used to prevent conflicts of the same name.

  • Create a database

The following is an example of creating a database (Suppose it is saved in lib/my_test.ftl ):

<#macro copyright date><p>Copyright (C) ${date} Julia Smith. All rights reserved.<br>Email: ${mail}</p></#macro><#assign mail = "jsmith@acme.com">

Use the import command to import data to the template. Freemarker creates a new namespace for the imported database and can access the variables in the database through the hash variables specified in the import command:

<#import "/lib/my_test.ftl" as my><#assign mail="fred@acme.com"><@my.copyright date="1999-2002"/>${my.mail}${mail}

Output result:

  <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.<br>Email: jsmith@acme.com</p>jsmith@acme.comfred@acme.com

We can see that the two variables with the same name in the example do not conflict because they are located in different namespaces.

You can use the assign command to create or replace variables in the imported namespace. The following is an example:

<#import "/lib/my_test.ftl" as my>${my.mail}<#assign mail="jsmith@other.com" in my>${my.mail}

Output result:

jsmith@acme.comjsmith@other.com

Variables in the data model are visible anywhere and contain different namespaces. The following is the modified Library:

<#macro copyright date><p>Copyright (C) ${date} ${user}. All rights reserved.</p></#macro><#assign mail = "${user}@acme.com">

Assume that the value of the user variable in the data model is Fred, the following code:

<#import "/lib/my_test.ftl" as my><@my.copyright date="1999-2002"/>${my.mail}

Output result:

  <p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>Fred@acme.com

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.