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

后端的动态模板

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

Nodejs大前端技术

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

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

一句话来讲,这些代码非常类似于机器代码或者汇编代码。没有高级语言的精准控制和抽象层去对代码做宏观把控。

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

不要去直接编写“底层”的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提供的函数,它能够定义一个函数去生成某个组件。

例如,如果你需要定义一组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功能,便可以把模板文件本身当作接口,从而将实现与定义分离。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,237评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,671评论 2 59
  • 说到如何去坚持做一件事,可能大家都会有很多自己的想法与建议。 你可能听谁说过我要减肥,我要运动,但是坚持了不到一个...
    生涯发展顾问_束仁阅读 515评论 2 9
  • 这一个十字路口 是谁在张望 下一个十字路口 是谁在等待 把手给我 我要带你一起去 看这个繁华世界
    蓝主咖阅读 598评论 5 12
  • 今天有双重福利, 文章不阅读完你会后悔的哦! 括弧捂嘴笑括弧完毕! 还记得前面我分享了一个“盗”图的技巧么? 许多...
    野鹿志阅读 353评论 2 3