freemarker实现通用布局的模板拆分与复用
原文:http://www.hawu.me/coding/733
一、基础页面布局
假设我们项目页面的通用布局如下图所示:

实现这样的布局的基本html代码如下:
XHTML
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<html>
<head>
</head>
<body>
<div style="width: 700px; text-align:center; font-size:30px;">
<div style="">header</div>
<div style="width:30%; height:300px; float:left; ">
sidebar</div>
<div style="width:70%; height:300px; float:left; ">
main content</div>
<div style="">fotter</div>
</div>
</body>
</html>
|
这样看起来很简洁是吧,但实际上一个页面的代码是很凌乱的。如果我们每个前端页面都是基于这个布局,只是main content的内容有所不同。那么从模板的可复用角度来考虑,我们就应该header、siderbar、fotter作为单独的模板剥离出来。然后在渲染main content页面时候加载这些通用的模板。
二、freemarker基础语法
2.1 插值 ${…}
freemarker会将花括号内表达式的计算结果替换到这个花括号的位置${…}。比如
|
1
2
|
<b>hello, ${user.name}</b>
5 + 2 = ${5+2}
|
那么这个模板在freemarker处理后会输出(假定user.name=”funway”)
|
1
2
|
<b>hello, funway</b>
5 + 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宏用来定义自定义指令。基本语法是

name 表示自定义的指令名
param 可选,表示指令参数
nested 可选,表示嵌套内容
return 可选,表示到这就结束了,后面代码不执行了
2.4.1 简单的macro
|
1
2
3
4
5
6
7
|
<#-- 用macro定义一个sayHello指令 -->
<#macro sayHello>
<b>hello, world</b>
</#macro>
<#-- 调用上面定义的sayHello指令 -->
<@sayHello/>
|
上面这段模板输出的html文本如下:
|
1
|
<b>hello, world</b>
|
2.4.2 带参数的macro
|
1
2
3
4
5
6
7
|
<#-- 用macro定义一个带参的sayHelloTo指令 -->
<#macro sayHelloTo person>
hello, <b>${person}</b>
</#macro>
<#-- 调用上面定义的带参sayHelloTo指令 -->
<@sayHelloTo person="funway"/>
|
这个模板的输出结果如下:
|
1
|
hello, <b>funway</b>
|
2.4.3 嵌套内容
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<#macro sayHello>
hello, world.
<br/>
<#-- 在这里嵌入指令调用时候要嵌套的内容 -->
<#nested>
<br/>
form: funway
</#macro>
<@sayHello>
<#-- 这里写上需要嵌套的内容 -->
this is nested content.
</@sayHello>
|
这段模板的输出如下:
|
1
2
3
4
5
|
hello, world.
<br/>
this is nested content.
<br/>
form: funway
|
三、布局模板拆分
使用freemarker的macro、import、include指令,我们可以将布局模板拆分为如下几个文件

XHTML
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<#macro layout>
<html>
<head>
</head>
<body>
<div style="width: 700px; text-align:center; font-size:30px;">
<#include "header.ftl">
<#include "sidebar.ftl">
<#-- 在这里嵌入main content -->
<#nested>
<#include "footer.ftl">
</div>
</body>
</html>
</#macro>
|
XHTML
|
1
|
<div style="">header</div>
|
XHTML
|
1
2
3
|
<div style="width:30%; height:300px; float:left; ">
sidebar
</div>
|
XHTML
|
1
|
<div style="">fotter</div>
|
那么在任何一个使用该布局的页面,我们只要写如下的代码,修改要嵌入到layout中的main content就好了。
XHTML
|
1
2
3
4
5
6
7
8
9
10
11
|
<#-- 引入布局指令的命名空间 -->
<#import "../layout/defaultLayout.ftl" as defaultLayout>
<#-- 调用布局指令 -->
<@defaultLayout.layout>
<#-- 将下面这个main content嵌入到layout指令的nested块中 -->
<div style="width:70%; height:300px; float:left; ">
main content</div>
</@defaultLayout.layout>
|
而且如果要更换布局,比如修改header,也不用每个页面都去改一遍了。这就实现了模板的可复用。
四、题外话,关于freemarker的一些小细节
4.1 判断变量是否存在或者为null
freemarker不允许在模板中调用一个不存在或者为null的变量,否则会直接出错退出。所以在输出一个变量之前尽量先判断该变量是否存在:

freemarker实现通用布局的模板拆分与复用的更多相关文章
- “Word自动更改后的内容保存到通用文档模板上。是否加载该模板?“的解决办法
在win7系统下,Word2010出现了不能正常关闭.打开一个已有word文档,点击右上角关闭按钮后,先提示"word已停止工作,windows正在检查该问题的解决方案",随后提示 ...
- 免费css布局和模板集合
Internet 上有很多基于 (X)HTML/CSS 标记的模板.如果你是一个 Web 开发人员,你不希望把时间一次又一次地浪费在重复代码设计上面,这里提供了一个列表,提供了基于 CSS 的免费模板 ...
- (私人收藏)蓝色夜空背景的通用商务PPT模板
蓝色夜空背景的通用商务PPT模板 https://pan.baidu.com/s/1tsmPEdE5gjDDSxIyMDJGCA0m28
- FreeMarker笔记 第三章 模板
,先来一打小白兔: 3.1 总体结构 用程序语言编写的程序就是模板,模板也被成为FTL(代表FreeMarker模板语言). 模板是由如下部分混合而成的: Text文本:文本会照着原样来输出: Int ...
- ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例
工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说 ...
- ASP.Net MVC 布局页 模板页 使用方法详细说明
一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合 ...
- freeMarker(十二)——模板语言补充知识
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.特殊变量参考 特殊变量是由FreeMarker引擎自己定义的变量. ...
- 我所使用的一个通用的Makefile模板
话不多说,请看: 我的项目有的目录结构有: dirls/ ├── include │ └── apue.h ├── lib │ ├── error.c │ ├── error.o │ ...
- freemarker中的list 前端模板
freemarker list (长度,遍历,下标,嵌套,排序)1. freemarker获取list的size : JavaArrayList<String> list = new Ar ...
随机推荐
- C# 设置textedit只能输入英文数字下划线,并且只能以英文开头(正则表达式)
this.textEdit1.Properties.Mask.EditMask = @"[a-zA-z][a-zA-Z0-9_]*";
- C语言编程学习:写的秒速计算四则混合运算项目
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- [NetCore学习记录]第一章.使用netcore撸个简单的增删改查
1.引言 2.解决方案各部分介绍图 3.添加数据模型 4.添加数据库上下文 5.修改配置文件 6.使用依赖关系注入容器注册数据库上下文 7.添加基架工具并执行初始迁移 1.引言 NetCore出来有一 ...
- springboot pom 详解
Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合.可以获取所有spring及相关技术的一站式服务,不需要翻阅示例代码,拷贝粘贴大量的依赖描述符. Starter名字的含义: 所 ...
- linux命令之磁盘与文件系统管理命令(上)
1.fdisk:磁盘分区工具 该命令是linux下常用的磁盘分区工具,但是只能给小于2TB的磁盘划分分区. 常用参数为-l,显示所有磁盘分区的信息. 示例: 1)显示磁盘分区列表 [root@boxi ...
- 【转】WinForm多线程学习文档
源地址:https://www.cnblogs.com/jianglai11/articles/1708330.html 想学习更多,看<Windows 核心编程>
- shell 常用命令集合
grep -i 忽略大小写 -I 跳过二进制文件 -c 计算数量 -n 显示行号 -R 递归 -v 不匹配某个关键字 常用组合命令 grep -iIRn keyword * 搜索含有该 keyword ...
- Python2和Python3之间的区别
编码区别 Python3.X版本中源码文件默认使用的是utf-8编码 Unicode 字符串 Python 2有两种字符串类型:Unicode字符串和非Unicode字符串 Python 3只有一种类 ...
- jquery全屏幻灯轮播焦点图
<!--banner s--> <div class="banner"> <div class="hd"> <ul&g ...
- WPF捕获全局未处理异常
在WPF开发过程中我们一般都用try/catch块来捕获异常,但不是每个异常我们都能捕获,程序总会出现一些意想不到情况,抛出一些未捕获的异常,这时就要用到全局异常捕获,即在程序的最外层加上捕获未处理异 ...