Freemarker template files are not more complex than HTML pages, Freemarker template files consist of the following 4 parts:
1, Text: Part of the direct output
2, note: <#--...--> format section, does not output
3, interpolation: ${...} Or #{...} Part of the data model will be used instead of the output
4,FTL directive: Freemarker specified, similar to HTML tags, the first name plus # to differentiate, do not output
Here is an example of a freemarker template that contains the 4 parts mentioned above
<title>Welcome!</title><br>
<body><br>
<#--comment Section--><br>
The <#--below uses interpolation--
<p>we have these animals:<br>
<u1><br>
<#--using FTL instructions--
< #list animals as being><br>
<li>${being.name} for ${being.price} euros<br>
< #list ><br>
<u1><br>
</body><br>
1, FTL instruction rules
In Freemarker, using the FTL tag to use instructions, Freemarker has 3 FTL tags, which are exactly like the HTML tags.
1, start tag:< #directivename parameter>
2, end tag: </#directivename >
3, empty label:< #directivename parameter/>
In fact, the previous symbol # may also become @ when using the label, and if the instruction is a user instruction instead of a system built-in instruction, the # symbol should be changed to the @ symbol.
When using the FTL tag, you should have the correct nesting instead of cross-use, exactly as the XML tag is used. If you use an instruction that does not exist, Freemarker does not use the template output, but instead produces an error message. Freemarker ignores whitespace characters in the FTL tag. It is important to note that there is no white space between the </> and the instruction.
2, interpolation rules
There are two types of freemarker interpolation: 1, universal interpolation ${expr};2, numeric formatting interpolation: #{expr} or #{expr;format}
2.1 Universal interpolation
For universal interpolation, it can be divided into the following 4 cases:
1, the interpolation result is a string value: direct Output expression result
2, the interpolation result is a numeric value: The expression results are converted to text output according to the default format (set by the #setting Directive). You can use the built-in string function to format a single interpolation, as in the following example:
< #settion number_format= "currency"/>
< #assign answer=42/>
${answer}
${answer?string} <#--the same as ${answer}--
${answer?string.number}
${answer?string.currency}
${answer?string.percent}
${answer}
The output is:
$42.00
$42.00
42
$42.00
4,200%
3, the interpolation result is a date value: The expression results are converted to text output according to the default format (set by the #setting Directive). You can use the built-in string function to format a single interpolation, as in the following example:
${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 is:
2008-04-08 08:08:08 Pacific Daylight Time
Tue, APR 8, ' 03
Tuesday, April, 2003, 08:08:08 PM (PDT)
4, the interpolation result is a Boolean value: the expression results are converted to text output according to the default format (set by the #setting Directive). You can use the built-in string function to format a single interpolation, as in the following example:
< #assign foo=true/>
${foo?string ("Yes", "No")}
The output is:
Yes
2.2 Numeric formatting interpolation
Numeric formatting interpolation can be formatted with #{expr;format}, where format can be:
MX: Decimal part min x bit
MX: Fractional part max x bit
As in the following example:
< #assign x=2.582/>
< #assign y=4/>
#{x; M2} <#--output 2.58--
#{y; M2} <#--Output 4--
#{x; m2} <#--output 2.6--
#{y; m2} <#--Output 4.0--
#{x; m1m2} <#--output 2.58--
#{x; m1m2} <#--Output 4.0--
3, expression
The expression is the core function of the Freemarker template, and when the expression is placed in the interpolation syntax ${}, the value of the output expression is required, and the expression syntax can be combined with the freemarker tag to control the output. Actually, the Freemarker expression is very powerful, It not only supports directly specifying values, outputting variable values, but also supports functions such as string formatting output and collection access.
3.1 Specifying values directly
Use the direct-specified value syntax to let freemarker directly output the values in the interpolation instead of the output variable values. The direct specified value can be a string, numeric value, Boolean value, collection, and map object.
1, string
Specify string values directly using single or double quotation marks, if the string value contains special characters that need to be escaped, see the following example:
${"My files are saved on c:\\ disk"}
${' My name is \ ' Annlee\ '}
The output is:
My files are saved in the C \ \ Disk
My name is "Annlee."
The Freemarker supports the following escape characters:
\ "; double quotation marks (u0022)
\ '; single quotation mark (u0027)
\ \ backslash (u005c)
\ n; line break (u000a)
\ r; Enter (U000D)
\ t; Tab (u0009)
\b; backspace (u0008)
\f; Form Feed (u000c)
\l;<
\g;>
\a;&
\{; {
\xcode; Specifies the Unicode code directly from the 4-bit 16-digit number, outputting the character corresponding to the Unicode code.
If a piece of text contains a large number of special symbols, Freemarker provides another special format: You can add the R tag before the quotation marks of the specified string content, and the file after the R tag will be output directly. Look at the following code:
${r "${foo}"}
${r "C:\foo\bar"}
The output is:
${foo}
C:\foo\bar
2, value
The values in the expression are output directly, without the need for quotation marks. Decimal point use "." Delimited, cannot use the grouping "," symbol. Freemarker currently does not support scientific notation, so "1E3" is wrong. The use of numeric values in a Freemarker expression requires attention to the following points:
1, the value cannot omit 0 in front of the decimal point, so ". 5" is the wrong wording
2, Value 8, +8, 8.00 are all the same
3, Boolean value
Use True and false directly, without using quotation marks.
4, set
The set is enclosed in square brackets, and the elements of each collection are separated by commas "," to see the following example:
< #list ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] as X>
${X}
</#list >
The output is:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
In addition, the collection element can also be an expression, as in the following example:
[2 + 2, [1, 2, 3, 4], "whatnot"]
You can also use a numeric range to define a collection of numbers, such as 2. 5 is equivalent to [2, 3, 4, 5], but more efficient. Note that when you use a numeric range to define a collection, you do not need to use square brackets, and the numeric range also supports the inverse-incrementing range of numbers, such as 5. 2
5,map Object
The Map object uses curly braces to include the key-value pairs in the map separated by the English colon ":", and multiple sets of key-value pairs are separated by commas ",". Here's an example:
{"Language": 78, "math": 80}
The key and value of the map object are expressions, but key must be a string
3.2 Output Variable Value
Freemarker expression Output variables, these variables can be top-level variables, or they can be variables in a map object, can be variables in a collection, and can use points (.). Syntax to access the properties of a Java object. These are discussed separately below
1, top-level variables
The so-called top-level variable is a value that is placed directly in the data model, such as the following data model:
Map root = new HashMap (); Creating a data Model
Root.put ("name", "Annlee"); Name is a top-level variable
For the top-level variable, use ${variablename} directly to output the variable value, the variable name can only be a combination of letters, numbers, underscores, $,@ and #, and cannot be number one. To output the value of the name above, you can use the following syntax:
${name}
2, Output collection element
If you need to output a collection element, you can output the collection element based on the index of the collection element, and the index of the collection element is specified in square brackets. Suppose there is an index:
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]. The index is named week, and if you need to output Wednesday, you can use the following syntax:
${WEEK[2]}//output third collection element
In addition, Freemarker supports a subset of the returned collection, and if you need to return a subset of the collection, you can use the following syntax:
WEEK[3..5]//Returns the subset of the week collection, the element in the child collection is the 第4-6个 element in the week collection
3, Output Map element
The map object here can be an instance of a direct hashmap, even a JavaBean instance, and for a JavaBean instance, we can treat it as a map instance with the attribute value as the property key. In order to output the value of the map element, You can use point syntax or square bracket syntax. If you have the following data model:
Map root = new HashMap ();
Book book = new book ();
Author Author = new Author ();
Author.setname ("Annlee");
Author.setaddress ("GZ");
Book.setname ("Struts2");
Book.setauthor (author);
Root.put ("info", "struts");
Root.put ("book", book);
To access the name of the author of a book named Struts2 in the data model, you can use the following syntax:
Book.author.name//all use point syntax
book["Author"].name
book.author["name"]//mixed use point syntax and square brackets syntax
book["Author" ["Name"]//all use square brackets syntax
When using point syntax, the variable name has the same limit as the top-level variable, but the square bracket syntax does not have that restriction because the name can be the result of any expression.
3.3, string manipulation
Freemarker expressions are very flexible for string manipulation, you can concatenate string constants and variables, you can return substrings of strings, and so on.
There are two types of syntax for string joins:
1, use ${...} Or #{...} Inserts the value of the expression in the string constant section to complete the string connection.
2, connect the string directly using the Join operator +
For example, the following data models are available:
Map root = new HashMap (); Root.put ("User", "Annlee");
The following connects the user variable with the constant:
${"Hello, ${user}!"} Use the first syntax to connect
${"Hello," + user + "!"} Use the + sign to connect
The output string above is hello,annlee!, and you can see that the two syntaxes work exactly the same way.
It is worth noting that the ${...} Can only be used for text parts and cannot be used in expressions, the following code is wrong:
< #if ${isbig}>wow!</#if >
< #if "${isbig}" >wow!</#if >
should be written:< #if isbig>wow!</#if >
The Intercept substring can be based on the index of the string, and if only one index value is specified when the substring is truncated, the character corresponding to the specified index in the string is obtained, and if two index values are specified, the string substring in the middle of the two index is returned. If you have the following data model:
Map root = new HashMap (); Root.put ("book", "Struts2,freemarker");
You can intercept substrings with the following syntax:
${BOOK[0]}${BOOK[4]}//result is Su
${BOOK[1..4]}//result is Tru
3.4 Integrated Join operators
The set operator here is to concatenate two sets into a new collection, the operator of the connection set is +, see the following example:
< #list ["Monday", "Tuesday", "Wednesday"] + ["Thursday", "Friday", "Saturday", "Sunday"] as X>
${X}
</#list >
The output is: Monday Tuesday Wednesday Thursday Friday Saturday Sunday
3.5 Map Join operator
The join operator of the map object also joins the two map objects into a new map object, the connection operator of the map object is +, and if two map objects have the same key, the value on the right overrides the left. See the following example:
< #assign scores = {"Language": 86, "Math": 78} + {"math"::93}>, "Java"
Language achievement is ${scores. Language}
Math is ${scores. math}
Java scores are ${scores. Java}
The output is:
The language score is 86
The math score is 87.
Java score is 93
3.6 Arithmetic operators
Arithmetic operations are fully supported in Freemarker expressions, and the arithmetic operators supported by Freemarker include: +,-, *,/,% see the following code:
< #assign x=5>
${x * x-100}
${X/2}
${12%10}
The output is:
-75 2.5 2
Note the following points when using arithmetic operators in an expression:
1, the operands on either side of the operator must be numeric
2, when using the + operator, if the side is a number, one side is a string, it will automatically convert the number to a string to concatenate, such as: ${3 + "5"}, the result is: 35
Use the built-in int function to take an integer value, such as:
< #assign x=5>
${(X/2)? int}
${1.1?int}
${1.999?int}
${ -1.1?int}
${ -1.999?int}
The result is: 2 1 1-1-1
3.7 Comparison Operators
The comparison operators supported in an expression include the following:
1,= or = =: Determines whether two values are equal.
2,!=: Determine whether two values are unequal.
3,> or GT: Determine if the left value is greater than the right value
4,>= or GTE: Determine if the left value is greater than or equal to the right value
5,< or LT: Determine if the left value is less than the right value
6,<= or LTE: Determine if the left value is less than or equal to the right value
Note: = and! = can be used for strings, numbers and dates to compare equality, but = and! = must be the same type of value on either side, otherwise an error is generated, and Freemarker is an exact comparison, "X", "X", "X" are unequal. Other operators can be used for numbers and dates, But not for strings, most of the time, the use of the GT and other letter operators instead of > will have a better effect, because Freemarker will interpret > as the end character of the FTL tag, and of course, you can also use parentheses to avoid this situation, such as:< #if (x>y) >
3.8 Logical operators
There are several logical operators:
Logic and:&&
Logical OR: | |
Logical non-:!
Logical operators can only be used for Boolean values, otherwise an error will be generated
3.9 Built-in functions
Freemarker also provides built-in functions to transform the output, which can be rotated by the built-in function to rotate the output variable after any variable immediately following the?,?. The following are commonly used built-in string functions:
HTML: HTML Encoding of strings
Cap_first: Capitalize the first letter of a string
Lower_case: Converting a string to lowercase
Upper_case: Converting a string to uppercase
Trim: Remove whitespace characters before and after a string
The following are common built-in functions for collections
Size: Gets the number of elements in the sequence
The following are common built-in functions for numeric values
int: Gets the integer part of the number, with the result signed
For example:
< #assign test= "Tom & Jerry" >
${test?html}
${test?upper_case?html}
The result: Tom & Jerry TOM & JERRY
3.10 NULL processing operator
Freemarker the processing of null values is very strict, freemarker variables must have values, not assigned to the variable will throw an exception, because Freemarker unassigned variable coercion error can eliminate many potential errors, such as missing potential variable name, or other variable error. The null value mentioned here actually includes those variables that do not exist, and for a null value of Java, we think that this variable exists, except that its value is null, but for the freemarker template it cannot understand the null value. Null values are exactly the same as non-existent variables.
To handle missing variables, Freemarker provides two operators:
!: Specify default values for missing variables
??: Determine if a variable exists
Of these, there are two ways to use operators:
variable! or Variable!defaultvalue, the first usage does not specify a default value for the missing variable, indicating that the default value is an empty string, a collection of length 0, or a map object with a length of 0.
Use! When you specify a default value, the default value is not required to be of the same type and variable type. Use?? The operator is very simple and always returns a Boolean value, using: Variable??, If the variable exists, returns True, otherwise false
Precedence of the 3.11 operator
The operator precedence in Freemarker is as follows (from high to low):
1, unary operator:!
2, built-in function:?
3, multiplication Method: *,/,%
4, add and subtract:-, +
5, compare:>, <, >=, <= (LT, LTE, GT, GTE)
6, equal: = =, =,! =
7, Logic and:&&
8, logic or: | |
9, Number range:.
In fact, we should use parentheses in the development process to strictly differentiate, so that the readability is good, the error is less
4 Common directives for Freemarker
Freemarker's FTL directives are also an important part of the template, which implements the iterative, branching control of the data contained in the data model. In addition, there are some important features that are also implemented by the FTL instructions.
4.1 if directive
This is a typical branch control directive that functions exactly like the syntax of the IF,IF directive in the Java language as follows:
< #if Condition>, .....
< #elseif Condition>, .....
< #elseif Condition>, .....
< #else > ...
</#if >
Examples are as follows:
< #assign age=23>
< #if (age>60) > Seniors
< #elseif (age>40) > Middle-aged
< #elseif (age>20) > Young people
< #else > Juvenile
</#if >
The output is: young people
The logical expression in the above code is enclosed in parentheses mainly because there are > symbols in it, because Freemarker will use the > symbol as the end character of the label, which may cause the program to go wrong, in order to avoid this situation, we should be in the place where these symbols appear in parentheses.
4.2 Switch, case, default, break instruction
These instructions are obviously branch directives that act like a Java switch statement, with the syntax structure of the switch directive as follows:
< #switch value>
< #case refvalue>...< #break >
< #case refvalue>...< #break >
< #default, .....
</#switch >
4.3 List, break command
The list directive is an iterative output instruction used to iterate over the collection in the output data model, with the syntax of the list directive as follows:
< #list sequence as item>
...
</#list >
In the syntax format above, sequence is either a collection object or an expression, but the expression returns a collection object, and item is an arbitrary name, which is a collection element that is iterated over. In addition, when iterating over a collection object, it also contains two special loop variables:
Item_index: Index value of the current variable
Item_has_next: Whether the next object exists
You can also use the < #break > command to jump out of an iteration
Examples are as follows:
< #list ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] as X>
${x_index + 1}.${x}< #if x_has_next>,</if>
< #if x= "Thursday" >< #break ></#if >
</#list >
4.4 Include directives
The include directive acts like a JSP containing directive that contains the specified page. The syntax format for the include directive is as follows:
< #include filename [options]>
In the syntax format above, the two parameters are interpreted as follows:
FileName: This parameter specifies the template file to be included
Options: This parameter can be omitted, specifying the options that are included, including encoding and parse two options, where encoding specifies the decoding set to be used when the page is contained, and parse specifies whether the included file is parsed as an FTL file, and if the parse option value is omitted, This option is true by default.
4.5 import directive
The directive is used to import all the variables in the Freemarker template and place the variable in the specified Map object, with the following syntax for the import directive:
< #import "/LIB/COMMON.FTL" as com>
The above code will import all the variables in the/LIB/COMMON.FTL template file and place them in a map object named COM.
4.6 noparse directive
The noparse directive specifies that Freemarker does not process the content contained in the specified directive, which has the following syntax format:
< #noparse >...</#noparse >
Look at the following example:
< #noparse >
< #list books as book>
<tr><td>${book.name}<td> Author: ${book.author}
</#list >
</#noparse >
The output is as follows:
< #list books as book>
<tr><td>${book.name}<td> Author: ${book.author}
</#list >
4.7 Escape, Noescape command
The escape instruction causes the interpolation of the body area to be automatically added to the escape expression, but does not affect the interpolation within the string, only affects the interpolation that appears within the body, and the syntax format for using the escape instruction is as follows:
< #escape identifier as EXPRESSION>
< #noescape >...</#noescape >
</#escape >
Look at the following code:
< #escape x as x?html>
First Name:${firstname}
Last Name:${lastname}
Maiden Name:${maidenname}
</#escape >
The above code is equivalent to:
First name:${firstname?html}
Last name:${lastname?html}
Maiden name:${maidenname?html}
The escape instruction functions when parsing the template rather than at run time, except that the escape instruction is also nested, and the child escape inherits the rules of the parent escape, as in the following example:
< #escape x as x?html>
Customer Name:${customername}
Items to ship;
< #escape x as itemcodetonamemap[x]>
${ITEMCODE1}
${itemcode2}
${ITEMCODE3}
${ITEMCODE4}
</#escape >
</#escape >
The above code is similar to the following:
Customer name:${customername?html}
Items to ship;
${itemcodetonamemap[itemcode1]?html}
${itemcodetonamemap[itemcode2]?html}
${itemcodetonamemap[itemcode3]?html}
${itemcodetonamemap[itemcode4]?html}
This interpolation is automatically added to the escape expression for all interpolation placed in the escape instruction, and you should use the NOESCAPE directive if you need to specify some interpolation in the escape instruction without adding an escape expression. The interpolation placed in the Noescape directive will not add escape expressions.
4.8 Assign directive
The Assign directive has been used several times before, and it is used to create or replace a top-level variable for the template page, with a variety of assign directives, including creating or replacing a top-level variable, or creating or replacing multiple variables, and its simplest syntax is as follows:< #assign name= value [in Namespacehash]>, this usage is used to specify a variable named name, the value of the variable is "value", in addition, Freemarker allows the use of assign directives to increase the in clause, The IN clause is used to place the created name variable into the Namespacehash namespace.
The Assign directive also has the following usage:< #assign name1=value1 name2=value2 ... namen=valuen [in Namespacehash]>, this syntax can create or replace multiple top-level variables at the same time, in addition, There is also a complex usage, if the value of the variable you need to create or replace is a complex expression, you can use the following syntax format:< #assign name [in Namespacehash]>capture this</#assign; In this syntax, it refers to assigning the contents of the assign instruction to the name variable. The following example:
< #assign x>
< #list ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] as N>
${n}
</#list >
</#assign >
${X}
The above code will produce the following output: Monday Tuesday Wednesday Thursday Friday Saturday Sunday
Although assign specifies the use of this complex variable value, we do not misuse this usage, as the following example:< #assign X>hello ${user}!</#assign, the above code should be more appropriate to the following wording: <# Assign x= "Hello ${user}!" >
4.9 setting directive
This instruction is used to set the operating environment of the Freemarker, the syntax format of the directive is as follows:< #setting Name=value> In this format, the value range of name includes the following:
Locale: This option specifies the country/language options used for the template
Number_format: Specifies the format of the formatted output number
Boolean_format: Specifies the syntax format for two Boolean values, the default value is True,false
Date_format,time_format,datetime_format: Specifies the format of the formatted output date
Time_zone: Set the time zone to use when formatting the output date
4.10 macro, nested, return instruction
Macro can be used to implement custom directives, by using custom directives, you can define a section of a template fragment as a user instruction, using the macro instruction syntax in the following format:
< #macro name param1 param2 ... paramn>
...
< #nested loopvar1, Loopvar2, ..., loopvarn>
...
< #return >
...
</#macro >
In the above format fragment, the following sections are included:
The Name:name property specifies the name of the custom directive and can pass in multiple parameters when using a custom directive
PARAMX: This property specifies the use of the custom directive times parameter, which must be passed to the value when using the custom directive
Nested directive: Nested label output when using the middle part of a custom directive
Cyclic variables in the nested directive: This loop variable is specified by the macro definition section, passed to the template using the label
Return Directive: This directive can be used to end the custom instruction at any time.
Look at the following example:
< #macro book>//define a custom directive
J2ee
</#macro >
< @book/>//Use the instructions you just defined
The above code outputs the result: Java EE
In the above code, it may be difficult to see the usefulness of a custom label, because the book directive we define contains very simple content, in fact, the custom label can contain a lot of content, which can achieve better code reuse. In addition, you can specify parameters for custom directives when you define custom directives. Look at the following code:
< #macro book booklist> //define a custom directive Booklist is a parameter
< #list Booklist as book
${book}
</#list,
</#macro
< @book booklist=["Spring", "java ee"]/> //Use the directive you just defined
The above code passes a parameter value for the book Directive, and the output of the above code is: Spring Java EE
Not only that, you can also use the nested directive when customizing directives to output the middle part of a custom directive, see the following example:
< #macro page title>
<title>freemarker Sample Page-${title?html}</title>
<body>
< #nested > // Tag body for introducing user-defined Directives
</body>
</#macro;
The above code defines an HTML page template as a page directive. You can do so page directives in other pages:
< #import "/COMMON.FTL" as com> //assuming that the template page above is named COMMON.FTL, import the page
< @com. Page title= "book list";
<u1>
<li>spring</li>
<li>j2ee</li
</ul>
</@com. Page>
As can be seen from the above example, the use of macro and nested instructions can be very easy to achieve page decoration effect, in addition, you can also use the nested instruction, specify one or more loop variables, see the following code:
< #macro book>
< #nested 1>//Specify a loop variable value when using the book instruction
< #nested 2>
</#macro >
< @book;x> ${x}. Books </@book >
When you use the nested directive to pass in a variable value, you need to use a placeholder (such as after the book instruction; x) When you use the custom directive. The above code output text is as follows:
1. Books 2. Books
When using loop variables in the nested directive, you can use multiple loop variables to see the following code:
< #macro repeat count>
< #list 1..count as x>//Specify three loop variables when using the nested instruction
< #nested x, X/2, x==count>
</#list >
</#macro >
< @repeat count=4; C HALFC last>
${c}. ${halfc}< #if last> last! </#if >
</@repeat >
The above output results are:
1.0.5 2. 1 3. 1.5 4. 2 last;
The return instruction is used to end the macro instruction, and once the return instruction is executed in the macro command, Freemarker does not continue to process the contents of the macro instruction, as shown in the following code:
< #macro book>
Spring
< #return >
J2ee
</#macro >
< @book/>
The above code output: Spring, and the EE is not output after the return instruction.
Freemarker Grammar Knowledge