【基于GO的Web开发4】html/template 模板语法

一、基础概念

Go 标准库 html/template 是 Go 内置的网页模板引擎,用于后端把数据填充到 HTML 页面,再返回给浏览器。

所有模板语法都包裹在 {``{ }} 两个大括号之中,大括号必须紧贴,不要随意加多余空格。

1.1 核心符号:点 .

  • {``{ . }}.(点)代表当前作用域的对象 / 数据 ,也就是 t.Execute(w, 数据) 第二个参数传入的值。
  • 如果传入的是结构体对象,想要获取结构体字段:{``{ .字段名 }}
    • {``{ .Name }} 获取 Name 字段
    • {``{ .Age }} 获取 Age 字段

⚠️ 重要坑点:Go 结构体只有首字母大写的字段才能被模板访问。小写字段是私有字段,模板无法读取!

go

运行

Go 复制代码
type User struct {
	Name   string  // 大写,模板可读
	gender string  // ×小写私有,模板读取不到!
	Age    int     // 大写,模板可读
}

二、完整基础示例(Web 服务渲染模板)

2.1 项目文件结构

plaintext

复制代码
├─ main.go        // Go后端代码
└─ hello.tmpl     // 网页模板文件(html)

2.2 模板文件 hello.tmpl

html

预览

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
    <p>Hello {{ . }}</p>
</body>
</html>

2.3 Go 后端代码 main.go

go

运行

Go 复制代码
package main

import (
	"fmt"
	"html/template"
	"net/http"
)

// User 定义结构体
type User struct {
	Name   string
	Gender string
	Age    int
}

// sayHello 请求处理函数
// w: 用于给浏览器返回响应;r: 获取浏览器发来的请求信息
func sayHello(w http.ResponseWriter, r *http.Request) {
	// ----------------------1.解析模板----------------------
	t, err := template.ParseFiles("./hello.tmpl")
	if err != nil {
		fmt.Printf("parse template failed,err:%v", err)
		return
	}

	// ----------------------2.准备渲染数据----------------------
	u1 := User{
		Name:   "小王子",
		Gender: "男",
		Age:    18,
	}

	// ----------------------3.渲染模板,把数据填充进模板返回浏览器----------------------
	t.Execute(w, u1)
}

func main() {
	// 注册路由:访问根路径 / 执行sayHello函数
	http.HandleFunc("/", sayHello)
	// 启动web服务器,端口9000
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err:%v", err)
		return
	}
}

启动程序后,浏览器访问 http://127.0.0.1:9000 即可查看渲染结果。

2.4 两种常用传参方式

方式 1:传入结构体

go

运行

Go 复制代码
u1 := User{Name:"小王子",Gender:"男",Age:18}
t.Execute(w,u1)

模板取值:{``{ .Name }}{``{ .Age }}

方式 2:传入 map

go

运行

Go 复制代码
m1 := map[string]interface{}{
	"name":"小王子",
	"gender":"男",
	"age":18,
}
t.Execute(w,m1)

模板取值:{``{ .name }}{``{ .age }}


三、模板基础语法大全

3.1 模板注释

go

运行

Go 复制代码
{{/*遇事不决写注释*/}}
  • 注释内容执行渲染时会被忽略,不会输出到网页
  • 支持多行注释
  • ❗不能嵌套注释,分界符不能加空格

3.2 Pipeline(管道数据流)

pipeline 就是能够产生数据的操作。 模板中所有可以传递、产生数据的表达式,都属于 pipeline,数据顺着管道向后传递。

3.3 模板内部变量定义

go

运行

Go 复制代码
{{$v1 := 100}}
{{$age := 19}}
  • 变量必须带 $ 符号
  • 定义之后可以在模板任意位置使用:{``{ $v1 }}

3.4 移除多余空格 {``{- -}}

- 符号用来消除渲染后生成 HTML 的换行和空格

go

运行

Go 复制代码
{{- .Name -}}
  • {``{- :删除左边空格换行
  • -}}:删除右边空格换行

四、条件判断 if‑else

基础语法

go

运行

Go 复制代码
{{ if $v1 }}
	{{ $v1 }}
{{else}}
	啥都没有
{{end}}

if 判断必须以 {``{end}} 结尾闭合!

内置比较函数

表格

函数 含义
lt less‑than 小于
le 小于等于
eq 等于
ne 不等于
gt 大于
ge 大于等于

示例:

go

运行

Go 复制代码
{{ if lt .age 22 }}
    好好上学
{{else}}
    好好工作
{{end}}

五、循环遍历 range

适合遍历切片、数组、map 数据

后端准备切片数据

go

运行

Go 复制代码
hobbyList := []string{
    "篮球",
    "足球",
    "双色球",
}
data := map[string]interface{}{
    "hobby": hobbyList,
}
t.Execute(w, data)

模板循环写法

go

运行

Go 复制代码
{{ range $idx, $hobby := .hobby}}
	<p>{{$idx}} - {{$hobby}}</p>
{{end}}
  • $idx:索引下标
  • $hobby:遍历取出的元素值

range + else(空数据兜底)

当切片长度为 0 的时候,会执行 else 分支

go

运行

Go 复制代码
{{ range $idx, $hobby := .hobby}}
	<p>{{$idx}} - {{$hobby}}</p>
{{else}}
     <p>没啥爱好</p>
{{end}}

六、with 作用域简写

with 可以切换当前. 的指向,简化很长的变量路径,创造局部作用域。

不使用 with(完整写法)

go

运行

Go 复制代码
<p>{{ .m1.name }}</p>
<p>{{ .m1.age }}</p>

使用 with 简写

go

运行

html 复制代码
{{with .m1}}
	<p>{{ .name }}</p>
	<p>{{ .age }}</p>
{{end}}

在 with 块内部,. 就代表 .m1,不用每次都写完整路径


七、index 索引取值

用于根据下标获取切片、数组指定位置的元素

go

运行

Go 复制代码
{{index .hobby 2 }}

代表取切片 .hobby 中下标为 2 的元素


八、速查思维导图

  1. 包裹标记:{``{ 内容 }}
  2. . = 当前对象
  3. 取字段:{``{ .Name }}
  4. 注释:{``{/* 注释 */}}
  5. 变量:{``{ $x := 值 }}
  6. 去空格:{``{- .xxx -}}
  7. 判断:{``{if}} ... {``{else}} ... {``{end}}
  8. 循环:{``{range}} ... {``{else}} ... {``{end}}
  9. 简写域:{``{with 目标}} ... {``{end}} 10. 索引取值:{``{index 数组 下标}}
相关推荐
一只叫煤球的猫1 小时前
Spring AI 2.0 源码解析(三):ChatClient 的 Fluent API 如何构建请求?
java·后端·面试
掘金者阿豪2 小时前
数据库迁移工具选了半年,最后发现决策的起点错了
后端
卷无止境2 小时前
FastAPI查询参数模型:把散落的参数收拢成一个整齐的盒子
后端·python
gis开发之家3 小时前
Spring Boot 4 深度解析——参数接收大全:@RequestParam、@PathVariable、@RequestBody
java·spring boot·后端·spring
NutShell Wang3 小时前
Rust 1.97 实战迁移:v0 符号重整、Cargo 警告治理与位运算新 API
人工智能·后端·性能优化·rust·vibe coding
阑梦清川3 小时前
零成本把笔记转成双人播客:WorkBuddy + 腾讯云 TTS 完整教程
后端
赫媒派3 小时前
Go 1.27 来了:泛型方法补齐,JSON 提速不踩坑
后端·go·敏捷开发
不ok哥男人3 小时前
C# Roslyn 编译器平台实战:源生成器、分析器与代码修补
后端
长栎3 小时前
99% 的人把桥接模式当策略模式用——抽象与实现分离,你做的不是同一件事
后端