之前学习freemarker都是使用后台的代码手动合成(templateMerge),有幸进入了京东,京东前端使用volocity,研究了前端布局,发现完全使用volocity的配置,前端页面就可以搞定(https://www.iteye.com/blog/qstar-1677130),于是就想起之前使用的freemarker,是不是也可以通过页面配置搞定,经过一番探索,搞定,于是把他记录下来,用于之后的学习。

假设我们项目页面的通用布局如下图所示:

freemarker前端布局(通过macro、import、include实现前端布局)

实现这样的布局的基本html代码如下:

 
 
 
 
 
XHTML
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
</head>
<body>
>
</div>
>
</div>
>
</div>
</div>
</div>
</body>
</html>

这样看起来很简洁是吧,但实际上一个页面的代码是很凌乱的。如果我们每个前端页面都是基于这个布局,只是main content的内容有所不同。那么从模板的可复用角度来考虑,我们就应该header、siderbar、fotter作为单独的模板剥离出来。然后在渲染main content页面时候加载这些通用的模板。

 

二、freemarker基础语法

2.1 插值 ${…}

freemarker会将花括号内表达式的计算结果替换到这个花括号的位置${…}。比如

 
1
2
</b>
}

那么这个模板在freemarker处理后会输出(假定user.name=”funway”)

 
1
2
>
7

 

2.2 <#…>与<@…>

<#…>表示freemarker内建的指令,比如<#macro>、<#if>、<#list>、<#assign>。

<@…>表示用户自定义的指令,自定义指令要先用<#macro>宏来定义。(参见2.4)

2.3 <#include>与<#import>

include指令表示在当前位置插入其他文件的内容。比如<#include “/copyright.html”>

import指令表示将一个文件作为一个命名空间引入到当前文件。标准写法是<#import  “filePath”  as  nameSpace>。就像java的命名空间一样,防止两个文件中相同的变量名或者自定义指令名冲突。然后就可以在当前模板中使用${nameSpace.variable}和<@nameSpace.command>来调用该命名空间的变量与指令了。

include引入文件的内容(包括其中自定义的变量与指令),但import只会引入变量与指令,不会把html写入。

2.4 <#macro>

参考官方文档

macro宏用来定义自定义指令。基本语法是

freemarker前端布局(通过macro、import、include实现前端布局)

name 表示自定义的指令名

param 可选,表示指令参数

nested 可选,表示嵌套内容

return 可选,表示到这就结束了,后面代码不执行了

2.4.1 简单的macro

 

 
1
2
3
4
5
6
7
>
>
</b>
</#macro>
 
>
<@sayHello/>

上面这段模板输出的html文本如下:

 
1
</b>

 

2.4.2 带参数的macro

 

 
1
2
3
4
5
6
7
>
>
</b>
</#macro>
 
>
/>

这个模板的输出结果如下:

 
1
</b>

2.4.3 嵌套内容

 
1
2
3
4
5
6
7
8
9
10
11
12
13
>
    hello, world.
<br/>
>
<#nested>
<br/>
    form: funway
</#macro>
 
<@sayHello>
>
    this is nested content.
</@sayHello>

这段模板的输出如下:

 
1
2
3
4
5
.
<br/>
    this is nested content.
<br/>
 funway

 

三、布局模板拆分

使用freemarker的macro、import、include指令,我们可以将布局模板拆分为如下几个文件

freemarker前端布局(通过macro、import、include实现前端布局)

defaultLayout.ftl
 
 
 
 
 
XHTML
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>
<html>
<head>
</head>
<body>
>
>
    
>
 
>
<#nested>
    
>
</div>
</body>
</html>
</#macro>

 

header.ftl
 
 
 
 
 
XHTML
 
1
</div>

 

sidebar.ftl
 
 
 
 
 
XHTML
 
1
2
3
>
    sidebar
</div>

 

footer.ftl
 
 
 
 
 
XHTML
 
1
</div>

那么在任何一个使用该布局的页面,我们只要写如下的代码,修改要嵌入到layout中的main content就好了。

page.ftl
 
 
 
 
 
XHTML
 
1
2
3
4
5
6
7
8
9
10
11
>
>
 
>
<@defaultLayout.layout>
 
>
>
</div>
 
</@defaultLayout.layout>

而且如果要更换布局,比如修改header,也不用每个页面都去改一遍了。这就实现了模板的可复用。

四、题外话,关于freemarker的一些小细节

4.1 判断变量是否存在或者为null

freemarker不允许在模板中调用一个不存在或者为null的变量,否则会直接出错退出。所以在输出一个变量之前尽量先判断该变量是否存在:

freemarker前端布局(通过macro、import、include实现前端布局)

相关文章:

  • 2022-12-23
  • 2021-09-13
  • 2021-11-19
  • 2021-11-19
  • 2021-11-29
  • 2021-11-29
  • 2021-11-29
猜你喜欢
  • 2021-11-04
  • 2021-08-01
  • 2022-03-04
  • 2021-08-18
  • 2021-09-08
  • 2021-11-11
相关资源
相似解决方案