package main import ( "fmt" "html/template" "net/http" "os" "path" "strings" "time" ) type Article struct { Title string // 文章标题 Click int64 // 文章点击数 } // GetCurrentYear 获取当前年份 // @return int 当前年份 func GetCurrentYear() int { location, _ := time.LoadLocation("Asia/Shanghai") return time.Now().In(location).Year() } // GetSum 求两数之和 // @param num1 int64 整数1 // @param num2 int64 整数2 // @return int 两数之和 func GetSum(num1 int64, num2 int64) int64 { return num1 + num2 } // GetArticleList 获取文章列表数据 // @param args ...string 参数 // @return []Article 文章列表数据 func GetArticleList(args ...string) []Article { // 提取出参数 argsMap := make(map[string]any) for _, arg := range args { item := strings.Split(arg, "=") if len(item) == 2 { argsMap[item[0]] = item[1] } } orderby := argsMap["orderby"] // 文章排序规则 row := argsMap["row"] // 要获取多少条记录 tid := argsMap["tid"] // 文章分类ID fmt.Printf("orderby = %+v \n", orderby) // orderby = aid DESC fmt.Printf("row = %+v \n", row) // row = 5 fmt.Printf("tid = %+v \n", tid) // tid = 3 // 这里需要根据tid、row等参数查出文章列表数据,由于只是演示原理,故不实现完整功能直接返回数据 list := []Article{ {Title: "孩儿立志出乡关", Click: 1001}, {Title: "学不成名誓不还", Click: 1002}, {Title: "埋骨何须桑梓地", Click: 1003}, {Title: "人生无处不青山", Click: 1004}, } return list } func main() { http.HandleFunc("/demo", func(writer http.ResponseWriter, request *http.Request) { filename := "demo.htm" // 模板文件名 rootPath, _ := os.Getwd() files := path.Dir(rootPath) + "/template/default/*.htm" // 模板文件正则 // 创建模板 tmpl := template.New(filename) // 修改模板标签定界符 tmpl.Delims("{MN:", "}") // 函数映射,功能是实现在模板文件调用自定义函数。 // 重要说明:函数映射必须在解析模板文件前调用。 tmpl.Funcs(template.FuncMap{ "GetArticleList": GetArticleList, "GetCurrentYear": GetCurrentYear, "GetSum": GetSum, }) // 解析模板 _, err := tmpl.ParseGlob(files) if err != nil { _, _ = writer.Write([]byte("解析模板文件出错,原因:" + err.Error())) return } // 列表数据 list := []Article{ {Title: "PHP是世界上最好の语言", Click: 1024}, {Title: "Go语言开发·从入门到放弃", Click: 512}, {Title: "MySQL·从删库到跑路", Click: 256}, } // 需要在模板渲染的数据 data := map[string]any{ "website": "码农人生", // 模板文件调用示例:{{.website}} "title": "模板引擎的使用", // 模板文件调用示例:{{.title}} "name": "张三", // 模板文件调用示例:{{.name}} "age": 18, // 模板文件调用示例:{{.age}} "gender": "男", // 模板文件调用示例:{{.gender}} "list": list, } // 渲染模板文件 err = tmpl.ExecuteTemplate(writer, filename, data) if err != nil { _, _ = writer.Write([]byte("渲染模板文件出错,原因:" + err.Error())) return } }) _ = http.ListenAndServe(":8081", nil) } //========== 总结 ==========// // 1、修改模板文件是即时生效的,不需要重启服务器。
<!doctype html> <html lang="zh"> <head> <meta charset="utf-8"> <title>{MN:.title} - {MN:.website}</title> </head> <body> <!-- 包含全站通用底部模板 --> {MN:template "head.htm" .} <!-- 重要提醒:被包含的模板文件名称后面要加一个小数点,否则无法渲染变量 --> <!-- 模板引擎会把HTML注释屏蔽,查看网页源代码是看不到这段文字的 --> 『body』部分:俺叫{MN:.name}({MN:.gender}),今年{MN:.age}岁。<br> <!-- 遍历列表数据示例 --> <ul> <li>========== 遍历开始 ==========</li> {MN:range $index, $row := .list} <li>第{MN:$index}条记录:{MN:$row.Title}(点击数:{MN:$row.Click})</li> {MN:end} <li>========== 遍历结束 ==========</li> </ul> <!-- 获取文章列表示例 --> {MN:$art :=(GetArticleList "tid=3" "orderby=aid DESC" "row=5")} <ul> <li>========== 获取文章列表示例开始 ==========</li> {MN:range $index, $row := $art} <li>第{MN:$index}条记录:{MN:$row.Title}(点击数:{MN:$row.Click})</li> {MN:end} <li>========== 获取文章列表示例结束 ==========</li> </ul> <!-- 包含全站通用底部模板 --> {MN:template "foot.htm" .} <!-- 重要提醒:被包含的模板文件名称后面要加一个小数点,否则无法渲染变量 --> </body> </html>
『head』部分:俺叫{MN:.name}({MN:.gender}),今年{MN:.age}岁。<br> <br>
『foot』部分:俺叫{MN:.name}({MN:.gender}),今年{MN:.age}岁。<br> <br> <!-- 调用自定义函数示例 --> Copyright © {MN:GetCurrentYear} 码农人生. All Rights Reserved<br> <br> <!-- 调用自定义函数示例 --> 两数之和为:{MN:GetSum 10 24}<br> <br>
Copyright © 2024 码农人生. All Rights Reserved