使用Freemarker宏进行可扩展式模块化编程

该文是转载而来,并非我本人所写,但是觉得真心不错,所以收藏一下

一、前言

今天的文章聊一下freemarker的一些特性:宏,我们将使用它写出一些模块化,可扩展的页面代码,这样的复用并且可扩展的代码风格正是我一直所追求的优雅。

二、需求案例

干巴巴的代码没意思,我们拿一个实际应用的例子。

先看一下我们具体的需求,以我的博客网站为例,比较首页 及markdown编辑器页 可以发现他们的公共点即头部导航栏。

再比对下首页文章全文页

可以发现公共点除了头部导航行,还包括博客大标题及右侧导航栏,用面向对象中的继承关系我们可以将它们表示如下:

正如同类可以通过基类定义通用功能实现复用,通过继承扩展一样,freemarker的页面是不是也可以定义基础模板,并经过类似继承的手段来实现复用和扩展呢,答案自然是有的,这个就是我们今天的所谈到的。

三、语法实现

首先是baseMarco.ftl 基本模板宏:

1.baseMarco.ftl

<#compress>//在基本宏里定义#compress 压缩页面指令, 扩展页就不需要定义了
<#macro base base_title base_keywords="" base_js=[] base_css=[]>
//base: 模板名 base_title base_keywords 可由扩展页传入的标题和关键字
//base_js css 由扩展页传入其自己的css js 我这里定义的是一个数据,方便传入多个
<html lang="zh-CN">
<head>
<title>初的博客-${base_title}</title>
//标题 后缀为扩展页所传入
//公共css
<link rel="stylesheet"
href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
//遍历扩展页css
<#list base_css as c>
<link rel="stylesheet" href="${staticsPath}${c}">
</#list>
<body id="main-body" >
<div class="container">
<ul class="nav nav-pills">
<li ><a href="/">首页</a></li>
<li ><a href="/articles.html">文章</a></li>
...
</ul>
</div>
//以上是公共导航栏
//#nested 指令表示扩展页内容将嵌套在此处
<#nested>
//以下是公共页脚
<footer class="blog-footer">
<p>? 2015-2016 初</p>
</footer>
</body>
//公共js
<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
//遍历公共js
<#list base_js as j>
<script src="${staticsPath}${j}"></script>
</#list>
</html>
</#macro>
</#compress>

ok,然后是扩展的markdown页。 有了基本宏之后,扩展页就只需要填写自己的内容了,代码非常干净。

2.markdown.ftl:

//引入基本宏
<#include "WEB-INF/views/baseMacro.ftl">
//@base 基本宏的名字 base_title 本页标题,与base中的前缀拼接就成为了该页完整标题 Chu Lung's Blog-markdown编辑器
//base_js css 本页自有的js和css
<@base base_title="markdown编辑器" base_js=["/markdown/editormd.js","/markdown/main.js"] base_css=["/markdown/css/editormd.css"] base_keywords="在线markdown编辑器,editormd">
//@base 中间的内容将嵌套至 base 宏中的#nested处
<div id="layout">
<div id="editor-div"></div>
</div> </@base>

以上就完成了markdown页面的扩展。

freemarker的宏嵌套不仅可以嵌套内容,同样也可以嵌套宏,就如同子类继承父类,"孙"类还可以继承子类一样。

前面说到了,首页文章全文页的公共点除了导航栏,还有大标题和侧边栏。因此我们需要扩展宏,让它包含这两页面的公共内容。

3.pageMarco.ftl

//宏名字 page
<#macro page title js=[] css=[] keywords="">
//引入base宏
<#include "WEB-INF/views/baseMacro.ftl">
//标题 js css等让下一级扩展页传入 keywords本页赋值
<@base base_title=title base_js=js base_css=css base_keywords="个人博客,java,初">
//以下内容将被嵌套至base宏中#nested指令处, 注意内容中又包含一个#nested指令
<div class="container">
//公共大标题
<div class="blog-header">
<h1 class="blog-title">初的博客</h1>
<p class="lead blog-description">唯爱、技术和美食三者不可辜负.</p>
</div>
<div class="row">
<div class="col-sm-8 blog-main">
//该指令表明下一级扩展页内容将被嵌套至此
<#nested>
</div>
//公共侧边栏
<div class="col-sm-3 col-sm-offset-1 blog-sidebar">
<div class="sidebar-module sidebar-module-inset">
<h4>Hi</h4>
<p>欢迎来到我的博客</p>
</div>
<#-- <div class="sidebar-module">
<h4>标签</h4>
<ol class="list-unstyled">
<li><a href="#">March 2014</a></li>
</ol>
</div>
-->
<div class="sidebar-module">
<h4>档案</h4>
<ol id="articleFilings" class="list-unstyled">
</ol>
</div>
</div>
</div>
</div>
</@base>
</#macro>

然后首页就可以嵌套至page中了,文章页也一样,这里就不再累述了。

4.index.ftl

<#include "WEB-INF/views/pageMacro.ftl">
<@page title="首页" js=["/blog/js/common.js"]>
<div>
...
</div>
</@page>

巧用freemarker的更多相关文章

  1. 巧用Freemarker的自定义方法

    要想使用Freemarker支持的自定义方法,需要实现freemarker.template.TemplateMethodModel接口,然后将方法对象放入到Freemarker的数据模型中,这样在f ...

  2. spring源码分析之freemarker整合

    FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用户的,而是一个Java类库,是一款程 ...

  3. Maven 整合FreeMarker使用

    pom.xml <!-- freemarker jar --> <dependency> <groupId>org.freemarker</groupId&g ...

  4. JAVA FreeMarker工具类

    FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...

  5. FreeMarker:怎么使用

    第一个FreeMarker程序 1. 建立一个普通的java项目:testFreeMarker 2. 引入freemarker.jar包 3. 在项目目录下建立模板目录:templates 4. 在t ...

  6. FreeMarker的基础语法

    FreeMarker语言 FreeMarker语言概述 FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写. FreeMarker被设计用来生成HTML Web ...

  7. freemarker页面中文乱码

    一.前言 简单的记录freemarker遇到的错误问题:ftl页面中文乱码 由于freemarker整合在ssm框架中,所以笔者直接贴配置代码 <beans xmlns="http:/ ...

  8. Spring 4 使用Freemarker模板发送邮件&添加附件

    前言 Spring对Java的邮件发送提供了很好的支持,提供了超级简单的API,大大简化了Java邮件发送功能的开发. Spring对Email的支持是基于JavaMail API开发的,所以,我们在 ...

  9. Freemarker 程序开发

    Freemarker 程序开发 现在web开发中,多使用freemarker 来描述页面.通常会使用的macro来定义各种组件,从而达到UI组件的复用.结合使用其它的指定,可快速的描述一个html页面 ...

随机推荐

  1. Java单例模式(转载)

    原文地址:1:http://www.cnblogs.com/hupp/p/4487521; 2:http://cantellow.javaeye.com/blog/838473 先罗列五种单例模式的实 ...

  2. EF6 连接Oracle 迁移数据错误解决方法

    环境:vs2015 + EF6 +ODP 数据库Oracle 11G add-migratioin 正常,但在update-database 时报如下错误: System.Runtime.Serial ...

  3. Quartz2D之绘制一个简单的机器猫

    学习iOS有一段时间了,在博客园也默默的潜水了两个月,见识了很多大神,收获不少. 今天整理笔记,发现忘记的不少,我感觉需要及时的整理一下了,同时也把做的小东西贴上来和大家分享一下. 最近学习了Quar ...

  4. Java Concurrent之 AbstractQueuedSynchronizer

    ReentrantLock/CountDownLatch/Semaphore/FutureTask/ThreadPoolExecutor的源码中都会包含一个静态的内部类Sync,它继承了Abstrac ...

  5. IntelliJ IDEA 的 20 个代码自动完成的特性

    http://www.oschina.net/question/12_70799 在这篇文章中,我想向您展示 IntelliJ IDEA 中最棒的 20 个代码自动完成的特性,可让 Java 编码变得 ...

  6. DELPHI 各版本下载

    各版本中国下载地址: http://pan.baidu.com/s/1eQ1QGy2 http://pan.baidu.com/s/1qWK3mw8 (有新版本发布时,会同步最新官网地址) ───── ...

  7. Add Digits, Maximum Depth of BinaryTree, Search for a Range, Single Number,Find the Difference

    最近做的题记录下. 258. Add Digits Given a non-negative integer num, repeatedly add all its digits until the ...

  8. ruby 生成有条件限制的随机数

    #conding:utf-8 #生成只有数字的随机码可控制长度def random_int(len) newpass = "" 1.upto(len){ |i| newpass & ...

  9. viewPager--viewpager时,发生内存溢出OOM问题

    两个问题:1.如果图片达到500kb每张,你这个划屏会有顿卡:2.快速滑动有出现0.几秒的白屏.图片越大,顿卡越明显. 回复parcool:500kb的背景算大的了,如果是想做图片墙,viewpage ...

  10. Java创建WebService服务及客户端实现(转)

    简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...