国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Go Web 編程中的模板庫應用指南(超詳細)

Go Web 編程中的模板庫應用指南(超詳細)

2020-06-06 12:24kevin_tech Golang

這篇文章主要介紹了Go Web 編程中的模板庫應用指南,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

如果你有過Web編程的經驗,那么或多或少都聽說過或者使用過模板。簡而言之,模板是可用于創建動態內容的文本文件。例如,你有一個網站導航欄的模板,其中動態內容的一部分可能是根據當前用戶是否登錄顯示登錄還是退出按鈕。

Go提供了兩個模板庫 text/template和 html/template。這兩個模板庫的使用方式是相同的,但是 html/template包在渲染頁面模板時會在后臺進行一些編碼以幫助防止造成代碼注入(XSS 攻擊)。

因為兩個模板庫都使用相同的接口,因此本文中介紹的所有內容均可用于這兩個程序包,但是大多數時候我們都會使用 html/template程序包來生成HTML代碼段。

模板文件的后綴名

模板文件可以使用 .html或任何其他擴展名。但是通常我們將使用 .gohtml擴展名來命名模板文件,因為編輯器通常使用它來表示你想要高亮 GoHTML模板語法。Atom和 SublimeText等編輯器都具有 Go插件,來默認識別此擴展名。

模板語法

我們先來創建一個簡單的模板文件 test.gohtml:

?
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Go Web</title>
 </head>
 <body>
 {{ . }}
 </body>
</html>

{{ 和 }} 中間的半角句號 . 它代表模板對象執行 Execute(w,data)傳入模板的數據,它是頂級作用域范圍內的,根據傳入的數據不同渲染不同的內容。. 可以代表 Go語言中的任何類型,如結構體、 Map等。

在寫模板的時候,會經常用到 .。比如 {{.}}、 {{len.}}、 {{.Name}}、 {{$x.Name}}

{{ 和 }} 包裹的內容統稱為 action,分為兩種類型:

數據求值(data evaluations)

控制結構(control structures)

action求值的結果會直接復制到模板中,控制結構和我們寫 Go程序差不多,也是條件語句、循環語句、變量、函數調用等等...模板中的 action 并不多,我們一個一個看。

注釋

{{/* comment */}}

裁剪空字符

注意裁剪的是替換內容前面或者后面的空字符,你可以理解成模板中{{前面或}}后面的空字符(包括換行符、制表符、空格等)。

// 裁剪 content 前后的空字符
{{- content -}}
// 裁剪 content 前面的空字符
{{- content }}
// 裁剪 content 后面的空字符
{{ content -}}

文本輸出

{{ pipeline }}

pipeline代表的數據會產生與調用 fmt.Print 函數類似的輸出,例如整數類型的 3 會轉換成字符串 "3" 輸出。

條件語句

{{ if pipeline }} T1 {{ end }}
{{ if pipeline }} T1 {{ else }} T0 {{ end }}
{{ if pipeline }} T1 {{ else if pipeline }} T0 {{ end }}
// 上面的語法其實是下面的簡寫
{{ if pipeline }} T1 {{ else }}{{ if pipeline }} T0 { {end }}{{ end }}
{{ if pipeline }} T1 {{ else if pipeline }} T2 {{ else }} T0 {{ end }}

如果 pipeline 的值為空,不會輸出 T1,除此之外 T1 都會被輸出。

空值有 false、 0、 nil空字符串 ""(長度為 0 的字符串)。

循環語句

{{ range pipeline }} T1 {{ end }}
// 這個 else 比較有意思,如果 pipeline 的長度為 0 則輸出 else 中的內容
{{ range pipeline }} T1 {{ else }} T0 {{ end }}
// 獲取容器的下標
{{ range $index, $value := pipeline }} T1 {{ end }}

循環語句中的 pipeline 的值必須是數組、切片、字典和通道中的一種,即可迭代類型的值,根據值的長度輸出多個 T1。

define

{{ define "name" }} T {{ end }}

定義命名為 name 的模板。

template

{{ template "name" }}
{{ template "name" pipeline }}

第一種是直接執行名為 name的模板,模板的全局數據對象 .設置為 nil。第二種是點 .設置為pipeline的值,并執行名為 name的模板。

block

{{ block "name" pipeline }} T1 {{ end }}

block 的語義是如果有命名為 name 的模板,就引用過來執行,如果沒有命名為 name 的模板,就是執行自己定義的內容。換句話說,block可以認為是設置一個默認模板。

with

{{ with pipeline }} T1 {{ end }}
// 如果 pipeline 是空值則輸出 T0
{{ with pipeline }} T1 {{ else }} T0 {{ end }}
{{ with arg }}
    . // 此時 . 就是 arg
{{ end }}

with 創建一個新的上下文環境,在此環境中的 . 與外面的 . 無關。

對于第一種格式,當pipeline不為0值的時候,點 .設置為pipeline運算的值,否則跳過。對于第二種格式,當pipeline為0值時,執行else語句塊,否則 .設置為pipeline運算的值,并執行T1。

例如:

{{with .Person}}{{ .Name}}{{end}}

在這個 with 塊中 .Name實際上引用的是全局數據對象的 .Person.Name。

實踐練習:課程花名冊頁面

了解完模板語法后,接下來讓我們在 http_demo項目中結合 BootStrap創建一個簡單的模板,來展示服務器如何把數據傳遞給模板、渲染 HTML頁面,把頁面響應返回給客戶端。

我們創建一個用來展示大學物理課程的花名冊(授課老師和上課學生)

創建頁面模板

首先在我們的項目添加一個 views目錄用于存放模板文件,在創建三個模板文件分別是:

layout.gohtml 用于存放頁面的整體布局。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html lang="en">
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="description" content="">
 <meta name="author" content="">
 <title>Bootstrap Template Page for Go Web Programming</title>
 <!-- Bootstrap core CSS -->
 <link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
</head>
<body>
{{ template "nav" .}}
<div class="container">
 {{template "content" .}}
</div>
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

nav.gohtml是網頁頭部區域的頁面模板。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{{define "nav"}}
<nav class="navbar navbar-inverse navbar-fixed-top">
 <div class="container">
 <div class="navbar-header">
  <a class="navbar-brand" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Person general infor</a>
 </div>
 </div>
</nav>
<div class="jumbotron">
 <div class="container">
 <h1>Hello, Professor {{.Teacher.Name}}</h1>
 <ul>
  <li>Name : {{.Teacher.Name}}<p>
  <li>Subject : {{.Teacher.Subject}}
 </ul>
 <p><a class="btn btn-primary btn-lg" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" role="button">More &raquo;</a></p>
 </div>
</div>
{{end}}

content.gohtml是網頁主體內容部分的頁面模板。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{{define "content"}}
{{range .Students}}
<div class="row">
 <div class="col-md-4">
 <h2>Name</h2>
 <p>Name has the value of : {{.Name}} </p>
 <p><a class="btn btn-default" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" role="button">More &raquo;</a></p>
 </div>
 <div class="col-md-4">
 <h2>Id</h2>
 <p>Id has the value of : {{.Id}} </p>
 <p><a class="btn btn-default" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" role="button">More &raquo;</a></p>
 </div>
 <div class="col-md-4">
 <h2>Country</h2>
 <p>Country has the value of : {{.Country}} </p>
 <p><a class="btn btn-default" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" role="button">More &raquo;</a></p>
 </div>
</div>
{{end}}
{{end}}

在 layout.gohtml中我們引用了另外的兩個模板:

{{ template "nav" .}}
{{template "content" .}}

這樣不同的頁面變化的部分就只是 content部分,針對不同的頁面我們只需要定義多個 content模板,每次根據不同請求使用不同的 content模板就行了。當然這里的例子有點簡陋,大家理解意思就行了。

注意模板名稱后面的 .,我們把 layout.gohtml的全局數據對象傳給了另外兩個模板這樣,在子模板里也能訪問傳給模板的數據了。如果頁面模板中使用的數據字段和循環語句有點疑惑可以先不用管,繼續往下看,等看過傳給頁面模板的數據后自然就理解了。

創建響應頁面請求的Handler

接下來創建一個伺服頁面請求的 Handler:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package handler
import (
 "fmt"
 "html/template"
 "net/http"
)
type Teacher struct {
 Name string
 Subject string
}
type Student struct {
 Id int
 Name string
 Country string
}
type Rooster struct {
 Teacher Teacher
 Students []Student
}
func ShowIndexView(response http.ResponseWriter, request *http.Request) {
 teacher := Teacher{
 Name: "Alex",
 Subject: "Physics",
 }
 students := []Student{
 {Id: 1001, Name: "Peter", Country: "China"},
 {Id: 1002, Name: "Jeniffer", Country: "Sweden"},
 }
 rooster := Rooster{
 Teacher: teacher,
 Students: students,
 }
 tmpl, err := template.ParseFiles("./views/layout.gohtml",
     "./views/nav.gohtml",
     "./views/content.gohtml")
 if err != nil {
 fmt.Println("Error " + err.Error())
 }
 tmpl.Execute(response, rooster)
}

使用 template.ParseFiles加載這個頁面要使用的全部三個模板(如果加載少了,訪問頁面時會發生 panic),然后使用模板對象的 Execute方法把我們存儲了花名冊信息的數據對象傳給模板: tmpl.Execute(response,rooster) 渲染頁面并寫到響應里去( http.ResponseWriter對象)。

注冊頁面路由

處理程序寫完后,為其注冊路由,在我們項目的路由模塊添加如下路由:

?
1
2
3
4
5
6
7
8
9
10
11
12
package router
import (
 "example.com/http_demo/middleware"
 "github.com/gorilla/mux"
 "example.com/http_demo/handler"
)
func RegisterRoutes(r *mux.Router) {
 r.Use(middleware.Logging())
...
 viewRouter := r.PathPrefix("/view").Subrouter()
 viewRouter.HandleFunc("/index", handler.ShowIndexView)
}

訪問頁面

現在所有步驟都完成了,重啟我們的服務器后就可以訪問到新寫的頁面了。

如果是在本地電腦里,用 Ctrl+C結束服務器進程后再次執行 go run main.go。如果是使用我們之前文章里的 Docker開發環境的話,需要在 docker-compose.yml所在的目錄里用 docker-compose restart重啟服務。

打開瀏覽器輸入 http://localhost:8000/view/index就能訪問到我們剛才寫的頁面了。

Go Web 編程中的模板庫應用指南(超詳細)

總結

今天的文章講解了 Go模板最常使用的幾個功能的使用方法,使用 html/template模板庫結合 BootStrap做頁面模板,還是比較簡單的 BootStrap幫我們解決了很多前端的樣式問題。模板庫還有很多更高級的用法,比如在模板中調用函數、定義變量等功能,可以看下文末給出的參考鏈接了解這部分內容。在前后端分離架構流行的今天我覺得作為用 Go開發的后端工程師了解文章中列出的這些功能就夠了。

今天的例子中是通過 CDN 引用的 BootStrap靜態資源,到目前我們的服務器還無法伺服靜態資源,這個我們下篇文章再講。

到此這篇關于Go Web 編程中的模板庫應用指南(超詳細)的文章就介紹到這了,更多相關go web 編程模塊庫內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/kevin_tech/article/details/104667071/

延伸 · 閱讀

精彩推薦
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
主站蜘蛛池模板: 青青久视频 | 欧美视频网站 | 国产资源免费观看 | 91在线高清 | 日韩欧美二区 | 激情综合五月 | 精品亚洲永久免费精品 | 内地农村三片在线观看 | 日韩精品视频一区二区三区 | 日美毛片 | 亚洲91精品| 欧美精品一区二区在线观看 | 看日韩毛片 | 人人爱人人爽 | 少妇精品视频在线观看 | 国产韩国精品一区二区三区 | 无码日韩精品一区二区免费 | 日韩91| 国产欧美一区二区视频 | 黄色av网站在线观看 | 一区二区av在线 | 亚洲精品久久久一区二区三区 | 亚洲精品久久久久久久久久久久久 | 婷婷在线视频 | 成人国产精品视频 | 国产裸体永久免费视频网站 | 国产99久久精品一区二区永久免费 | 亚洲国产精品一区二区三区 | 免费观看黄色av网站 | 精品国产91| 亚洲国产精品无卡做爰天天 | 一本久道视频一本久道 | 久久久亚洲精品视频 | 成人精品一区二区三区 | 男女啪啪免费网站 | 中文字幕免费看 | 亚洲亚色 | 中文字幕在线免费播放 | 国产成人av网站 | 福利网址| 在线国产视频 |