Una | 尤娜

一个基于Spring Boot 2.0构建的Java博客系统

序言

实现尤娜主题渲染标签的目的是为了能够加快主题皮肤的制作,对于不熟悉Java语言或者对Spring Boot不太了解的朋友也能快速的定制出自己的博客主题。尤娜主题渲染标签是在Freemarker框架的基础上实现的,沿用了Freemarker的基础标签,如逻辑判断(if语句,if…else语句,多重if…else语句,switch语句等),数据迭代(对象数组,分页),数据格式化(时间格式化)以及数据排序等。尤娜主题渲染标签分为全局常量,内容标签,格式化函数,脚本函数和分页函数五类,在接下来的内容中,将做详细介绍。下面是Freemarker的基本原理图,对Freemarker不是太熟悉的朋友可访问其官网(https://freemarker.apache.org/) 了解更多详细的知识。

二次扩展

尤娜主题渲染标签支持二次扩展,只需要让自定义的解析类继承AbstractUnaBootDirectiveModel.java类或者AbstractMethodModel.java类即可。尤娜会自动将扩展的解析类配置到Freemarker的上下文中。AbstractUnaBootDirectiveModel.java主要用于定义取值标签,而AbstractMethodModel.java类主要用于定义插件函数。你可以在com.ramostear.unaboot.freemarker包中找到这两个类。接下来,将列举两个小列子,演示如何扩展尤娜的主题渲染标签。

NumberFormat.java

@Service
public 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

<div class="meta">
    <i class="fa fa-info"> ${u_numberFormat(1024666996)}</i>
</div>

Output

1,024,666,996

说明:

传入的1024666996将会以科学计数法的方式进行格式化,最后输出1,024,666,996

Navigation.java

@Service
public class Navigation extends AbstractUnaBootDirectiveModel {

    @Autowired
    private CategoryService categoryService;

    @Override
    public void execute(DirectiveHandler handler) throws Exception {
        List<Category> data = categoryService.navigation();
        if(CollectionUtils.isEmpty(data)){
            handler.put(MULTI,new ArrayList<Category>()).render();
        }else{
            handler.put(MULTI,data).render();
        }
    }
}

最后,以导航栏标签为例,介绍取值标签的定义。取值标签需要继承AbstractUnaBootDirectiveModel类,然后使用@Service进行注解,然后重写execute()方法,实现具体的业务逻辑,最后将数据通过handler返回到模板中。尤娜系统默认了两个数据的名称:SINGLE和MULTI,值分别是“result”和“results”。现在,我们可以在模板中按照以下的方式使用Navigation标签:

html

<@u_navigation>
    <#if results?? && results?size gt 0>
        <#list results as nav>
            <a class="" href="${una}/category/${nav.slug}">
                <span>${nav.name}</span>
            </a>
        </#list>
    </#if>
</@u_navigation>

此外,我们还可以使用Freemarker的sort_by()对数据进行排序,例如:

<@u_navigation>
    <#if results?? && results?size gt 0>
        <#list results?sort_by("id")?reverse as nav>
            <a class="" href="${una}/category/${nav.slug}">
                <span>${nav.name}</span>
            </a>
        </#list>
    </#if>
</@u_navigation>

注意:

sort_by()和reverse可以单独使用,sort_by()是升序排列,reverse是降序排列;两者也可以同时使用,上面的例子中,将导航栏目按照id进行降序排列。