FreeMaker入门

2024-04-14 09:38
文章标签 入门 freemaker

本文主要是介绍FreeMaker入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

第一章 简介

 

1 什么是FreeMaker

 

FreeMaker是一款模板引擎,即基于模板,用来生成文本的工具。可以用来实现MVC模式。FreeMaker基于BSD协议。是ISO认证的开源软件。

 

2. 简介

 

如果你的在线商店需要这样的页面如:

 

<html> 
<head> <title>Welcome!</title> 
</head> 
<body> <h1>Welcome tntxia!</h1> <p>Our latest product: <a href="products/greenmouse.html">green mouse</a>! 
</body> 
</html>

 

这里tntxia是用户名。应该使用动态。

 

FreeMaker是这样实现的。

 

<html> 
<head> <title>Welcome!</title> 
</head> 
<body> <h1>Welcome ${user}!</h1> <p>Our latest product: <a href="${latestProduct.url}">${latestProduct.name}</a>! 
</body> 
</html>   

 

FreeMaker可以使用Map、List对象,也可以自定义的数据模型。

 

${…}:FreeMaker会使用动态的数据改成$里面的内容。

 

FTL tags 标签(FreeMarker  模板的语言标签) :与HTML标签相似,一般以#开关,但也可以自定义。

 

Comments 注释:<#--    -->

 

 

 

 

 

 

可以增加一个Servlet:

 

package com.tntxia.freemaker.test;import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;public class HelloFreeMarker extends HttpServlet {/*** */private static final long serialVersionUID = 6255189103129788283L;public HelloFreeMarker() {super();}// 负责管理FreeMarker模板的Configuration实例private Configuration cfg = null;public void init() throws ServletException {// 创建一个FreeMarker实例cfg = new Configuration();// 指定FreeMarker模板文件的位置cfg.setServletContextForTemplateLoading(getServletContext(),"/WEB-INF/templates");}public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 建立数据模型Map root = new HashMap();root.put("message", "hello world");root.put("name", "聂靖宇");root.put("num", 5);DataModel data = new DataModel();root.put("data", data);// root.put("personList", list);// 获取模板文件Template t = cfg.getTemplate("test1.ftl");// 开始准备生成输出// - 使用模板文件的Charset作为本页面的charset// - 使用text/html MIME-typeresponse.setContentType("text/html; charset=" + t.getEncoding());Writer out = response.getWriter();// 合并数据模型和模板,并将结果输出到out中try {t.process(root, out); // 往模板里写数据} catch (TemplateException e) {e.printStackTrace();}}public void destroy() {super.destroy();}
}

 

 在WEB-INF里面增加一个template的文件,增加一个FTL文件:

 

test1.ftl

 

<html><head>      <title>Hello Word</title>     </head> <body>        
<#--  测试注释                    -->
<h3>${message},${name}    ${data.test}</h3> <#if num > 5 >num  is 5</#if></body> </html>

 


 

1.1 指令

 

1.1.1 if指令

 

<#if user == "Big Joe">, our beloved leader</#if>!

 

通过if指令,可以让符合条件的内容显示。

 

当condition 的判断结果为 false(布尔值)时,在<#if condition>和</#if>标签之间的内容将会被略过。

 

使用<#else>标签可以指定当条件为假时程序执行的内容。例如:

 

<#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. 
<#else> Pythons are not cheaper than elephants today. 
</#if>      

 

1.1.2 list指令

 

用List指令可以实现循环输出

 

如:

 

<p>We have these animals:
<table border=1><tr><th>Name<th>Price<#list animals as being><tr><td>${being.name}<td>${being.price} Euros</#list>
</table> 

 

  list 指令的一般格式为:
  <#list sequence as loopVariable>repeatThis</#list>
  repeatThis 部分将会在给定的sequence 遍历时在每项中重复,从第一项开始,
一个接着一个。在所有的重复中,loopVariable 将持有当前项的值。这个循环变量仅
存在于<#list …>和</#list>标签之间。

 

1.1.3  include指令

 

引入一个模板:

 

<#include "test.ftl">
 
使用

 

<#include "/test.ftl">
 
是一样的效果

 

文件的位置与模板文件夹一致。

 

1.1.4 不存在的变量的处理

 

${user!"Asynonymous"}<#if user??>welcome ${user}<#else>Asynonymous Again</#if>

 

 FreeMaker容器:

 

2.2.3  容器
  这些值存在的目的是为了包含其他变量,它们仅仅作为容器。被包含的变量通常是子变
量。容器的类型有:
 哈希表:每个子变量都可以通过一个唯一的名称来查找,这个名称是不受限制的字
符串。哈希表并不确定其中子变量的顺序,也就是说没有第一个变量,第二个变量
这样的说法,变量仅仅是通过名称来访问的。 (就像 Java 语言中的 HashMap 一样,
是实现了 Hash 算法的 Map,不记录内部元素的顺序,仅仅通过名称来访问。译者
注)
  序列:每个子变量通过一个整数来标识。 第一个子变量的标识符是 0,第二个是 1,
第三个是 2,这样来类推,而且子变量是有顺序的。这些数字通常被称为是子变量
的索引。序列通常比较密集,也就是所有的索引,包括最后一个子变量的,它们和
子变量都是相关联的,但不是绝对必要的。 子变量的数值类型也并不需要完全一致。 
  集:  从模板设计者角度来看,集是有限制的序列。不能获取集的大小,也不能通过
索引取出集中的子变量,但是它们仍然可以通过 list 指令来遍历。

 

2.2.4 函数

 

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)}  

 

输出结果:

 

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 

 

 

 2.2.5 自定义方法

 

方法变量在存于实现了 TemplateMethodModel 接口的模板中。这个接口仅包含方法调用表达式调用方法时, exec方法将会被调用。 形参将会包含FTL方法调用形参的值。exec 方法的返回值给出了 FTL 方法调用表达式的返回值。

 

2.2.6 自定义指令

 

  Java程序员可以使用TemplateDirectiveModel 接口在Java代码中实现自定义指令。详情可以参看 API 文档。

 

2.2.6.1  第一个示例

 

模板:

 

 

foo 
<@upper> bar <#-- 这里允许使用所有的 FTL --> <#list ["red", "green", "blue"] as color> ${color} </#list> baaz 
</@upper> 
wombat 
 

 

将会输出:

 

foo
  BAR
    RED
    GREEN
    BLUE
  BAAZ
wombat

 

下面是指令类的源代码:

root.put("upper", new com.example.UpperDirective()); 

 

 

package com.example; 
import java.io.IOException; 
import java.io.Writer; 
import java.util.Map; 
import freemarker.core.Environment; 
import freemarker.template.TemplateDirectiveBody; 
import freemarker.template.TemplateDirectiveModel; 
import freemarker.template.TemplateException; 
import freemarker.template.TemplateModel; 
import freemarker.template.TemplateModelException; 
/** *  FreeMarker的用户自定义指令在逐步改变 
*  它嵌套内容的输出转换为大写形式 
*  <p><b>指令内容</b></p> 
*  <p>指令参数:无 *  <p>循环变量:无 
*  <p>指令嵌套内容:是 
*/ 
public class UpperDirective implements TemplateDirectiveModel 
{ public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { // 检查参数是否传入 if (!params.isEmpty()) { throw new TemplateModelException( "This directive doesn't allow parameters."); } if (loopVars.length != 0) { throw new TemplateModelException("This directive doesn't allow loop variables."); } // 是否有非空的嵌入内容 if (body != null) { // 执行嵌入体部分,和 FTL中的<#nested>一样,除了 // 我们使用我们自己的 writer 来代替当前的 output writer. body.render(new UpperCaseFilterWriter(env.getOut())); } else { throw new RuntimeException("missing body"); } 
} 
/** * {@link Writer}改变字符流到大写形式, 
* 而且把它发送到另外一个{@link Writer}中。 
*/ 
private static class UpperCaseFilterWriter extends Writer { 
private final Writer out; 
UpperCaseFilterWriter (Writer out) { this.out = out; 
} public void write(char[] cbuf, int off, int len) throws IOException { char[] transformedCbuf = new char[len]; for (int i = 0; i < len; i++) { transformedCbuf[i] = Character. 
toUpperCase(cbuf[i + off]); } out.write(transformedCbuf); } public void flush() throws IOException { out.flush(); } public void close() throws IOException { out.close(); } 
} 
}  
 

 

最后,把它放在数据模型里面,如:

 

 

root.put("upper", new com.example.UpperDirective()); 

 

第二个示例 :Repeat

 

 

 

 

 

这篇关于FreeMaker入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902690

相关文章

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能

《POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能》ApachePOI是一个流行的Java库,用于处理MicrosoftOffice格式文件,提供丰富API来创建、读取和修改O... 目录前言:Apache POIEasyPoiEasyExcel一、EasyExcel1.1、核心特性

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis