重构后端模板文件的一种实践

后端的动态模板

Java后端一般会使用ftl(freemarker template language)模板文件来动态返回前端页面。这个工做,一般还能够用jspphp文件来实现。但这些动态模板的实现,一般是在已有的html文件上对特定的须要作动态处理的部分作改写。这对小项目来说没什么不对。可若是你的页面数量足够多,维护它们将成为一件异常困难的事情。php

Nodejs大前端技术

在目前的大前端技术栈下,Nodejs的各类框架让前端开发变得规矩很多。个人一个理解是,传统前端的html+css+js的技术栈的最大问题在于其模块化、组织能力像是一个教学语言,应有的语句控制和代码复用的技术,都显得苍白无力。css

就html的编写来说,几乎不存在一种相似函数的复用方式,可以简化重复的UI component的生成。你只能不断地去写一些重复的、杂乱的代码。总体上来说,这不只难以作后期的维护,也没法轻易地看懂其间的代码逻辑。html

一句话来说,这些代码很是相似于机器代码或者汇编代码。没有高级语言的精准控制和抽象层去对代码作宏观把控。前端

Pugjs是一个很好的html预处理项目。它的基本想法是:json

不要去直接编写“底层”的html代码,而是用本身定义的一套语法去编写 pug文件。

经过这个pug文件去生成出html代码。特别的,在它的语法中,你没必要再写一大堆的尖括号和与先后呼应的tag。如同Python,仅仅依靠代码的对齐方式,就能够自动识别相应的做用域范围。例如后端

<div> 
    <ul>
        <li> First tip </li>
        <li> Second tip </li>
        <li> Third tip </li>
    </ul>
</div>

这样语义简单、语法繁琐的一堆代码,在pug下能够简化为框架

div
    ul
        li First tip
        li Second tip
        li Third tip

但这还不是最诱人的技术,由于这无非是加入了一些语法糖。最为诱人的是pug提供的函数,它可以定义一个函数去生成某个组件。jsp

例如,若是你须要定义一组table,每一个table仅仅是表头或者其中一部分的数据不同,你该如何处理?传统的方式固然是复制粘贴一堆模板代码,而后一个个地去修改里面的数据。模块化

pug的处理方式就要好太多,彻底符合将数据和代码分离的思想。定义函数:函数

mixin leftbox-gen(dataObj)
        table.table
            thead
                tr
                    th(scope="col") #{dataObj.title}
            tbody
                each area in dataObj.areas
                    tr
                        td
                            .box-title #{area.name}
                            ul
                                each subarea in area.subareas
                                    li
                                        a(id=subarea.id, href=subarea.url) #{subarea.name}

这样就能够根据经过定义json格式的dataObj去引用函数:

+leftbox-gen(cs_leftbox_data)

你经过不一样的json数据,就可以生成不一样的table出来。这就实现了代码的模块化和以及数据和业务代码的分离。要作出新的table component,你只须要改变数据就能够了。

这样的实现方式在别的高级语言中是很常见的,可是在传统的前端代码中,这经常难以见到。缘由就在于,html代码更像是没有抽象层的机器代码,只是一大堆的实际操做,而缺乏抽象层的高效管理。

前端预处理和后端动态模板的结合

pug这样优秀的工具,若是可以用来管理后端的ftl模板固然会至关合适。优秀的语法糖、代码模块化、数据和业务逻辑的分离,实在是至关诱人的选择。

但这样的理念真要实施在生产代码中,特别是用来重构已有的legacy code时,就不大容易了。

例如,pug只能生成html代码,且生成出来的位置一般是在一个统一的地方。可ftl代码却分散在各个不一样Java工程的不一样目录之下。这二者很难统一到一块儿。

或许一个直接的想法是,不如直接把全部的ftl都放到一个地方,这样就不用把模板语言分散到各个不一样项目的不一样文件夹里,而难以维护。

但这种方案带来的一个麻烦是,若是真的把后端的ftl文件挪动了位置,那么你后端代码的接口部分就不得不作修改。而这样的接口部分其数量并很多。既要作出大量的修改,还要保证它们的正确性,并非一件轻松的事情。

通过大量的思考和尝试,我得出的一个解决方案是:

使用 Pugjs生成出统一的 ftl文件,放在同一个公共资源文件夹下。让每个具体项目下的 ftl文件中,直接 include这个公共资源文件夹中 ftl内容。

这种作法的一个精妙之处是:它将ftl文件看成函数接口来使用。后端Java代码调用ftl文件能够看做是函数调用。而函数实现并不须要直接放在这个ftl文件里,而是能够放在别的地方作引用。这就把实现和调用部分,经过一个单独的文件分离开了。

这里虽然处理的是后端模板文件和前端的一个结合,但其思想能够利用在别的地方。若是一个模板文件具有了include功能,即可以把模板文件自己看成接口,从而将实现与定义分离。

相关文章
相关标签/搜索