重構後端模板文件的一種實踐

後端的動態模板

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功能,即可以把模板文件自己看成接口,從而將實現與定義分離。

相關文章
相關標籤/搜索