Freemarker模版实现接口和继承(下)
有时我们需要定义一些接口模版,让实现这个模版的开发人员遵循我们的设计。例如开发jsp模版时,定义好header,footer,子页面必须实现中间的内容contents.
如何才能实现freemarker接口模版,类似Java中的接口,在接口模版中定义一些“方法”,子模版override父模版中的“方法”?
其实利用freemarker的宏macro和inlcude指令,就可以达到我们的目的。宏macro已经设计的相当好了,可以带参数等,再加上<#include>指令,接口模版指日可待。
接口模版interface.ftl
start
< @mid/>
end
子模版implement.ftl
<#include "interface.ftl">
< #macro mid>
实现
< /#macro>
结果是:
start
实现
end
绝!
接口模版不能单独运行,因为找不到宏<@mid>定义,类似Java中的接口,子模版必须实现宏<@mid>。
子模版使用<#include>指令继承接口模版,并实现了宏<@mid>。
你笑了!!@!!@! 这就是接口啊?使用<#assign>在父模版定义一个变量,子模版实现不就可以了!!!
如果你正这样做了,现在的你正如当初的我。
想想Java中的变量和方法,<#assign>和<#macro>类似。
<#assign>定义和解释是同时进行的,在模版中的位置相当重要!
<#macro>定义和解释是分开的,只有调用时才会解释里面的内容;位置不重要;宏里面可以访问外面定义的变量,也可以使用local指令定义/替换局部变量。
所以子模版这样写也是可以的:
< #macro mid>
实现
< /#macro>
<#include "interface.ftl">
Java实现接口都是先implemnts interface,再重写接口方法。所以不推荐第二种写法。
顺藤摸瓜,类似Java中的继承, 如果我要开发extends.ftl,继承implement.ftl,我在extends.ftl中也写一个同名的宏< @mid> 。
extends.ftl
<#include "
implement.ftl
">
< #macro mid>
继承
< /#macro>
结果:
start
实现
end
晕倒!
freemarker的宏有一个重要的特性:<#incluce>的模版优先使用自身的宏指令。
下一篇《Freemarker模版实现接口和继承(下)》介绍定义一个扩展<#include>标签的宏指令<@extends>,修改freemarker<#include>对宏指令解析的优先顺序 ,达到继承的效果。