Una | 尤娜
一个基于Spring Boot 2.0构建的Java博客系统
序言
实现尤娜主题渲染标签的目的是为了能够加快主题皮肤的制作,对于不熟悉Java语言或者对Spring Boot不太了解的朋友也能快速的定制出自己的博客主题。尤娜主题渲染标签是在Freemarker框架的基础上实现的,沿用了Freemarker的基础标签,如逻辑判断(if语句,if...else语句,多重if...else语句,switch语句等),数据迭代(对象数组,分页),数据格式化(时间格式化)以及数据排序等。尤娜主题渲染标签分为全局常量,内容标签,格式化函数,脚本函数和分页函数五类,在接下来的内容中,将做详细介绍。下面是Freemarker的基本原理图,对Freemarker不是太熟悉的朋友可访问其官网(https://freemarker.apache.org/) 了解更多详细的知识。
FreeMarker
1.扩展
尤娜主题渲染标签支持二次扩展,只需要让自定义的解析类继承AbstractUnaBootDirectiveModel.java类或者AbstractMethodModel.java类即可。尤娜会自动将扩展的解析类配置到Freemarker的上下文中。AbstractUnaBootDirectiveModel.java主要用于定义取值标签,而AbstractMethodModel.java类主要用于定义插件函数。你可以在com.ramostear.unaboot.freemarker包中找到这两个类。接下来,将列举两个小列子,演示如何扩展尤娜的主题渲染标签。
NumberFormat.java
@Servicepublic class NumberFormat extends AbstractMethodModel { @Override public Object exec(List arguments) throws TemplateModelException { int number = getInteger(arguments,0); DecimalFormat format = new DecimalFormat("###,###"); return format.format(number); }}
首先,需要使用@Service对类进行注解,表面这是一个被Spring容器所管理的Bean,然后继承AbstractMethodModel类,并重写exec()方法。这样就简单的定制了一个数值格式化的函数。在尤娜系统中,对函数和标签的名称做了区分(前缀都为“u_”),函数采用驼峰命名法且首字母小写,标签名称在驼峰命名法的基础上使用下滑线进行分割(无大写)。定义完函数后,便可通过下面的方式使用NumberFormat:
html
${u_numberFormat(1024666996)}
Output
1,024,666,996
说明:
传入的1024666996将会以科学计数法的方式进行格式化,最后输出1,024,666,996
Navigation.java
@Servicepublic class Navigation extends AbstractUnaBootDirectiveModel { @Autowired private CategoryService categoryService; @Override public void execute(DirectiveHandler handler) throws Exception { List data = categoryService.navigation(); if(CollectionUtils.isEmpty(data)){ handler.put(MULTI,new ArrayList()).render(); }else{ handler.put(MULTI,data).render(); } }}
最后,以导航栏标签为例,介绍取值标签的定义。取值标签需要继承AbstractUnaBootDirectiveModel类,然后使用@Service进行注解,然后重写execute()方法,实现具体的业务逻辑,最后将数据通过handler返回到模板中。尤娜系统默认了两个数据的名称:SINGLE和MULTI,值分别是“result”和“results”。现在,我们可以在模板中按照以下的方式使用Navigation标签:
html
${nav.name} #list> #if>@u_navigation>
此外,我们还可以使用Freemarker的sort_by()对数据进行排序,例如:
${nav.name} #list> #if>@u_navigation>
注意:
sort_by()和reverse可以单独使用,sort_by()是升序排列,reverse是降序排列;两者也可以同时使用,上面的例子中,将导航栏目按照id进行降序排列。
2.全局常量
全局常量主要针对尤娜博客的基本配置信息,如站点名称,域名,Logo,备案号,版权信息等。下表列出了尤娜主题渲染标签所包含的所有全局常量标签(una-boot-v1.2.2版本):
尤娜全局常量列表
提示:
在使用全局常量时,最好做空值处理(!'xxxx'),提供一个默认值,因为尤娜主题渲染标签是在Freemarker的基础上实现的,Freemarker就像一个玻璃制品,好用漂亮,但易碎!!!最好是在取值时做好空值处理。
3.格式化函数
在尤娜v1.2.2版本中,共提供了5个格式化函数,它们时字符串长度截取函数u_ellipsis(),数值格式化函数u_numberFormat(),字数统计函数u_wordNumber(),时间格式化函数u_timeAgo()和阅读时间计算函数u_readTime()。
3.1 u_ellipsis()
在制作主题时,往往会遇到字符串的长度超过div的宽度,需要对字符串进行截取。我们可以通过CSS3或者Freemarker自带的substring()对字符串进行截取,但两种方式相对来说都比较麻烦,因此,从尤娜1.2.0版本开始便提供了内置的字符串截取函数u_ellipsis()。该函数接收两个参数,一个是字符串,一个是截取长度,当字符串长度超过所设置的长度时,会自动对字符串进行截取,并在截取的字符串末尾添加“...”。下面是u_ellipsis()函数使用示例:
Data
String msg = "尤娜是一个开源免费的博客系统,使用Java语言进行开发";
u_ellipsis()
${u_ellipsis(msg 17)}
Output
尤娜是一个开源免费的博客系统...
3.2 u_numberFormat()
通常,我们都会在网页中对数字进行格式化输出,如科学计数法(1,100,000),用K代表千(1K,10K)。在尤娜系统中,提供了以科学计数法对数值进行格式化输出的函数u_numberFoarmat(),该函数接收一个数值参数,下面是函数使用示例:
Data
Integer total = 1314996;
u_numberFormat()
${u_numberFormat(total)}
Output
1,314,996
3.3 u_wordNumber()
在尤娜主题中,可以使用u_wordNumber()函数对文章的字数进行统计,在醒目的位置告知读者当前文章有多少字。下面是我个人博客中的一个截图:
u_wordNumber()函数
下面是u_wordNumber()使用示例,该函数接收一个字符串参数:
Data
String content = "尤娜是一个基于Spring Boot 2.0 进行构建的Java博客系统"
u_wordNumber()
本文共计${u_wordNumber(content)}个字
Output
本文共计21个字
补充
u_wordNumber()会自动将内容中的空格,标点符号,换行符等剔除再计算字数,英文以空格切分计算。
3.4 u_timeAgo()
u_timeAge()函数用于计算文章发布时间到当前的时间长度,并以秒,分,小时,天,月和年格式化时间。假设我们有如下的几个文章发布时间:
Data
String date1 = "2019-01-01 12:00:00";String date2 = "2019-12-31 00:59:00";String data3 = "2020-01-01 00:00:00";
假设当前时间为2020-01-01 00:00:00,使用u_timeAgo()对上述三个发布时间进行格式化:
${u_timeAgo(date1)}${u_timeAgo(date2)}${u_timeAgo(date3)}
Output
1年以前1分钟以前刚刚
补充
除了使用u_timeAgo()函数对时间进行格式化外,你还可以选择Freemarker自带的格式化函数对时间进行格式化,例如对2020-04-05 06:11进行格式化:
Data
String date = "2020-04-05 06:11";
html
${date?string("yyyy年MM月dd日")}
Output
2020年04月05日
3.5 u_readTime()
u_readTime()是尤娜1.2.2版本中新增的一个趣味性函数,用于估算正常情况下阅读文章完文章所需要的时间。u_readTime()函数接收一个字符串变量(文章内容),并以200字/分钟的阅读速度计算阅读时间。下面是我个人网站的一个截图:
u_readTime()函数
下面是u_readTime()函数的使用示例:
Data
String content = "你假装这里有4512个字";
u_readTime()
预计阅读需要${u_readTime(content)}分钟
Output
预计阅读需要22分钟
4.脚本函数
在尤娜v1.2.2版本中,新增了两个脚本函数u_gitalkScript()和u_gitalkSource()。u_gitalkScript()函数用于生成Gitalk的JavaScript初始化脚本,u_gitalkSource()函数用于生成Gitalk的样式文件连接和JS脚本的链接地址。
4.1 u_gitalkSource()
u_gitalkSource()函数接收一个String类型参数,该参数的可选值有"css"和"js"(u_gitalkSource()函数会忽略大小写)。下面是使用示例:
html
...
Output
...
4.2 u_gitalkScript()
u_gitalkScript()函数接收两个参数,文章ID和评论区的DOM属性(可以是div的id或class属性值)。使用此函数后,会生成一段Gitalk评论插件的初始化脚本(使用该函数的前提是在尤娜系统后台配置了Gitalk插件的相关信息)。下面是u_gitalkScript()使用示例:
Data
Integer postId = 1101;
u_gitalkScript()
Output
下图是u_gitalkScript()使用的实际效果图:
gitalk插件使用效果
本小节介绍了尤娜V1.2.2版本中的主题渲染标签,包括二次扩展,全局常量,格式化函数和脚本函数,并给出了相应的示例代码。在第二部分中,将详细讲解尤娜主题渲染标签中的分页函数和内容标签。
尤娜博客系统V1.2.2版本