6. 模板 HTML Template

Kesa...大约 1 分钟golang

https://github.com/dreamjz/golang-notes/tree/main/books/7-days-golang/Gee/day6-html-templateopen in new window

目录结构:

\DAY6-HTML-TEMPLATE
│  go.mod
│  go.work
│  main.go
│
├─gee
│      context.go
│      gee.go
│      go.mod
│      logger.go
│      router.go
│      router_group.go
│      router_test.go
│      trie.go
│
├─static
│      tst.txt
│
└─tmpl
        tst.tmpl

1. 静态文件 (Serve Static Files)

1.1 router_group


func (group *RouterGroup) createStaticHandler(relPath string, fs http.FileSystem) HandlerFunc {
	absPath := path.Join(group.prefix, relPath)
	fileServer := http.StripPrefix(absPath, http.FileServer(fs))
	return func(c *Context) {
		file := c.Param("filepath")

		if _, err := fs.Open(file); err != nil {
			c.Status(http.StatusNotFound)
			return
		}
		fileServer.ServeHTTP(c.Writer, c.Req)
	}
}

func (group *RouterGroup) Static(relPath string, root string) {
	handler := group.createStaticHandler(relPath, http.Dir(root))
	urlPattern := path.Join(relPath, "/*filepath")

	group.GET(urlPattern, handler)
}

Static将磁盘路径映射到relPath上,然后注册路由。

1.2 Demo

func main() {
	r := gee.New()

	r.Static("/assets", "./static")

	r.Run(":8000")
}
$ curl http://localhost:8000/assets/tst.txt
123

访问/assets/tst.txt将本地文件./static/tst.txt返回。

2. HTML 模板

使用http/template可以进行 HTML 模板渲染。

2.1 gee

type Engine struct {
	*RouterGroup
	router *router
	groups []*RouterGroup // store all groups
	// HTML rendering
	htmlTmpls *template.Template
	funcMap   template.FuncMap
}

func (engine *Engine) SetFuncMap(funcMap template.FuncMap) {
	engine.funcMap = funcMap
}

func (engine *Engine) LoadHTMLGlob(pattern string) {
	engine.htmlTmpls = template.Must(template.New("").Funcs(engine.funcMap).ParseGlob(pattern))
}

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	...
	c.engine = engine
	engine.router.handle(c)
}
  • LoadHTMLGlob:将模板文件读取至内存中
  • SetFuncMap:设置渲染函数

2.2 Context

type Context struct {
	...
    // engine
	engine *Engine
}

func (c *Context) HTML(code int, tmplName string, data any) {
	c.SetHeader("Content-Type", "text/html")
	c.Status(code)
	if err := c.engine.htmlTmpls.ExecuteTemplate(c.Writer, tmplName, data); err != nil {
		c.Fail(500, err.Error())
	}
}
  • HTML:改为渲染指定的 HTML 模板
  • Context:持有 Engine实例,可访问模板及渲染函数

2.3 Demo


func main() {
	r := gee.New()

	r.Static("/assets", "./static")
	r.LoadHTMLGlob("tmpl/*")

	r.GET("/hello/:name", func(c *gee.Context) {
		c.HTML(http.StatusOK, "tst.tmpl", gee.H{
			"name": c.Param("name"),
		})
	})

	r.Run(":8000")
}
$ curl http://localhost:8000/hello/alice
<h1>Hello alice </h1>

Reference

  1. https://geektutu.com/post/gee-day6.htmlopen in new window
上次编辑于:
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.2