【Gee-Web框架】【Day6】【Golang】模板Template

  1. 实现静态资源服务Static Resource
  2. 支持HTML模板渲染

一、 服务端渲染

1. 简要说明

  • 前后端分离的开发模式,web后端提供RESTful接口,返回结构化的数据(通常是JSON或者XML),前端使用AJAX技术请求到所需的数据,利用JavaScript进行渲染。
  • Vue/React等前端框架火热,优势突出
  • 后端专注解决资源利用、并发、数据库等问题,只需考虑数据如何生成
  • 前端专注界面设计实现,只需要考虑拿到数据后如何渲染即可

2. 静态文件(Serve Static Files)

  • 网页三剑客:JavaScript、CSS、HTML
  • 要做到服务端渲染,第一步要支持JS、CSS等静态文件
  • gee.go
    func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem){
    	absolutePath := path.Join(group.prefix, relativePath)
    	fileServer := http.StripPrefix(absolutePath, 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(relativePath string, root string){
    	handler := group.createStaticHanlder(relativePath, http.Dir(root))
    	urlPattern := path.Join(relativePath, "/*filepath")
    	group.GET(urlPattern, handler)	
    }
    

3. HTML模板渲染

  • Go语言内置了text/template和html/template两个模板标准库
  • html/template为HTML提供了较为完整的支持
    • 包括普通变量渲染、列表渲染、对象渲染等
  • 使用html/template提供的渲染能力
    type Engine struct{
    	*RouterGroup
    	router *router
    	groups []*RouterGroup
    	htmlTemplates *templat.Template  // 将所有的模板加载进内存
    	funcMap template.FuncMap	  // 所有的自定义模板渲染函数
    }
    
    // 设置自定义渲染函数
    func (engine *Engine) SetFuncMap(funcMap template.FuncMap){
    	engine.funcMap = funcMap	
    }
    
    // 加载模板
    func (engine *Engine) LoadHTMLGlob(pattern string){
    	engine.htmlTampletes = template.Must(template.New("").Funcs(engine.funcMap).ParseGlob(pattern))	
    }
    
  • context.go
    type Context struct{
    	engine *Engine	
    }
    	
    func (c *Context) HTML(code int, name string, data interface{}){
    	c.SetHeader("Content-Type", "text/html")
    	c.Status(code)
    	if err := c.engine.htmlTemplates.ExecuteTemplate(c.Writer, name, data); err != nil{
    		c.Fail(500, err.Error())
    	}	
    }
    
  • gee.go
    func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request){
    	c := newContext(w, req)
    	c.handlers = middilewares
    	c.engine = engine
    	engine.router.handle(c)	
    }
    
  • main.go
    【Gee-Web框架】【Day6】【Golang】模板Template_第1张图片
    
    <html>
        <link rel="stylesheet" href="/assets/css/geektutu.css">
        <p>geektutu.css is loadedp>
    html>
    
    type student struct{
    	Name string
    	Age int8	
    }
    	
    func FormatAsDate(t time.Time) string{
    	year, month, day := t.Date()
    	return fmt.Sprintf("%d-%02d-%02d", year, month, day)	
    }
    
    func main(){
    	r := gee.New()
    	r.Use(gee.Logger())
    	r.SetFuncMap(template.FuncMap{
    		"FormatAsDate": FormatAsDate,	
    	})	
    	r.LoadHTMLGlob("templates/*")
    	r.Static("/assets", "./static")
    	
    	stu1 := &student{Name: "Geektutu", Age: 20}
    	stu2 := &student{Name: "xcc", Age: 22}
    	r.GET("/", func(c *gee.Context){
    		c.HTML(http.StatusOK, "css.tmpl", nil)	
    	})
    	r.GET("/students", func(c *gee.Context){
    		c.HTML(http.StatusOK, "arr.tmpl", gee.H{
    			"title": "gee",
    			"stuArr": [2]*student{stu1, stu2},	
    		})	
    	})
    	r.GET("/date", func(c *gee.Context){
    		c.HTML(http.StatusOK, "custom_func.tmpl", gee.H{
    			"title": "gee",
    			"now": time.Date(2019, 8, 17, 0, 0, 0, 0, time.UTC)	
    		})	
    	})
    	r.Run(":9999")
    }
    
  • 测试
    • 浏览器访问主页:http://localhost:9999
    • 预期效果:模板正常渲染,CSS静态文件加载成功

二、 待续…

参考

  1. https://geektutu.com/post/gee-day6.html

你可能感兴趣的:(GeeWeb,前端,golang,开发语言)