<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 視圖模板篇(一):模板引擎的定義、解析與執(zhí)行

          共 3670字,需瀏覽 8分鐘

           ·

          2020-08-22 03:09

          1、模板和模板引擎

          在 Web 編程中,模板引擎用于聚合數據和模板并生成最終的 HTML 文檔,處理器調用模板引擎來完成這一工作并將 HTML 文檔作為響應實體發(fā)送給客戶端:

          雖然模板引擎沒有統(tǒng)一的標準,甚至不同的模板引擎提供的功能特性也是天差地別,但是仍然可以劃分為兩種不同的類型:

          • 無業(yè)務邏輯:數據通過指定占位符替換,模板中不包含業(yè)務邏輯,所有業(yè)務邏輯都在處理器中完成,這樣做的好處是將業(yè)務邏輯和數據渲染很好的隔離開。

          • 嵌入業(yè)務邏輯:在視圖模板中嵌入業(yè)務邏輯,這使得視圖模板的功能非常強大,但是這樣一來,也使得代碼維護非常困難。

          我們傾向于無業(yè)務邏輯嵌入的模板引擎,這樣的視圖模板性能更好,可維護性更好,但是絕對的無業(yè)務邏輯嵌入也是做不到的(比如一些簡單的條件判斷和循環(huán)),大部分時候這取決于業(yè)務開發(fā)團隊的約定,盡量不要在視圖模板中編寫業(yè)務邏輯代碼。

          PHP 誕生之初就是一個將業(yè)務邏輯和 HTML 視圖混為一體的腳本語言,不過現在的 PHP 腳本中已經很少看到 HTML 代碼了,這是 PHP 框架的功勞,比如 Laravel、Yii,PHP 自身作為一個模板引擎,現在已經衍生出獨立的模板引擎,比如 Smarty、Blade。

          實際上,大部分模板引擎都是介于以上兩種類型之間,只能說離誰更近一些。

          Go 語言官方提供的模板引擎 text/templatehtml/template 也是這樣的混合物。

          2、Go 模板引擎

          Go 模板引擎都是在處理器中觸發(fā),指定要解析的模板文件,并傳入待渲染的數據,最后返回由模板引擎最終生成的 HTML 作為 HTTP 響應發(fā)送給客戶端:

          Go 模板都是文本文檔,在 Web 應用中,通常是 HTML 文檔,其中包含了嵌入的命令。這些文檔會被 Go 模板引擎解析和執(zhí)行,生成另外的文本片段(替換完命令和數據)。

          Go 標準庫提供了 text/template 庫用于解析任意類型的文本格式模板,以及 html/template 庫用于解析并處理 HTML 格式模板。

          在這些模板中,命令以 {{}} 包裹(實際上,這些界定符可以通過程序進行修改),下面我們看一段簡單的模板代碼 tmpl.html


          <html?lang="en">
          ????<head>
          ????????<meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8">
          ????????<title>Go?Web?Programmingtitle>
          ????head>
          ????<body>
          ????????{{?.?}}
          ????body>
          html>

          模板文件中的內容必須是可讀的文本格式,但是擴展名可以隨意,在這里由于最終生成的是 HTML 文檔,所以我們使用了 .html 擴展名(tmpl.html)。

          {{ . }} 中的 . 就是一個命令,用于在模板執(zhí)行時替換從處理器傳入的變量。

          使用 Go 模板引擎通常包括以下兩個步驟:

          • 解析文本模板源,可以是表單字符串、或者模板文件,用于創(chuàng)建解析后的模板結構體。

          • 執(zhí)行解析后的模板,傳遞 ResponseWriter 和變量數據,這樣一來,模板引擎就可以基于模板和數據生成最終的 HTML 并將其傳遞給 ResponseWriter 發(fā)送給客戶端。

          下面是服務端處理器調用模版引擎渲染上述模板代碼的示例:

          package?main

          import?(
          ????"html/template"
          ????"net/http"
          )

          func?process(w?http.ResponseWriter,?r?*http.Request)??{
          ????t,?_?:=?template.ParseFiles("tmpl.html")?//?解析模板,返回?Template
          ????t.Execute(w,?"Hello?World!")??//?執(zhí)行模板,并將其傳遞給?w
          }

          func?main()??{
          ????http.HandleFunc("/template",?process)
          ????http.ListenAndServe(":8080",?nil)
          }

          運行上述代碼啟動服務器,在終端窗口通過 curl 請求 /template 路由,返回結果如下:

          表明 HTML 模板解析渲染成功,對應的 {{ . }} 也別替換成 Hello World!

          解析模板

          在上面的示例代碼中,我們調用了 ParseFiles 方法解析模板文件并創(chuàng)建稍后執(zhí)行的解析后的 Template。其底層分為兩步,它可以接收一個或多個模板文件名稱,傳入多個模板文件名的時候,會以第一個文件名作為模板名稱,后續(xù)其它模板通常是第一個模板或者其他模板嵌套的子模板。

          此外,我們還可以通過 ParseGlob 方法解析模板,該方法傳入的參數是模式匹配串,而不是文件名稱:

          t,?_?:=?template.ParseFiles("tmpl.html")
          t,?_?:=?template.ParseGlob("*.html")

          如果當前路徑只有一個 tmpl.html 模板文件,上述代碼的效果是一樣的。

          除了解析文件之外,還支持解析字符串,實際上,所有解析方法最終調用的都是 Parse 方法:

          package?main

          import?(
          ????"html/template"
          ????"net/http"
          )

          func?parseFiles(w?http.ResponseWriter,?r?*http.Request)??{
          ????t,?_?:=?template.ParseFiles("tmpl.html")
          ????t.Execute(w,?"Hello?World!")
          }

          func?parseString(w?http.ResponseWriter,?r?*http.Request)??{
          ????tmpl?:=?`?
          ????????
          ????????????
          ????????????Go?Web?Programming
          ????????
          ????????
          ????????????{{?.?}}
          ?????????
          ????`


          ????t?:=?template.New("tmpl.html")
          ????t.Parse(tmpl)
          ????t.Execute(w,?"Hello?World!")
          }

          func?main()??{
          ????http.HandleFunc("/template",?parseFiles)
          ????http.HandleFunc("/string",?parseFiles)
          ????http.ListenAndServe(":8080",?nil)
          }

          上面 parseString 方法和 parseFiles 方法實現的效果是一樣的,實際上 ?template.ParseFiles("tmpl.html") 底層調用的代碼正是:

          t?:=?template.New(filename)
          t.Parse(string)?//?string?就是讀取傳入?file?的文本內容

          在上面的代碼中,我們忽略了 template.ParseFiles 返回的錯誤信息,不過,Go 官方建議我們對這個錯誤進行處理,為此,Go 還提供了更簡潔的方式來處理模板解析過程中出現的錯誤:

          t?:=?template.Must(template.ParseFiles("tmpl.html"))

          這種情況下,如果解析模板過程中出現問題,則拋出 panic(在 Go 語言中,panic 有點類似其它語言的異常,當函數內拋出 panic 時,會一直上溯到 main 入口,然后崩潰)。

          執(zhí)行模板

          如果只解析一個模板文件的話,使用 Execute 方法就夠了,如果要解析多個模板文件,也可以使用 Execute 方法,這個時候,會使用傳入模板文件的第一個作為模板名稱,并將其作為入口模板,如果要指定其它模板作為入口模板(或者稱之為布局模板),需要調用 ExecuteTemplate 方法并將模板名作為第二個參數傳遞進去:

          t,?_?:=?template.ParseFiles("t1.html",?"t2.html")
          t.Execute(w,?"Hello?World!")
          t.ExecuteTemplate(w,?"t1.html",?"Hello?World!")

          上面的 t.Executet.ExecuteTemplate 執(zhí)行結果等效,如果你要從 t2.html 開始解析,需要這樣指定入口文件:

          t.ExecuteTemplate(w,?"t2.html",?"Hello?World!")


          (全文完)



          推薦閱讀



          學習交流 Go 語言,掃碼回復「進群」即可


          站長 polarisxu

          自己的原創(chuàng)文章

          不限于 Go 技術

          職場和創(chuàng)業(yè)經驗


          Go語言中文網

          每天為你

          分享 Go 知識

          Go愛好者值得關注



          瀏覽 75
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  婷婷无码成人精品俺来俺去 | 亚洲影院第一页在线观看 | 久久草大香蕉 | A片网电影在线观看 | 国产美女一级真毛片酒店 |