# freemarker小记

freemarker小记

how to use freemarker


章节一

前阵子接触的项目中使用了freemarker,so记录下
有个不错的网站是 freemarker.foofun.cn 里面是中文文档的freemarker
不过我倾向于英文学习

像基本内容的 page contents
里面讲了基本的数值 basic value

freemarker is a template engine 模板引擎

通常前端最初了解到html, 后再接触vue react 这是最经常的事情
template engine 则解决了后端人员渲染数据时对前端原有共通的组件或语法不甚了解而出现的

比如后端mvc 返回model后 前端拿到渲染
在freemarker中仅需要

<#list userList as oneUser>
  ${oneUser.name}
<#list>

即可展示:

张三
里斯
王五

又比如model(就是SpringMvc)中的Model或ModelAndView add进去的东东(key值)
like this:

GetMapping("/list")
public String getList(Model model){
	model.addAttribute("userList",userService.getAllUsers());
	return "userList";
}

attention!! sometimes 返回的数据对像名称和key value的key同名
假如设定key value后,另一个对象也是同名的,如:

    @GetMapping(value = {"", "/"})
    public String index(Model model){
        User user = User.builder().name("熊志强").password("sanyanliangyu").build();
        model.addAttribute("user","XXXX熊志强XXXX");
        model.addAttribute(user);
        return "page/index";
    }

那么会以后设定的那个为准,上面也就是以model.addAttribute(user);为准


同样可以调用对象中的方法如:

Data
Builder
public class User {
    private String name;
    private String password;

    public String sayHello(){
        return "Hello~~~~~~~~";
    }
}
<!doctype html>
<html lang="en">
<#include "../common/head.ftl">
<body>
<div id="app" style="margin: 20px 20%">
<#--	欢迎登录,${user.name}!-->
	欢迎登录,${user}!
  <br>
  调用方法, ${user.sayHello()}
</div>
</body>
</html>

Alt text

判定userList或者上面user存在与否,在进行list或者方法调用
(方法调用一般不推荐使用)
则需要先判定一下该对象或者list是否存在,否则会抛出页面错误

like this:

  <#if manName??>
    欢迎登陆,${manName}
    <#else>
    欢迎登陆,游客
  </#if>

or this:

<#if userList??>
	<#list userList as oneUser>
	  ${oneUser.name}
	<#list>
	<#else>
	没有用户列表信息
</#if>

Template + data model = output

more复杂点的业务,如返回userList到前端freemarker模板渲染,并在点击其中一条时,获取其用户id

<#if userList??>

  <#list userList as user>
		<input type="checkbox" id="bids" value=${user.id}>
  <#list>

<#if>

临下班记录:
关于assign的使用
assign 类似于js中的var let, 类似于声明一个变量
而如果我想声明一个集合,存放list传送过来的统计之后(处理过)的数据该怎样做呢?
只使用assign配合freemarker语法来处理:

<#list jdtjs as jdddd>
var analysisList${jdddd.jdid} =
    <#assign all_death_every = 0>
    <#assign all_death = all_death_every+(jdddd.zdszsw+jdddd.snlrsw+jdddd.hszsw)>
    <#assign all_people_every = 0>
    <#assign all_people = all_people_every+(jdddd.zdszjz+jdddd.snlrjz+jdddd.hszjz+jdddd.zdszsw+jdddd.snlrsw+jdddd.hszsw)>
    {
        'jdid': ${jdddd.jdid}
        , 'community_name': '${jdddd.jdname!'某街道未命名'}',
        'death_ratio':
            <#if all_people??>
            <#if (all_people gt 0) && (all_death gt 0)>
            ${(all_death/all_people)!0}
        <#else>0
        </#if>
        <#else>0
        </#if>
        , 'all_people': ${all_people!0}, 'all_death': ${all_death!0}
    }
</#list>

上面的这个方式相当于创建许多analysisList后缀不同id的数据对象

而如果要使用这些数据对象再声明:

<#list jdtjs as jd>
deathRatios(analysisList${jd.jdid})
</#list>

这样即可,不过感觉如果数据量再多点这样渲染也不会有很好的效果,
还是感觉把list数据处理好,前端接收一个整体list用来渲染即可


章节二

引入相关模板,记得最早接触thymeleaf和vue时都有引入的概念,就是相通的页面都在一个公用层面,而其它用到的页面引入即可.

<#include "../common/head.ftl">

在ftl中也有这样的写法

Alt text
这样在page中的页面都可以引用同一个head.ftl来作为共有层使用.
除了引入js和css还可以定义相关宏来操作经常用到的表达式

如定义一个欢迎某人的页面,其font size要+2号

<#macro greet people>
  <font size="+2">${people}</font>
</#macro>

将这个放入head.ftl中,那么在其它页面使用时,将要被欢迎的人的名字放到people处即可
如下:

欢迎登陆,<@greet manName!'熊志强(๑•̀ㅂ•́)و✧'/>

Alt text

当然渲染list是必须的吧
like this:

<#macro forUserList l>
  <ul>
    <#list l as user>
      <th>
      <td>${user.id}</td>
      <td>${user.userName}</td>
      <td>${user.age}</td>
      <td>${user.birthday}</td>
      <td>${user.userMoney}</td>
      </th>
      <br>
    </#list>
  </ul>
</#macro>

而要渲染列表时仅需要调用这个macro

<@forUserList userList />

Alt text

今天做项目时发现之前公司代码套用了国外两位大佬写的一个freemarker宏定义文件
spring.ftl
竟然叫spring不过确实好像跟spring有点关系
Darren Davison
Juergen Hoeller
后来发现这个spring.ftl是来自springboot springmvc依赖中的

整个宏文件定义在单独的ftl文件中

<#ftl strip_whitespace=true>

作为开头,之下都是注释加宏定义

上次看到宏直接看到springmvc源码中的宏了

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

其中nested为嵌入数据
<#nested> 指令执行位于开始和结束标记指令之间的模板代码段。 如果这样写:

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

将输出

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

重复三遍数据

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

嵌套中嵌套其它语法

<@border>
  <ul>
  <@do_thrice>
    <li><@greet person="Joe"/>
  </@do_thrice>
  </ul>
</@border>
  <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>

http://freemarker.foofun.cn/dgui_template_exp.html

  • 内建函数
${testString?upper_case}
${testString?html}
${testString?upper_case?html}

${testSequence?size}
${testSequence?join(", ")}

假设 testString 中存储了字符串 ''Tom & Jerry'', 而testSequnce中存储了字符串 "foo", "bar" 和 "baz", 将会输出

TOM & JERRY
Tom &amp; Jerry
TOM &amp; JERRY

3
foo, bar, baz
${mouse!"No mouse."}
<#assign mouse="Jerry">
${mouse!"No mouse."}

判断不存在的值啊

上面!表示前面变量不存在则输出后面的!

No mouse.
Jerry

即设定默认值

不存在值检测操作符
使用形式:

unsafe_expr?? 

(unsafe_expr)??

章节三

章节三的记录将从自定义指令开始!!!

原文地址:https://www.cnblogs.com/ukzq/p/15647576.html