go语言的成神之路-筑基篇-第二章

发布于:2024-11-27 ⋅ 阅读:(123) ⋅ 点赞:(0)

目录

第一节-go模板语法详解

DemoB02.go代码部分

 DemoB02.html代码部分

效果展示

第二节-模板嵌套

main.go

 ul.html

效果展示 

第三节-模板继承

 home2.html

index2.html

目录部分展示

注意事项

第四节-模板补充


 

第一节-go模板语法详解

go模板的基本用法

1.定义模板

2.解析模板

3.渲染模板

每次使用的时候都将这三部分先写上,根据顺序一步一步进行。遇事不决,先写注释

下面是一个基础代码展示

DemoB02.go代码部分

package main

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

// User 结构体用于表示用户信息
type User struct {
	Name   string // 用户名
	Age    int    // 年龄
	Gender string // 性别
}

// sayHello 是处理 HTTP 请求的处理器函数
func sayHello(w http.ResponseWriter, r *http.Request) {
	// 定义模板文件路径
	// 2.解析模板文件
	t, err := template.ParseFiles("D:\\Golang\\gin_demo\\Unit02\\demoB02.html")
	if err != nil {
		// 如果解析模板文件失败,打印错误信息
		fmt.Println("ParseFiles err:", err)
		return
	}

	// 利用结构体定义用户信息
	u1 := User{
		Name:   "VON",
		Age:    18,
		Gender: "男",
	}

	// 利用 map 定义用户信息
	m1 := map[string]interface{}{
		"name":   "清洒",
		"age":    18,
		"gender": "男",
	}

	// 定义学生姓名列表
	nameList := []string{
		"小明",
		"小红",
		"小刚",
	}

	// 3.渲染模板并将数据传递给模板
	t.Execute(w, map[string]interface{}{
		"u1":   u1,      // 传递结构体用户信息
		"m1":   m1,      // 传递 map 用户信息
		"name": nameList, // 传递学生姓名列表
	})
}

func main() {
	// 绑定路由,将根路径 "/" 的请求交给 sayHello 处理
	http.HandleFunc("/", sayHello)

	// 监听并启动 HTTP 服务器,监听 8080 端口
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		// 如果启动服务器失败,打印错误信息并退出程序
		fmt.Println("ListenAndServe: ", err)
		return
	}
}

 DemoB02.html代码部分

<!-- 1. 构建模版 -->
<!-- 这是一个简单的 HTML 模板文件,用于生成动态内容。 -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 使用 Go 模板语法 {{ . }} 来插入传递给模板的数据。 -->

<p>u1</p>
<p>{{ .u1.Name}}</p>
<p>{{ .u1.Age}}</p>
<p>{{ .u1.Gender}}</p>

<p>m1</p>
<p>{{ .m1.name}}</p>
<p>{{ .m1.age}}</p>
<p>{{ .m1.gender}}</p>

<!-- 条件语句-->
<hr>
<!-- 定义变量 $v1 并赋值为 1 -->
{{ $v1 := 1 }}

<!-- 检查 $v1 是否等于 1 -->
{{ if eq $v1 1 }}
    <p>v1 == 1</p>
{{ else }}
    <p>v1 != 1</p>
{{ end }}

<!-- 检查 $v1 是否小于 1 -->
{{ if lt $v1 1 }}
    <p>v1 < 1</p>
{{ else }}
    <p>v1 >= 1</p>
{{ end }}

<!-- 检查 $v1 是否大于 1 -->
{{ if gt $v1 1 }}
    <p>v1 > 1</p>
{{ else }}
    <p>v1 <= 1</p>
{{ end }}
<hr>

<!--range的应用-->
{{ range $id,$name := .name }}
    <p>{{ $id }} - {{ $name }}</p>
{{ end }}

<!--with的应用-->
<hr>
{{ with .u1 }}
    <p>{{ .Name}}</p>
    <p>{{ .Age}}</p>
    <p>{{ .Gender}}</p>
{{ end }}
</body>
</html>

效果展示

第二节-模板嵌套

这一部分不知道为什么我的路径只能选用绝对路径,相对路径会找不到文件位置。

具体每部分都有相应的注释,可以参考注释来进行理解。

main.go

package main

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

// f1 处理函数,用于处理根路径请求
func f1(w http.ResponseWriter, r *http.Request) {
	// 自定义函数,用于在模板中调用
	k := func(name string) (string, error) {
		return name + "真帅", nil
	}

	// 创建一个新的模板对象
	t := template.New("demoB01.html")

	// 应用自定义函数到模板
	t.Funcs(template.FuncMap{
		"kua": k,
	})

	// 解析模板文件
	t, err := t.ParseFiles("D:\\Golang\\gin_demo\\Unit02\\demoB01.html")
	if err != nil {
		// 如果解析模板文件失败,返回内部服务器错误
		http.Error(w, fmt.Sprintf("解析模板文件失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 渲染模板文件
	name := "VON"
	if err := t.Execute(w, name); err != nil {
		// 如果渲染模板文件失败,返回内部服务器错误
		http.Error(w, fmt.Sprintf("渲染模板文件失败: %v", err), http.StatusInternalServerError)
	}
}

// demo01 处理函数,用于处理 /texthtml 路径请求
func demo01(w http.ResponseWriter, r *http.Request) {
	// 解析多个模板文件,父模板写在前面,子模板写在后面
	t, err := template.ParseFiles("D:\\Golang\\gin_demo\\Unit03\\demoB01.html", "D:\\Golang\\gin_demo\\Unit03\\ul.html")
	if err != nil {
		// 如果解析模板文件失败,打印错误信息并返回
		fmt.Println("解析模板失败:", err)
		return
	}

	// 渲染模板文件
	name := "清洒"
	if err := t.Execute(w, name); err != nil {
		// 如果渲染模板文件失败,返回内部服务器错误
		http.Error(w, fmt.Sprintf("渲染模板文件失败: %v", err), http.StatusInternalServerError)
	}
}

// main 函数,程序入口
func main() {
	// 注册处理函数
	http.HandleFunc("/", f1)
	http.HandleFunc("/texthtml", demo01)

	// 启动 HTTP 服务器,监听 1209 端口
	err := http.ListenAndServe(":1209", nil)
	if err != nil {
		// 如果启动服务器失败,打印错误信息并返回
		fmt.Println("启动服务器失败:", err)
		return
	}
}

 ul.html

<ul>
  <li>一</li>
  <li>二</li>
  <li>三</li>
</ul>

效果展示 

第三节-模板继承

在做网页的时候难免会有相同的地方,如果每次使用都重新写一次,会大大影响性能,也会影响运行效率,因此对于公共部分我们可以采用继承的方式来进行优化。以下是一个简单的例子。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板继承</title>
    <!-- 添加全局样式 -->
    <style>
        /* 重置所有元素的内外边距 */
        * {
            margin: 0;
            padding: 0;
        }
        /* 导航栏样式 */
        .nav {
            height: 50px;          /* 高度为 50px */
            width: 100%;           /* 宽度为 100% */
            position: fixed;       /* 固定定位 */
            top: 0;                /* 距离顶部 0px */
            background-color: #d4127c; /* 背景颜色 */
        }
        /* 主体内容区域样式 */
        .main {
            margin-top: 50px;      /* 顶部外边距为 50px,以避免被导航栏遮挡 */
        }
        /* 菜单栏样式 */
        .menu {
            width: 20%;            /* 宽度为 20% */
            height: 100%;          /* 高度为 100% */
            position: fixed;       /* 固定定位 */
            left: 0;               /* 距离左侧 0px */
            background-color: #124fd4; /* 背景颜色 */
        }
        /* 中心内容区域样式 */
        .center {
            text-align: center;    /* 文本居中对齐 */
        }
    </style>
</head>
<body>
    <!-- 导航栏 -->
    <div class="nav"></div>
    <!-- 主体内容区域 -->
    <div class="main">
        <!-- 菜单栏 -->
        <div class="menu"></div>
        <!-- 中心内容区域 -->
        <div class="content center">
            {{block "content" .}}{{end}}  <!-- 这里是子模板插入内容的地方 -->
        </div>
    </div>
</body>
</html>

上述代码是网页中通用的样式

 

 

不难看出这两部分就内容区域不同,因此可以将相同部分进行封装。

将需要填充内容的部分给留出来。

 home2.html

这个地方的“.”千万不能省略,我就是省略了这个地方的“.”导致找了好久的问题

index2.html

目录部分展示

注意事项

这里以home2函数为例,main.go部分代码展示,大致步骤相似,还是三步走,上述标注的地方适当的注意一下。 

第四节-模板补充

为了防止与前端一些用法上面发生冲突,有时候自定义模板就显得格外重要。

下面是一个小例子

前端页面就可以使用到我们自定义的模板了。 

效果图


网站公告

今日签到

点亮在社区的每一天
去签到