和有些小伙伴一樣,本人是從php轉(zhuǎn)到了go,從事php時使用symfony框架一直享受其豐富的功能帶來的便利,轉(zhuǎn)到其他語言時比較直觀的感覺就是twig真強(qiáng),為什么其他語言沒有擴(kuò)展twig呢?
創(chuàng)新互聯(lián)建站服務(wù)項目包括瀘水網(wǎng)站建設(shè)、瀘水網(wǎng)站制作、瀘水網(wǎng)頁制作以及瀘水網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,瀘水網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到瀘水省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
雖然前后端的開發(fā)模式,讓模板引擎這個東西慢慢淡去,但是有時候還是需要用到這種東西,所以就有了,go調(diào)用php實現(xiàn)twig模板引擎的想法。
原理,go 通過exec.Command調(diào)用php,通過STDIN,STDOUT 方式進(jìn)行數(shù)據(jù)交互
go在初始化階段提供一些配置參數(shù),比如模板引擎的為止,是否為開發(fā)環(huán)境等,php接收數(shù)據(jù)并初始化
初始換環(huán)境完畢后,當(dāng)需要渲染模板,go再講模板文件和數(shù)據(jù)以json字符串的形式寫入STDIN告知php,
php接收到數(shù)據(jù)后,解析數(shù)據(jù),選取指定的模板并渲染,然后通過STDOUT返回給go
這樣一次渲染就結(jié)束了
整理好的文件打包在github上了
如果喜歡就動動你的小手指點個贊,star一下吧!
可以。golang模板引擎動態(tài)可以讀取sql。text/template是Go語言標(biāo)準(zhǔn)庫,實現(xiàn)數(shù)據(jù)驅(qū)動模板以生成文本輸出,可以理解為一組文字按照特定格式動態(tài)嵌入另一組文字中。
1.用{{}}包圍的是變量,如 {{testName}} ,這表示把給定變量的值插入, {%%}這是塊元素 在faygo里叫tag,常見的有 for , if 等
2.如何在模板中定義變量, 平常我們在使用的模板的時候的常會有這樣的需要,在模板中要定義一個變量以方便前端邏輯的實現(xiàn),在faygo模板中定義變量需要用到標(biāo)簽{%set%}
使用方法
{#定義變量 newName #}
{% set newName = "hello faygo" %}
{#獲取變量newName的值#}
{{newName}}
定義用 tag set 取值就是上文所提到的{{}}取值
3.在模板中調(diào)用方法
這也是一個非常常見和有用的方法,在faygo中調(diào)用方法有兩種方式 , 一是在渲染模板時在faygo.Map在加入你要調(diào)用的方法 , 二是注冊一個全局的方法 (在faygo里叫filter過濾器),我們分別來看一下每個方法的實現(xiàn)
1) 在渲染模板時加入方法(render)
//在后端render時加入方法 testFunc
rErr := ctx.Render(200, switchDir+"index.html", faygo.Map{
"TITLE": title,
"testMap": map[string]string{"aaa": "111111"},
"testFunc": func(s string) string {
return s + " this is test func"
},
})
{#前端模板中調(diào)用#}
{{ testFunc("hello") }}
結(jié)果如下
hello this is test func
這種方法適合只用于此模板一個特殊方法 , 在其它功能中不通用 ,那么如果想定義一個方法全局都可以使用怎么辦,這里就需要注冊全局方法了(見下文)
2)注冊全局方法(過濾器)
如果想定義一個方法全局都可以使用怎么辦 ,這里就需要注冊一個方法
// pongo2 注冊一個全局過濾器,一般在程序啟動時init中注冊
//這里注冊了一個名叫testFilter的過濾器,指向TestFilterFunc方法
pongo2.RegisterFilter("testFilter", TestFilterFunc)
func TestFilterFunc(in, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
a := in.String() + " this is global filter"
return pongo2.AsValue(a), nil
}
在這里我們看到TestFilterFunc方法里接收參數(shù)和返回參數(shù)的類型是pongo2.Value和pongo2.Error
在注冊過濾器里方法的接收參數(shù)和返回參數(shù)是固定的這兩個不能改變
官網(wǎng)的話:
All functions’ parameters types must be of either your own type or of type *pongo2.Value(no matter how many) and functions must return one value of either type *Value or your own one.
那么我們返回數(shù)據(jù)時怎么返回? 在上面例子在我們看到了 AsValue 這個方法可以將我們數(shù)據(jù)返回,我們可以返回struct,map,array,string 等
在前端調(diào)用
{{ "hello" | testFilter }}
結(jié)果:
hello this is global filter
返回結(jié)構(gòu)體:
type LoginUserInfo struct {
Username string `json:"username"`
Telephone string `json:"telephone"`
Email string `json:"email"`
Level int `json:"level"`
}
func TestFilterFunc(in, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
userInfo := LoginUserInfo{
Username: "userA",
Telephone: "123456",
Email: "123456@test.com",
Level: 1,
}
return pongo2.AsValue(userInfo), nil
}
前端使用:
{#定義一個變量接收struct數(shù)據(jù) #}
{% set uinfo = "" | testFilter %}
{#取用戶名字#}
{{ uinfo.Username }}
注意,如是 uinfo 只是一個struct 不是struct數(shù)組([]uinfo)時 在模板中不能使用{% for %} 使用也不會得到任何數(shù)據(jù)
如果uinfo是struct數(shù)組 在模板中for循環(huán)時不要使用 key,val in uinfo
如果uinfo是struct數(shù)組 uinfo = []userInfo{}
{#錯誤示例#}
{% for key,val in uinfo %}
{{val.Username}}
{% endfor %}
struct數(shù)據(jù)不能使用key,否則循環(huán)會執(zhí)行,但取不到任何數(shù)據(jù)
{# 正確示例 #}
{% for val in uinfo %}
{{val.Username}}
{% endfor %}
說一下返回map時 用for循環(huán)的情況,無論是否是map數(shù)組都可以用for key,val in uinfo 來遍歷數(shù)據(jù)
4. 在模板中字符串的連接和宏標(biāo)簽的使用
在模板中有時我們會碰到這樣的需要:在模板中有幾個變量 ,我們想把這幾個變量連接在一起賦值給另一個變量以做其它操作
例: 在模板中有三個變量 host是域名,route是路由地址,param是參數(shù) ,要把這三個變量連接起來賦值給另一個新的變量做urlencode操作。這應(yīng)該怎么辦
因為在模板中使用 + 號連接變量時,程序會認(rèn)為是數(shù)學(xué)運(yùn)算,兩個字符串的連接值為0, 如果用內(nèi)置的filter: join來連接需要傳入一個slice,但這三個只是字符串變量。
這個時候我們可能就要用到宏標(biāo)簽了% macro %% endmacro %.
思路是這樣的,在宏標(biāo)簽中定義一個宏(可以理解為一個方法),這個宏接收三個參數(shù)(參數(shù)個數(shù)看需求而定),在宏內(nèi)返回連接的字符串
代碼:
{#定義三個變量#}
{% set host="" %}
{% set route="/aaa/bbb" %}
{% set param= "?id=123" %}
{#定義一個宏標(biāo)簽接收三個參數(shù),并返回。注意在宏標(biāo)簽內(nèi)如果換行,輸出的結(jié)果中也會有換行,在urlencode的時候也會把換行符進(jìn)行轉(zhuǎn)義#}
{% macro joinUrl(paramA,paramB,paramC) %}{{paramA}}{{paramB}}{{paramC}}{% endmacro %}
hr
{#定義一個新變量調(diào)用宏方法,并將三個參數(shù)傳入#}
{% set newurl = joinUrl(host,route,param) %}
{#輸出newurl的值#}
{{newurl}}br
{#輸入出urlencode后的字符串#}
{{newurl|urlencode}}br
結(jié)果:
http%3A%2F%2F
在宏標(biāo)簽在也可加入自定義的一些字符串如在上面的宏標(biāo)簽返回結(jié)果中要加一個固定字符可以這樣寫:
{% macro joinUrl(paramA,paramB,paramC) %}{{paramA}}{{paramB}}{{paramC}}from=macro{% endmacro %}