beego的模板處理引擎采用的是Go內置的html/template包進行處理,而且beego的模板處理邏輯是采用了緩存編譯方式,
也就是所有的模板會在beego應用啟動的時候全部編譯然后緩存在map里面。
1.模板目錄
beego中默認的模板目錄是views,用戶可以把模板文件放到該目錄下,
beego會自動把該目錄下的所有模板文件進行解析並緩存,開發模式下每次都會重新解析,不做緩存。
當然,用戶也可以通過如下的方式改變模板的目錄(只能指定一個目錄為模板目錄):
beego.ViewsPath = "myviewpath"
2.自動渲染
用戶無需手動的調用渲染輸出模板,beego會自動地在調用完相應地method方法之后調用Render函數,
當然如果你的應用是不需要模板輸出地,那么可以在配置文件或者main.go中設置關閉自動渲染。
配置文件如下:
autorender = false
main.go文件中設置如下:
beego.AutoRender = false
3.模板標簽
Go語言的默認模板采用了{{和}}作為左右標簽,但是我們有時候在開發中可能界面是采用了Angular JS開發,
他的模板也是這個標簽,故而引起了沖突,在beego中你可以通過配置文件或者直接設置配置變量修改:
beego.TemplateLeft = "<<<" beego.TemplateRight = ">>>"
4.模板數據
模板中數據是通過在Controller中this.Data獲取的,所以如果你想在模板中獲取內容{{.Content}},那么你需要在Controller中如下設置:
this.Data["Content"] = "value"
如何使用各種類型的數據渲染:
(1)結構體
結構體結構
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}}
(2)map
控制器數據賦值
mp["name"]="astaxie" mp["nickname"] = "haha" this.Data["m"]=mp
模板渲染數據如下:
the username is {{.m.name}} the username is {{.m.nickname}}
(3)slice
控制器數據賦值
ss :=[]string{"a","b","c"} this.Data["s"]=ss
模板渲染數據如下:
{{range $key, $val := .s}} {{$key}} {{$val}} {{end}}
5.模板名稱
beego采用了Go語言內置的模板引擎,所有模板的語法和Go的一模一樣。
用戶通過在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
文件。
6.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" .}}
7.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"] = "" }
8.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 方法 共用一個標簽,標簽后面有三個可選參數,用 ,
分割。
第一個參數為表單中類型的 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="">