# 模板處理
beego 的模板處理引擎采用的是 Go 內置的 `html/template` 包進行處理,而且 beego 的模板處理邏輯是采用了緩存編譯方式,也就是所有的模板會在 beego 應用啟動的時候全部編譯然后緩存在 map 里面。
## 模板目錄
beego 中默認的模板目錄是 `views`,用戶可以把模板文件放到該目錄下,beego 會自動在該目錄下的所有模板文件進行解析并緩存,開發模式下每次都會重新解析,不做緩存。當然,用戶也可以通過如下的方式改變模板的目錄(只能指定一個目錄為模板目錄):
~~~
beego.ViewsPath = "myviewpath"
~~~
## 自動渲染
用戶無需手動的調用渲染輸出模板,beego 會自動的在調用完相應的 method 方法之后調用 Render 函數,當然如果您的應用是不需要模板輸出的,那么可以在配置文件或者在 `main.go` 中設置關閉自動渲染。
配置文件配置如下:
~~~
autorender = false
~~~
main.go 文件中設置如下:
~~~
beego.AutoRender = false
~~~
## 模板標簽
Go 語言的默認模板采用了 `{{` 和 `}}` 作為左右標簽,但是我們有時候在開發中可能界面是采用了 AngularJS 開發,他的模板也是這個標簽,故而引起了沖突。在 beego 中你可以通過配置文件或者直接設置配置變量修改:
~~~
beego.TemplateLeft = "<<<"
beego.TemplateRight = ">>>"
~~~
## 模板數據
模板中的數據是通過在 Controller 中 `this.Data` 獲取的,所以如果你想在模板中獲取內容 `{{.Content}}` ,那么你需要在 Controller 中如下設置:
~~~
this.Data["Content"] = "value"
~~~
如何使用各種類型的數據渲染:
* 結構體
結構體結構
~~~
type A struct{
Name string
Age int
}
~~~
控制器數據賦值
~~~
this.Data["a"]=&A{Name:"astaxie",Age:25}
~~~
模板渲染數據如下:
~~~
the username is {{.a.Name}}
the age is {{.a.Age}}
~~~
* map
控制器數據賦值
~~~
mp["name"]="astaxie"
mp["nickname"] = "haha"
this.Data["m"]=mp
~~~
模板渲染數據如下:
~~~
the username is {{.m.name}}
the username is {{.m.nickname}}
~~~
* slice
控制器數據賦值
~~~
ss :=[]string{"a","b","c"}
this.Data["s"]=ss
~~~
模板渲染數據如下:
~~~
{{range $key, $val := .s}}
{{$key}}
{{$val}}
{{end}}
~~~
## 模板名稱
beego 采用了 Go 語言內置的模板引擎,所有模板的語法和 Go 的一模一樣,至于如何寫模板文件,詳細的請參考 [模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.4.md)。
用戶通過在 Controller 的對應方法中設置相應的模板名稱,beego 會自動的在 viewpath 目錄下查詢該文件并渲染,例如下面的設置,beego 會在 admin 下面找 add.tpl 文件進行渲染:
~~~
this.TplName = "admin/add.tpl"
~~~
我們看到上面的模板后綴名是 tpl,beego 默認情況下支持 tpl 和 html 后綴名的模板文件,如果你的后綴名不是這兩種,請進行如下設置:
~~~
beego.AddTemplateExt("你文件的后綴名")
~~~
當你設置了自動渲染,然后在你的 Controller 中沒有設置任何的 TplName,那么 beego 會自動設置你的模板文件如下:
~~~
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
~~~
也就是你對應的 Controller 名字+請求方法名.模板后綴,也就是如果你的 Controller 名是 `AddController`,請求方法是`POST`,默認的文件后綴是 `tpl`,那么就會默認請求 `/viewpath/AddController/post.tpl` 文件。
## Layout 設計
beego 支持 layout 設計,例如你在管理系統中,整個管理界面是固定的,只會變化中間的部分,那么你可以通過如下的設置:
~~~
this.Layout = "admin/layout.html"
this.TplName = "admin/add.tpl"
~~~
在 layout.html 中你必須設置如下的變量:
~~~
{{.LayoutContent}}
~~~
beego 就會首先解析 TplName 指定的文件,獲取內容賦值給 LayoutContent,然后最后渲染 layout.html 文件。
目前采用首先把目錄下所有的文件進行緩存,所以用戶還可以通過類似這樣的方式實現 layout:
~~~
{{template "header.html" .}}
Logic code
{{template "footer.html" .}}
~~~
> > > 特別注意后面的`.`,這是傳遞當前參數到子模板
## LayoutSection
對于一個復雜的 `LayoutContent`,其中可能包括有javascript腳本、CSS 引用等,根據慣例,通常 css 會放到 Head 元素中,javascript 腳本需要放到 body 元素的末尾,而其它內容則根據需要放在合適的位置。在 `Layout` 頁中僅有一個`LayoutContent` 是不夠的。所以在 `Controller` 中增加了一個 `LayoutSections`屬性,可以允許 `Layout` 頁中設置多個`section`,然后每個 `section` 可以分別包含各自的子模板頁。
layout\_blog.tpl:
~~~
<!DOCTYPE html>
<html>
<head>
? ?<title>Lin Li</title>
? ?<meta name="viewport" content="width=device-width, initial-scale=1.0">
? ?<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
? ?<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
? ?<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
? {{.HtmlHead}}
</head>
<body>
?
? ?<div class="container">
? ? ? {{.LayoutContent}}
? ?</div>
? ?<div>
? ? ? {{.SideBar}}
? ?</div>
? ?<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
? ?<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
? {{.Scripts}}
</body>
</html>
~~~
html\_head.tpl:
~~~
<style>
? ? h1 {
? ? ? color: red;
? ? }
</style>
~~~
scripts.tpl:
~~~
<script type="text/javascript">
? $(document).ready(function() {
? ? ? // bla bla bla
? });
</script>
~~~
邏輯處理如下所示:
~~~
type BlogsController struct {
? beego.Controller
}
?
func (this *BlogsController) Get() {
? this.Layout = "layout_blog.tpl"
? this.TplName = "blogs/index.tpl"
? this.LayoutSections = make(map[string]string)
? this.LayoutSections["HtmlHead"] = "blogs/html_head.tpl"
? this.LayoutSections["Scripts"] = "blogs/scripts.tpl"
? this.LayoutSections["Sidebar"] = ""
}
~~~
## renderform 使用
定義 struct:
~~~
type User struct {
Id ? int ? ? ? ? `form:"-"`
Name interface{} `form:"username"`
Age ? int ? ? ? ? `form:"age,text,年齡:"`
Sex ? string
Intro string `form:",textarea"`
}
~~~
* StructTag 的定義用的標簽用為 `form`,和 [ParseForm 方法](https://github.com/beego/beedoc/blob/master/zh-CN/mvc/controller/params.md#%E7%9B%B4%E6%8E%A5%E8%A7%A3%E6%9E%90%E5%88%B0-struct) 共用一個標簽,標簽后面有三個可選參數,用 `,` 分割。第一個參數為表單中類型的 `name` 的值,如果為空,則以 `struct field name` 為值。第二個參數為表單組件的類型,如果為空,則為 `text`。表單組件的標簽默認為 `struct field name` 的值,否則為第三個值。
* 如果 `form` 標簽只有一個值,則為表單中類型 `name` 的值,除了最后一個值可以忽略外,其他位置的必須要有 `,` 號分割,如:`form:",,姓名:"`
* 如果要忽略一個字段,有兩種辦法,一是:字段名小寫開頭,二是:`form` 標簽的值設置為 `-`
* 現在的代碼版本只能實現固定的格式,用 br 標簽實現換行,無法實現 css 和 class 等代碼的插入。所以,要實現 form 的高級排版,不能使用 renderform 的方法,而需要手動處理每一個字段。
controller:
~~~
func (this *AddController) Get() {
? this.Data["Form"] = &User{}
? this.TplName = "index.tpl"
}
~~~
Form 的參數必須是一個 struct 的指針。
template:
~~~
<form action="" method="post">
{{.Form | renderform}}
</form>
~~~
上面的代碼生成的表單為:
~~~
Name: <input name="username" type="text" value="test"></br>
年齡:<input name="age" type="text" value="0"></br>
Sex: <input name="Sex" type="text" value=""></br>
Intro: <input name="Intro" type="textarea" value="">
~~~
- go環境搭建
- 解決go get網絡慢的問題
- beego的安裝
- bee的安裝
- 編輯器
- go module
- 配置文件詳解
- 配置文件其他說明
- 路由方法
- 路由
- 數據校驗
- 校驗函數
- 頁面跳轉
- 獲取前端數據
- json文件的獲取
- xsrf的用法
- xsrf的防護
- srfs和json的搭配
- flash的用法
- 過濾器
- url反轉
- 各類數據的處理
- 模板函數
- 內置模板函數
- 自定義模板函數
- 模板
- 模板處理
- 模板渲染
- 視圖文件的處理
- 靜態文件
- 請求方式判斷
- 驗證碼
- 另一種方法
- 分頁類
- session
- 登錄判斷
- orm模塊
- 使用方法
- mysql的安裝
- 安裝orm及驅動
- 建立模型
- 自定義模型
- 增刪改查
- 高級查詢
- 常見問題匯總
- 代碼收藏
- 打包部署
- go build打包
- utils收藏
- 新goer容易犯的錯
- 字符串操作