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

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

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

    在win7系统下,Word2010出现了不能正常关闭.打开一个已有word文档,点击右上角关闭按钮后,先提示"word已停止工作,windows正在检查该问题的解决方案",随后提示 ...

  2. 免费css布局和模板集合

    Internet 上有很多基于 (X)HTML/CSS 标记的模板.如果你是一个 Web 开发人员,你不希望把时间一次又一次地浪费在重复代码设计上面,这里提供了一个列表,提供了基于 CSS 的免费模板 ...

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

    蓝色夜空背景的通用商务PPT模板 https://pan.baidu.com/s/1tsmPEdE5gjDDSxIyMDJGCA0m28

  4. FreeMarker笔记 第三章 模板

    ,先来一打小白兔: 3.1 总体结构 用程序语言编写的程序就是模板,模板也被成为FTL(代表FreeMarker模板语言). 模板是由如下部分混合而成的: Text文本:文本会照着原样来输出: Int ...

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

    工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说 ...

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

    一.Views文件夹 -> Shared文件夹下的 _Layout.cshtml 母版页 @RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合 ...

  7. freeMarker(十二)——模板语言补充知识

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.特殊变量参考 特殊变量是由FreeMarker引擎自己定义的变量. ...

  8. 我所使用的一个通用的Makefile模板

    话不多说,请看: 我的项目有的目录结构有: dirls/ ├── include │   └── apue.h ├── lib │   ├── error.c │   ├── error.o │   ...

  9. freemarker中的list 前端模板

    freemarker list (长度,遍历,下标,嵌套,排序)1. freemarker获取list的size : JavaArrayList<String> list = new Ar ...

随机推荐

  1. zigzag数组实现

    题目出自面试宝典8.3.2 题目描述: 输入n,求一个n*n的矩阵,规定矩阵沿45度线递增,形成一个zigzag数组(JPEG编码里去像素数据的排列顺序),请问如何用C++实现? 例如: n=2 0 ...

  2. sql 计算地球2个坐标之间的距离

    show variables like '%func%'; set global log_bin_trust_function_creators=1; use scm_wuliudelimiter $ ...

  3. 直接导入用户信息到discuz ucenter.

    上一篇帖子: 直接导入帖子到Discuz 论坛数据库. 结束时说要写一篇导入用户的帖子, 一直没时间, 但是咱不能做太监,不是? 所以今天赶快补上. 在做discuz整合或者迁移是, 很多人可能遇到相 ...

  4. vcenter安装错误The DSN is pointing to anunspported ODBC driver...

    在安装vcenter server中采用现有独立sql server数据库时出现下列错误. 这是由于当前独立数据库版本和当前系统的客户端驱动不匹配.导致我们在odbc中配置dsn无法正常运行. 如sq ...

  5. 南昌网络赛 I. Max answer 单调栈

    Max answer 题目链接 https://nanti.jisuanke.com/t/38228 Describe Alice has a magic array. She suggests th ...

  6. 忽略warning 警告

    1

  7. BeginEditorCommand的原理

    代码来源 :http://www.arch-pub.com/problem-about-CPropertyPage_10682271.html CWnd* pAcadWnd = CWnd::FromH ...

  8. ubuntu下搭建Discuz

      环境:我用桥接方式创建了一个ubuntu16的虚拟机,ip为192.168.0.220   1.安装mysql sudo apt-get install mysql-server mysql-cl ...

  9. Objective-C语法基础:面向对象编程特点的总结

    1.类的声明与实现 Objective-C类的声明要写在@interface 与 @end之间,实现要写在@implementation 与 @end之间 2.类的-方法和+方法 类的-方法即类的实例 ...

  10. yolov3源码分析keras(二)损失函数计算

    一.前言 损失函数计算主要分析两部分一部分是yolo_head函数的分析另一部分为ignore_mask的生成的分析. 二.重要细节分析 2.1损失函数计算具体代码及部分分析 def yolo_los ...