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指令,我们可以将布局模板拆分为如下几个文件

defaultLayout.ftl

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>

header.ftl

XHTML

1

<div style="">header</div>

sidebar.ftl

XHTML

1

2

3

<div style="width:30%; height:300px; float:left; ">

sidebar

</div>

footer.ftl

XHTML

1

<div style="">fotter</div>

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

page.ftl

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的变量,否则会直接出错退出。所以在输出一个变量之前尽量先判断该变量是否存在:

时间: 2024-11-01 21:03:48

freemarker实现通用布局的模板拆分与复用的相关文章

“Word自动更改后的内容保存到通用文档模板上。是否加载该模板?“的解决办法

在win7系统下,Word2010出现了不能正常关闭.打开一个已有word文档,点击右上角关闭按钮后,先提示"word已停止工作,windows正在检查该问题的解决方案",随后提示"Microsoft word正试图恢复您的信息,这可能需要几分钟",最后提示"Microsoft Word已停止工作,出现了一个问题,导致程序停止正常工作.如果有可用的解决方案,Windows将关闭程序并通知您".之后,再重新打开word时,提示"Word自

linux下面简单通用的Makefile模板

简单通用的Makefile模板: ############################################## # # 单目录通用Makefile # 目标文件可自己的设定 # 始须调试程序,修改 CFLAGS 变量为-Wall -g # # wuyq 20140825 ############################################## # EXECUTABLE为目标的可执行文件名, 可以根据具体的情况对其进行修改. EXECUTABLE := spi

(私人收藏)蓝色夜空背景的通用商务PPT模板

蓝色夜空背景的通用商务PPT模板 https://pan.baidu.com/s/1tsmPEdE5gjDDSxIyMDJGCA0m28 原文地址:https://www.cnblogs.com/Nathan-Young/p/11029621.html

2020年布局小模板

[2020年布局小模板:永远以结果导向.] *,建立高纬认知(不断读好书,交牛人[只要某个方面比我们厉害就是牛人],不断拜师(随着自身提高,老师级别随时提升),混入更高端圈子(以点带面,像每个人学习一招)) 0,市调,市调,极致市调. 1,明确目标(结果导向)人生就两件事,一件事与结果无关,一件事是与结果有关,多数人没有结果,根本在于把焦点放错了地方. 2,必须具备的资源(列出必备的几十个条件) 3,分析现有资源(有多少差距) 4,还缺少那些资源? (计划资源:缺少的条件) 记住:永远都不要等到

[Android 性能优化系列]布局篇之通过&lt;include&gt;复用布局

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/improving-layouts/reusing-layouts.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 性能优化布局篇: [Android 性能优化系列]布局篇之

MVC+BootStrap 企业通用型框架搭建 ---(2)框架布局及模板页的创建

模板页面介绍 _Header.cshtml头部页面 ,_Footer.cshtml底部页面 ,Main.cshtml框架主页面, _Theme.cshtml(主题页面),_Menu.cshtml(左侧菜单页面),_Style.cshtml(通用样式页面) _Header.cshtml 代码: @{ ViewBag.Title = "_Header";}<script type="text/ecmascript"> $(function () { $(&q

MVC+BootStrap 企业通用型框架搭建 ---(1)框架布局及模板页的创建

本系统使用的ui框架是Bootstrap3.0 布局是使用mvc的模板页面:分[左侧菜单栏目],头部[个人信息任务栏目],尾部[公司信息简介栏目],三大块: 系统搭建:(1)ManagerSystem.DI(控制反转层),ManagerSystem.UI(MVC UI层),ManagerSystem.Utility(通用工具类),SqlServer.BLL(通用业务层),SqlServer.IBLL(父业务层),SqlServer.DAL(数据层), SqlServer.IDAL(父数据层);

ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例

工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说,我这个工程十分便捷,对于初学者来说,可能包含到以下的一些知识点: 一.React-Router的使用 Router是为了方便管理组件的路径,它使用比较简单,一般定义如下就行,需要注意的是,react-router的版本有1.0-3.0,各个版本对应的API大致相似,但也有不同,我使用的是2.X的,

ASP.Net MVC 布局页 模板页 使用方法详细说明

一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过_Layout.cshtml布局页面的@RenderBody()方法呈现在标签之间. @RenderPage从名称可以猜出来这个方法是要呈现一个页面.比如网页中固定的头部可以单独放在一个共享的视图文件中,然后在布局页面中通过这个方法调用,用法如下:@RenderPage(“~/