Go语言动手写Web框架 - Gee第六天 模板(HTML Template)
源代码/数据集已上传到 Github - 7days-golang
本文是 7天用Go从零实现Web框架Gee教程系列的第六篇。
- 实现静态资源服务(Static Resource)。
- 支持HTML模板渲染。
服务端渲染
现在越来越流行前后端分离的开发模式,即 Web 后端提供 RESTful 接口,返回结构化的数据(通常为 JSON 或者 XML)。前端使用 AJAX 技术请求到所需的数据,利用 JavaScript 进行渲染。Vue/React 等前端框架持续火热,这种开发模式前后端解耦,优势非常突出。后端童鞋专心解决资源利用,并发,数据库等问题,只需要考虑数据如何生成;前端童鞋专注于界面设计实现,只需要考虑拿到数据后如何渲染即可。使用 JSP 写过网站的童鞋,应该能感受到前后端耦合的痛苦。JSP 的表现力肯定是远不如 Vue/React 等专业做前端渲染的框架的。而且前后端分离在当前还有另外一个不可忽视的优势。因为后端只关注于数据,接口返回值是结构化的,与前端解耦。同一套后端服务能够同时支撑小程序、移动APP、PC端 Web 页面,以及对外提供的接口。随着前端工程化的不断地发展,Webpack,gulp 等工具层出不穷,前端技术越来越自成体系了。
但前后分离的一大问题在于,页面是在客户端渲染的,比如浏览器,这对于爬虫并不友好。Google 爬虫已经能够爬取渲染后的网页,但是短期内爬取服务端直接渲染的 HTML 页面仍是主流。
今天的内容便是介绍 Web 框架如何支持服务端渲染的场景。
静态文件(Serve Static Files)
网页的三剑客,JavaScript、CSS 和 HTML。要做到服务端渲染,第一步便是要支持 JS、CSS 等静态文件。还记得我们之前设计动态路由的时候,支持通配符*
匹配多级子路径。比如路由规则/assets/*filepath
,可以匹配/assets/
开头的所有的地址。例如/assets/js/geektutu.js
,匹配后,参数filepath
就赋值为js/geektutu.js
。
那如果我么将所有的静态文件放在/usr/web
目录下,那么filepath
的值即是该目录下文件的相对地址。映射到真实的文件后,将文件返回,静态服务器就实现了。
找到文件后,如何返回这一步,net/http
库已经实现了。因此,gee 框架要做的,仅仅是解析请求的地址,映射到服务器上文件的真实地址,交给http.FileServer
处理就好了。
1 | // create static handler |
我们给RouterGroup
添加了2个方法,Static
这个方法是暴露给用户的。用户可以将磁盘上的某个文件夹root
映射到路由relativePath
。例如:
1 | r := gee.New() |
用户访问localhost:9999/assets/js/geektutu.js
,最终返回/usr/geektutu/blog/static/js/geektutu.js
。
HTML 模板渲染
Go语言内置了text/template
和html/template
2个模板标准库,其中html/template为 HTML 提供了较为完整的支持。包括普通变量渲染、列表渲染、对象渲染等。gee 框架的模板渲染直接使用了html/template
提供的能力。
1 | Engine struct { |
首先为 Engine 示例添加了 *template.Template
和 template.FuncMap
对象,前者将所有的模板加载进内存,后者是所有的自定义模板渲染函数。
另外,给用户分别提供了设置自定义渲染函数funcMap
和加载模板的方法。
接下来,对原来的 (*Context).HTML()
方法做了些小修改,使之支持根据模板文件名选择模板进行渲染。
1 | type Context struct { |
我们在 Context
中添加了成员变量 engine *Engine
,这样就能够通过 Context 访问 Engine 中的 HTML 模板。实例化 Context 时,还需要给 c.engine
赋值。
1 | func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
使用Demo
最终的目录结构
1 | ---gee/ |
1 | <!-- day6-template/templates/css.tmpl --> |
1 | type student struct { |
访问下主页,模板正常渲染,CSS 静态文件加载成功。
last updated at 2023-11-15