go模版引擎的使用~~
go模板语句
以下是一些go语言模板引擎的一些简单知识和使用
基础语法
重要!!!:
模板在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页, golang也支持模板渲染。
【1】模板内内嵌的语法支持,全部需要加 {{}} 来标记。
【2】在模板文件内, . 代表了当前位置的上下文:
-
(1)在非循环体内,. 就代表了后端传过来的上下文
-
(2)在循环体中,. 就代表了循环的上下文,访问当前迭代的元素,意思是切片的话,循环里就是指数组的单个元素
【3】在模板文件内,
$.代表了模板根级的上下文【4】在模板文件内,$有两种用法:第一种,代表了当前迭代的索引值
例子:
{{ range $index, $element := .Items }}Index: {{ $index }}, Element: {{ $element }} {{ end }}第二种:在模板中定义和赋值变量:这个之后会讲到
{{ $variable := .SomeValue }} 后续的模板代码中使用 $variable来表示.SomeValue
简单示例
前端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Gin模板引擎示例</title>
</head>
<body><h1>Hello, {{.Name}}!</h1>
</body>
</html>
后端
{{.Name}}实际就是获取了map中name字段的值package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()// 加载模板文件r.LoadHTMLGlob("templates/*")// 定义路由r.GET("/hello", func(c *gin.Context) {// 渲染模板,并传递数据c.HTML(200, "index.html", gin.H{"Name": "Gin User",//注意!:gin.H{"title": "Hello Gin"}实际是map[string]interface{},通过用{{.Name}}实际就是获取了map中name字段的值,.就是上下文中gin.H传过来的数据;})})// 启动应用r.Run(":8080")
}
对符号的支持
-
1. 字符串:{{ “abc啦啦啦”}} 输出 abc啦啦啦 2. 原始字符串:用转义字符{ {`啦啦啦` } } { { `a` } } 不会转义 输出 啦啦啦a 3. 字节类型:{ { 'a' } } ---> 97 会转义 输出 97 4. 打印:打印 :字符串: { { print "abc李总辉" } } 输出:abc李总辉nil类型:{ { print nil } } 输出:<nil>
变量的定义和使用
演示:
讲到了$的第二个作用,变量的定义
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>变量的定义:{{$name := "马士兵888"}}变量的使用:{{$name}}
</body>
</html>
//最后会输出: 李总辉888
模板语法:
if语句:
支持最简单的bool类型和字符串类型的判断:
当.condition为bool类型的时候,则为true表示执行,当.condition为string类型的时候,则非空表示执行。
{{if .Condition}}{{/* 如果条件为真,执行此处的内容 */}}
{{else}}{{/* 如果条件为假,执行此处的内容 */}}
{{end}}
循环语句:
刚刚最开始也演示过
{{range .Items}}{{.}} {{/* 输出当前迭代的元素 */}}
{{end}}
内置的模板函数:
(用到的时候再去看吧)
not 非
and 与
or 或
eq 等于
ne 不等于
lt 小于 (less than)
le 小于等于
gt 大于
ge 大于等于
with的使用
其实就是提供的一个简便的写法:,用于创建一个新的局部作用域
使用起来很简单
{{with .Value}}{{/* 在这个作用域内,可以直接访问 .Value ,就是说把.Value变成了.来操作*/}}
{{end}}
比如:
原写法:
Name: {{.Person.Name}}
Age: {{.Person.Age}}使用with
{{with .Person}}Name: {{.Name}}Age: {{.Age}}
{{end}}
模板函数
【1】print 打印字符串
【2】printf 按照格式化的字符串输出
格式:参照:Go中:fmt.Sprintf
PS : 具体的格式参照GO中格式:https://studygolang.com/pkgdoc
【3】len 返回对应类型的长度(map, slice, array, string, chan)
【4】管道传递符: |
函数中使用管道传递过来的数值
【5】括号提高优先级别:()`
进阶示例:
后端
func Hello1(context *gin.Context){//定义数据:age := 19arr := []int{33,66,99}//将age 和arr放入map中:map_data := map[string]interface{}{"age" : age,"arr" : arr,}//获取路径中的参数值:context.HTML(200,"demo01/hello.html",map_data)将定义的数据(age和arr)传递给HTML模板,然后使用Gin框架将渲染后的HTML作为HTTP响应发送给客户端。在hello.html模板中使用age和arr的值来动态生成页面内容。
前端
<body>{{.age}
{{range .arr}}{{.}}{{$.age}}
{{end}}
<br>
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
{{/*$i,$v 从 后端传过来的map_data这个上下文中获取数据 */}}
{{range $i,$v := .arr}}{{$i}}{{$v}}
{{end}}</body>
后端
<body>{{/*获取后端传过来的map_data中的内容:*/}}{{/* . 当前的上下文,后端传过来的map_data这个上下文*/}}{{.age}}{{/*. 当前的上下文,后端传过来的map_data这个上下文*/}}{{range .arr}}{{/*. 上下文指的就是.arr这个上下文,指的就是遍历的每一个元素*/}}{{.}}{{/*在循环内部想获取根级上下文中的age的话,就需要使用$.来获取 (map_data这个上下文)*/}}{{$.age}}{{end}}<br>、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、{{/*$i,$v 从 后端传过来的map_data这个上下文中获取数据 */}}{{range $i,$v := .arr}}{{$i}}{{$v}}{{end}}
</body>
模版嵌套
为什么会有嵌套呢?他的作用其实还是很大的,主要用于在基础模版上充当更改部分模板的功能;
示例:
后端
// main.go
package mainimport ("html/template""net/http""github.com/gin-gonic/gin"
)var templates *template.Templatefunc init() {// 解析所有模板文件templates = template.Must(template.ParseGlob("templates/*.html"))
}func main() {router := gin.Default()// 基础路由router.GET("/", func(c *gin.Context) {// 渲染 index.html,不需要嵌套其他模板renderTemplate(c, "index.html", gin.H{"Title": "Home", "Content": "Welcome to the home page"})})// 带有模板嵌套的路由router.GET("/about", func(c *gin.Context) {// 渲染 base.html,并在 content 块中嵌套 about.htmlrenderTemplate(c, "base.html", gin.H{"Title": "About", "Content": "about.html"})})router.Run(":8080")
}func renderTemplate(c *gin.Context, tmpl string, data gin.H) {// 执行模板渲染err := templates.ExecuteTemplate(c.Writer, tmpl, data)if err != nil {// 处理错误c.AbortWithError(http.StatusInternalServerError, err)}
}// 路由渲染的是 "index.html" 模板,而 /about 路由渲染的是 "base.html" 模板,并在 content 块中嵌套了 "about.html" 模板。
前端:三个文件
------------templates/base.html-----------
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{{.Title}}</title>
</head>
<body><div id="content">{{ template "content" . }}</div>
</body>
</html>
-------------- templates/index.html--------------
{{ define "content" }}<h1>{{.Title}}</h1><p>{{.Content}}</p>
{{ end }}
---------templates/about.html------------
{{ define "content" }}<h1>{{.Title}}</h1><p>This is the content of the about page.</p>
{{ end }}
模板文件之间通过 {{ template "content" . }} 来实现了模板嵌套。
基础模板 “base.html” 定义了一个 content 块,子模板通过定义同名的块来覆盖或扩展基础模板中的内容。
啥意思呢?其实就是**base.html 充当了一个基础布局模板,而 index.html 和 about.html 分别充当了具体页面的内容模板。通过模板嵌套,可以轻松地在不同页面之间共享基础布局,提高模板的复用性。**
模版继承
模板继承是一种模板组织方式,通过它,你可以创建一个包含通用结构和样式的基础模板,并在此基础上创建具体内容的子模板。子模板可以覆盖或扩展基础模板中的块,从而实现灵活的页面结构和外观定制。
在模板继承中,通常有两个主要角色:
- 基础模板(父模板): 包含页面的整体结构、布局和通用元素。基础模板中定义了一些块(block),这些块表示可以被子模板覆盖或扩展的区域。
- 子模板: 继承基础模板,并提供具体的内容。子模板通过定义和填充基础模板中的块来定制页面的特定部分。
案例:
----------base.html----------
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{% block title %}Default Title{% endblock %}</title>
</head>
<body><div id="content">{% block content %}{% endblock %}</div>
</body>
</html>
-------------child.html-------------
{% extends "base.html" %}{% block title %}Child Title{% endblock %}{% block content %}<h1>Welcome to the child page</h1><p>This is the content of the child page.</p>
{% endblock %}
子模板 `child.html` 使用了 `{% extends "base.html" %}` 来声明继承自 `base.html`,然后通过 `{% block title %}...{% endblock %}` 和 `{% block content %}...{% endblock %}` 来定义或覆盖基础模板中的块。
后端:
package mainimport ("html/template""net/http""github.com/gin-gonic/gin"
)var templates *template.Templatefunc init() {// 解析所有模板文件templates = template.Must(template.ParseGlob("templates/*.html"))
}func main() {// 创建Gin引擎router := gin.Default()// 子模板路由router.GET("/child", func(c *gin.Context) {// 渲染 child.htmlrenderTemplate(c, "child.html", nil)})// 启动服务器router.Run(":8080")
}func renderTemplate(c *gin.Context, tmpl string, data interface{}) {// 执行模板渲染err := templates.ExecuteTemplate(c.Writer, tmpl, data)if err != nil {// 处理错误c.AbortWithError(http.StatusInternalServerError, err)}
}
原文链自:https://lz.chatallshop.top/?p=156
相关文章:
go模版引擎的使用~~
go模板语句 以下是一些go语言模板引擎的一些简单知识和使用 基础语法 重要!!!: 模板在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页࿰…...
我们为什么要进行敏捷开发培训
敏捷开发是一种以人为核心、迭代、循序渐进的软件开发方法。它强调团队合作、客户需求和适应变化。进行敏捷开发培训其实有多种原因,我整理了一些,可以作为参考: 理解敏捷原则和实践: 敏捷开发不仅是一种方法论,更是一…...
【算法萌新闯力扣】:合并两个有序链表
力扣题目:合并两个有序链表 开篇 今天是备战蓝桥杯的第24天及算法村开营第2天。根据算法村的讲义,来刷链表的相关题目。今天要分享的是合并两个有序链表。 题目链接: 21.合并两个有序链表 题目描述 代码思路 通过创建一个新链表,然后遍历…...
BEV+Transformer架构加速“上车”,智能驾驶市场变革开启
BEVTransformer成为了高阶智能驾驶领域最为火热的技术趋势。 近日,在2023年广州车展期间,不少车企及智能驾驶厂商都发布了BEVTransformer方案。其中,极越01已经实现了“BEVTransformer”的“纯视觉”方案的量产,成为国内唯一量产…...
Java中的jvm——面试题+答案(JVM的一些高级概念、调优技巧、垃圾回收算法等)——第13期
当涉及到Java虚拟机(JVM)时,面试官可能涉及更深入的问题,涵盖性能调优、垃圾回收算法、类加载机制等方面。 什么是类加载机制?请解释类加载的过程。 答案: 类加载是将类的.class文件加载到内存中的过程&…...
Android修行手册-ViewPager定制页面切换以及实现原理剖析
Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…...
Mycat实现读写分离
Mycat实现读写分离 Mycat支持MySQL主从复制状态绑定的读写分离机制。这里实现的也是基于MySQL主从复制的读写分离。 MySQL主从复制配置 首先要配置MySQL的主从复制,这里配置的是一主一次从。可以参考下面的文章。 https://blog.csdn.net/wsb_2526/article/detail…...
Ceph----CephFS文件系统的使用:详细实践过程实战版
CephFS 介绍 是一个基于 ceph 集群 且兼容 POSIX 标准的文件系统。 创建 cephfs 文件系统时 需要在 ceph 集群中添加 mds 服务,该服务 负责处理 POSIX 文件系统中的 metadata 部分, 实际的数据部分交由 ceph 集群中的 OSD 处理。 cephfs 支持以内核模块…...
python tkinter 使用(七)
python tkinter 使用(七) 本篇文章主要讲下tkinter 中的message 控件. Message控件可以用于在窗口中显示一段文本消息. 以下是个简单的例子: #!/usr/bin/python3 # -*- coding: UTF-8 -*- """Author: zhTime 2023/11/24 上午11:38 .Email:Describe: "…...
17. Python 数据库操作之MySQL和SQLite实例
目录 1. 简介2. 使用PyMySQL2. 使用SQLite 1. 简介 数据库种类繁多,每种数据库的对外接口实现各不相同,为了方便对数据库进行统一的操作,大部分编程语言都提供了标准化的数据库接口,用户不需要了解每种数据的接口实现细节&#x…...
Kafka-TopicPartition
Kafka主题与分区 主题与分区 topic & partition,是Kafka两个核心的概念,也是Kafka的基本组织单元。 主题作为消息的归类,可以再细分为一个或多个分区,分区也可以看作对消息的二次归类。 分区的划分为kafka提供了可伸缩性、水…...
英特尔工作站:助力专业用户实现高效创作
原创 | 文 BFT机器人 英特尔工作站是由全球知名的英特尔公司设计和开发的一款计算平台。英特尔在工作站处理器领域将其产品分为性能型和移动型两类,它的诞生旨在满足专业用户在科学、工程、设计等领域对高性能计算的需求。英特尔工作站配备了最新的英特尔处理器、大…...
软件工程期末复习(选择+填空+判断)
文章目录 软件工程期末复习一、 选择题 软件工程期末复习 一、 选择题 1.“软件危机”的表现不包括:(c) A、软件产品不能按期交付 B、用户对“已完成的”软件产品时常不满意 C、程序员越来越供不应求 D、软件项目难以管理,维护困…...
群晖NAS基础设置
群晖NAS基础设置 最近一直在玩群晖NAS系统,有一些基础的配置跟大家分享一下 开启ssh登录 1.开启方法 控制面板—>终端和SNMP—>终端机 2.使用ssh软件登录 这里我用SecureCRT登录 进入ssh 3.进入root用户 starstar-nas:~$ sudo su -l root Password: ro…...
2023亚太杯数学建模A题B题C题选题建议,思路分析,模型代码
目录 ABC题思路模型代码:获取见文末名片,第一时间更新 视频连接讲解如上 A题思路:采果机器人的图像识别技术思路模型代码 B题思路:玻璃温室中的微气候法规 C题思路:我国新能源电动汽车的发展趋势 ABC题思路模型代…...
OpenGL的学习之路 -5
1.视景体 正交投影 人眼看世界,有一个可见范围。范围内可见,范围外不可见。视景体就是这么一个概念。 (上图仅学习记录用) 在OGL中,有两种投影方式,对应两种视景体。第一种,正交投影…...
【linux】服务器CPU占用50%,top/htop/ps却看不到异常进程?使用unhide可以查看!
问题描述 htop发现前32个核全被占满了,但是却找不到对应进程号 查杀 治标:杀死隐藏进程 1、unhide 安装unhide apt-get install unhideunhide使用 unhide proc果然发现了隐藏进程 kill -9 kill -9 [pid]这么多pid号,我这边杀了其中…...
JSP EL表达式获取list/Map集合与java Bean对象
上文 JSP EL表达式基本使用 中 我们对EL表达式做了一个基本的了解 也做了基础的字符串数据使用 那么 我们可以来看一下我们的集合 首先 list 这个比较简单 我们直接这样写代码 <% page import"java.util.ArrayList" %> <% page import"java.util.Lis…...
汇编程序:查找数组中最大最小值
实验内容 1. 从数据段DS中包含9个字节的数组数据VALUE中分别找出最大值(存到max中)、最小值(存到min中)。 2. 能够单步执行程序,认真观察、判断每条指令执行的结果是否正确,对错误结果,能够做出…...
ElasticSearch之禁用交换分区
操作系统将进程加载至内存中执行时,对于当前未使用到的内存页,可能会将相关内存页交换至硬盘上,即swap。 对于性能敏感、时延敏感的应用程序比如ElasticSearch,swap特性会明显影响性能和稳定性,因此最好禁用swap特性。…...
Kotaemon功能测评:这个开源RAG UI到底有多好用?
Kotaemon功能测评:这个开源RAG UI到底有多好用? 想象一下,你手头有一堆产品文档、技术手册或者内部资料,每次想从中快速找到某个问题的答案,都得像大海捞针一样翻来翻去。或者,你费劲搭建了一个RAG&#x…...
GraphRAG 安装与使用教程
一、GraphRAG 简介 GraphRAG(Graph Retrieval-Augmented Generation)是由微软研究院开发的基于知识图谱的检索增强生成框架。它通过构建结构化的知识图谱来增强大语言模型(LLM)的推理能力,相比传统 RAG 方法在处理复杂…...
本地化部署MT5:无需联网,保障敏感数据隐私的文本处理方案
本地化部署MT5:无需联网,保障敏感数据隐私的文本处理方案 1. 为什么选择本地化部署的文本处理方案 1.1 数据隐私保护的刚性需求 在当今数据驱动的商业环境中,企业面临着越来越严格的数据合规要求。许多行业如金融、医疗、法律等࿰…...
Java 微服务弹性模式:构建高可用分布式系统
Java 微服务弹性模式:构建高可用分布式系统今天我们来聊聊 Java 微服务中的弹性模式,这是构建高可用分布式系统的核心能力。一、为什么需要弹性模式 在分布式系统中,故障是不可避免的。网络延迟、服务宕机、资源耗尽等问题随时可能发生。如果…...
OpenClaw+Phi-3-mini-128k-instruct内容处理:从爬虫到发布的自动化流水线
OpenClawPhi-3-mini-128k-instruct内容处理:从爬虫到发布的自动化流水线 1. 为什么需要内容处理自动化 作为一个技术博主,我每天需要处理大量信息:从技术社区抓取最新动态、整理成可读性强的文章、再发布到多个平台。这个过程耗时费力&…...
FireRed-OCR Studio部署指南:HuggingFace Spaces免费部署与限流配置
FireRed-OCR Studio部署指南:HuggingFace Spaces免费部署与限流配置 1. 引言 你是不是经常遇到这样的麻烦事?拿到一份纸质表格或者PDF扫描件,想把里面的内容整理成电子文档,结果发现表格结构复杂,手动录入费时费力&a…...
【OpenCV教程】Trackbar到底怎么用?
1.createTrackbar创建滚动条1.1 APICV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,int* value, int count,TrackbarCallback onChange 0,void* userdata 0);参数如下参数含义trackbarname滚动条名字winname(window name)窗体名字…...
Bypass Paywalls Chrome Clean:突破付费内容壁垒的高效浏览器扩展
Bypass Paywalls Chrome Clean:突破付费内容壁垒的高效浏览器扩展 在信息爆炸的数字时代,优质内容常被付费墙阻隔,学术文献、深度报道和专业期刊的访问限制成为知识获取的主要障碍。Bypass Paywalls Chrome Clean作为一款开源浏览器扩展&…...
WiFiEspAT:基于AT指令的嵌入式Wi-Fi协处理器适配库
1. 项目概述WiFiEspAT 是一个面向嵌入式系统的轻量级、高可靠性网络适配层库,其核心目标是将 ESP8266 或 ESP32 模块作为独立的 Wi-Fi 网络协处理器(Network Coprocessor),通过标准 AT 指令集与主控 MCU(如 AVR、ARM C…...
AI+电磁:当计算电磁学遇上人工智能,一场效率革命正在发生
AI电磁:当计算电磁学遇上人工智能,一场效率革命正在发生 引言 在6G通信、新能源汽车与高端芯片设计等领域,电磁仿真已成为不可或缺的“数字试验场”。然而,传统基于有限元(FEM)、时域有限差分(…...
