模板

未匹配的标注

模板

使用的库包

在 Gin 的 LoadHTMLGlob() 或者 LoadHTMLFiles() 基础上, 实际是 html/template 包的方法, 封装了两个多模板一次性加载的方法.

这个两个方法, 一个是非打包模板文件的加载方法, 一个是打包进程序的模板加载方法. 具体方法签名如下:

LoadHTMLGlobs(patterns ...string) error
LoadHTMLFS(embed fs.FS, patterns ...string)

实际加载

resources/resources.go

package resources

import (
    "embed"
    "gower/app"
)

var (
    route = app.Route()
    Tmpl  *embed.FS
)

func init() {
    err := route.LoadHTMLGlobs(
        "resources/views/*.tmpl",
        "resources/views/**/*.tmpl") // 支持多种层级的模板文件, 如果需要加三层, 那就添加一行 "resources/views/**/**/*.tmpl"

    if err != nil {
        if Tmpl == nil {
            panic("没有模板内容可加载")
        }

        // 如果程序根目录没有模板文件, 从打包的程序内部找模板, 多层级继续添加 "views/**/**/*.tmpl"
        route.LoadHTMLFS(Tmpl,
            "views/*.tmpl",
            "views/**/*.tmpl")
    }
}

注: 添加三层目录结构的模板文件时, resources/embed.go 也需要添加一行 //go:embed views/**/**/*, 用来在执行 go build -tags tmpl 时, 打包三层目录进程序内.

关于模板命名

例如在 resources/views/home/hello.tmpl

{{define "home/hello"}}

  {{template "head" .}}
  <div id="home-hello">Hello, Gower</div>
  {{template "foot" .}}

{{end}}

{{define "home/hello"}}{{end}}. 所有模板文件都需要用 define 包裹, 并且 define 的名称必须是唯一的, 不管文件在几层目录下.

因为 html/template 内部处理模板时, 放在一个 map[string]any 中, 这样如果在不同目录下, define 了相同的名称, 后面的模板会覆盖前面模板, 造成实际内容不一致的问题.

define 名称建议使用相对于 views 目录的路径结构, 不需要文件名后缀.

使用 Layout

layout 布局模板就是 app.tmpl, 内部 define 了 headfoot, 使用如上所示, 在自己模板文件名称内使用 {{template "head" .}}{{template "foot" .}} 即可. 内容放在这两个 template 中间

如何使用

因为要响应模板, 那么前端实际请求的 Accept 就是 text/html 了, 不能是 application/json

控制器内返回 services.Response


package controllers

import (
    "gower/app"
    "gower/app/http/requests"
    "gower/app/models"
    "gower/services"
    "github.com/gin-gonic/gin"
)

type AuthController struct {
    app.Controller
}

var Auth = new(AuthController)

// Me 获取个人信息
func (a *AuthController) Me() (services.Response, error) {
    // 响应模板名称, 与模板数据即可
    return res.Ok("auth/me", app.Data{
        "title": "我",
    }), nil
}

“auth/me” 就是模板名称

你可能发现怎么和响应 json 一个格式呀, 因为在处理自由控制器时, 响应根据前端 Accept 进行 Negotiate 判断, 如果是 text/html, 这时候的字符串类型就代表模板名称, 数据就代表模板数据, 如果是 application/json, 这时候的字符串就代表 Msg 或 Token, 数据就代表 Data.

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~