golang template HTML动态模板解析实现

使用场景: 我们希望在模板里面动态解析指定的模板文件。

这个似乎使用go语言的模板嵌套 template 可以实现,不过模板嵌套声明里面是不支持使用变量的, 如:{{template "模板文件名" .}}  这里的"模板文件名"不能使用变量,原因我们另外分析, 所以只能是静态嵌套其他模板,不能实现动态嵌套其他模板!

golang动态模板解析实现思路

       要实现模板文件的动态解析, 我们可以通过在自定义模板函数的方式来实现。即 这个函数接收一个 模板文件变量 和模板解析参数 然后将模板文件解析为 HTML后返回给调用模板,这样就实现了模板的动态解析。 【ps: 如果你有更好的思路,欢迎反馈分享 :)】

        

golang HTML动态模板解析实现代码 示例

import ("bytes""html/template""path/filepath""github.com/spf13/viper" // 配置信息解析,可以使用其他你喜欢的
)// 获取所有自定义模板函数
func GetFuncs() template.FuncMap {// fmap map[string]anyreturn template.FuncMap{"TplInclude":  TplInclude,}
}// 动态模板解析函数 将指定的模板文件渲染为html内容后返回
//
//	tplFile 模板文件 这个可以是相对exe所在文件夹的路径 或者绝对路径
//	datas 可选参数  要应用到模板文件中的数据 通常为map格式
//
// 返回可直接渲染页面的 template.HTML 格式的字符串
// @author: TekinTian <tekinTian@gmail.com>
// @see https://dev.tekin.cn
func TplInclude(tplFile string, datas ...interface{}) template.HTML {var data interface{} // 应用到模板中的数据,默认空if len(datas) > 0 {data = datas[0] // 从可选参数中获取}// 从配置文件中获取分隔符delss := viper.GetStringSlice("viewer.delimiters")if len(delss) != 2 {delss = []string{"", ""} // 使用默认的分隔符,这里留空go最后解析的时候就会使用默认的分隔符 {{ }} 详情src/text/template/parse/lex.go}// 获取*template.Template对象 注意如果用到了自定义分隔符,自定义函数,则需要再这里重新注册t := template.New(tplFile).Delims(delss[0], delss[1]).Funcs(GetFuncs())// 解析模板文件 注意这里的模板文件路径必须是相对于exe运行文件所在的路径 或者 绝对路径tpl, err := t.ParseFiles(filepath.Join("templates", tplFile))if err != nil {return template.HTML(err.Error())}// 新建一个字符串缓存 writer, 解析后的模板内容将写入到这里// 这里如果是直接输出到浏览器的话用浏览器的writer即可, gin的输出writer为 c.Writer// 我们这里不直接输出到浏览器,而是输出到模板文件中,所以用这个自定义的writer接收后转为字符串输出到模板中.buf := bytes.NewBufferString("")// 渲染模板if err := tpl.Execute(buf, data); err == nil {return template.HTML(buf.String()) // 将缓存中的所有数据以html格式放回 注意必须是template.HTML格式 否则页面不会被解析} else {return template.HTML(err.Error())}
}

总结

动态模板解析这里的关键点就是如何将指定的模板文件解析为HTML字符串,一般我们常见的就是直接将模板文件解析后输出到浏览器, 而这里是将模板文件解析后返回HTML格式的字符串,这就需要我们使用自定义的writer来接收模板解析后的内容,然后将这些内容返回, 注意这里在返回的时候必须使用 template.HTML 类型, 否则你返回的字符串将是被转码后的html,是不会被浏览器渲染的。

附 template包中定义的返回类型参考

我们上面就用到了下面的这个 HTML类型, 他其实就是一个string类型的类型定义, 当然如果我们希望实现动态渲染css,js 等其他内容,也需要使用下面定义的对应的类型才行哦。

package template// Strings of content from a trusted source.
type (// CSS encapsulates known safe content that matches any of://   1. The CSS3 stylesheet production, such as `p { color: purple }`.//   2. The CSS3 rule production, such as `a[href=~"https:"].foo#bar`.//   3. CSS3 declaration productions, such as `color: red; margin: 2px`.//   4. The CSS3 value production, such as `rgba(0, 0, 255, 127)`.// See https://www.w3.org/TR/css3-syntax/#parsing and// https://web.archive.org/web/20090211114933/http://w3.org/TR/css3-syntax#style//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.CSS string// HTML encapsulates a known safe HTML document fragment.// It should not be used for HTML from a third-party, or HTML with// unclosed tags or comments. The outputs of a sound HTML sanitizer// and a template escaped by this package are fine for use with HTML.//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.HTML string// HTMLAttr encapsulates an HTML attribute from a trusted source,// for example, ` dir="ltr"`.//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.HTMLAttr string// JS encapsulates a known safe EcmaScript5 Expression, for example,// `(x + y * z())`.// Template authors are responsible for ensuring that typed expressions// do not break the intended precedence and that there is no// statement/expression ambiguity as when passing an expression like// "{ foo: bar() }\n['foo']()", which is both a valid Expression and a// valid Program with a very different meaning.//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.//// Using JS to include valid but untrusted JSON is not safe.// A safe alternative is to parse the JSON with json.Unmarshal and then// pass the resultant object into the template, where it will be// converted to sanitized JSON when presented in a JavaScript context.JS string// JSStr encapsulates a sequence of characters meant to be embedded// between quotes in a JavaScript expression.// The string must match a series of StringCharacters://   StringCharacter :: SourceCharacter but not `\` or LineTerminator//                    | EscapeSequence// Note that LineContinuations are not allowed.// JSStr("foo\\nbar") is fine, but JSStr("foo\\\nbar") is not.//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.JSStr string// URL encapsulates a known safe URL or URL substring (see RFC 3986).// A URL like `javascript:checkThatFormNotEditedBeforeLeavingPage()`// from a trusted source should go in the page, but by default dynamic// `javascript:` URLs are filtered out since they are a frequently// exploited injection vector.//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.URL string// Srcset encapsulates a known safe srcset attribute// (see https://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset).//// Use of this type presents a security risk:// the encapsulated content should come from a trusted source,// as it will be included verbatim in the template output.Srcset string
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/37666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2710.移除字符串中的尾随零:模拟

【LetMeFly】2710.移除字符串中的尾随零&#xff1a;模拟 力扣题目链接&#xff1a;https://leetcode.cn/problems/remove-trailing-zeros-from-a-string/ 给你一个用字符串表示的正整数 num &#xff0c;请你以字符串形式返回不含尾随零的整数 num 。 示例 1&#xff1a; 输…

Apache Kylin资源管理全指南:优化你的大数据架构

标题&#xff1a;Apache Kylin资源管理全指南&#xff1a;优化你的大数据架构 摘要 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在为大规模数据集提供高性能的SQL查询能力。在Kylin中进行有效的资源管理对于确保查询性能和系统稳定性至关重要。本文将详细介绍如何…

leetcode 133双周赛 统计逆序对的数目「dp」「前缀和优化」

3193. 统计逆序对的数目 题目描述&#xff1a; 给定一个长度为n的二维数组 r e re re&#xff0c;其中 r e [ i ] [ i d i , c n t i ] re[i] [id_i, cnt_i] re[i][idi​,cnti​]&#xff0c;求存在多少个全排列perm满足对所有的 r e [ i ] re[i] re[i]都有 p e r m [ 0.. …

Bayes分类器设计

本篇文章是博主在人工智能等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在AI学习笔记&#…

东方博宜 OJ 1201-1300

目录 1268&#xff1a;【基础】高精度加法 1269&#xff1a;【基础】高精度减法 1280&#xff1a;【基础】求 2 的 n 次方 1281&#xff1a;【基础】求 222222⋯222⋯2 1285:【基础】计算 N 的阶乘 1286&#xff1a;【基础】高精度乘单精度 1287&#xff1a;【基础】高精…

第一百三十三节 Java数据类型教程 - Java基本数据类型

Java数据类型教程 - Java基本数据类型 Java定义了八种基本类型的数据:byte&#xff0c;short&#xff0c;int&#xff0c;long&#xff0c;char&#xff0c;float&#xff0c;double和boolean。 基本类型通常被称为简单类型。 这些可以分为四组: Integers - 包括byte&#x…

求推荐几款http可视化调试工具?

Postman 非常流行的API调试工具&#xff0c;适用于构建、测试和文档化APIs。它支持各种HTTP方法&#xff0c;有强大的集合和环境管理功能&#xff0c;以及代码生成能力。 BB-API 是一款旨在提升开发效率的工具&#xff0c;它专注于提供简约、完全免费且功能强大的HTTP模拟请…

目标检测算法

一、绪论 1.1 目标检测算法的定义和背景 1.2 目标检测算法在计算机视觉领域的重要性 二、目标检测算法的发展历程 2.1 传统目标检测算法 2.2 基于深度学习的目标检测算法 2.3 目标检测算法的评价指标 三、目标检测算法的关键技术 3.1 区域建议网络(RPN) 3.2 卷积神经…

springmvc快速上手

一、创建工程 1、创建maven工程&#xff0c;添加maven-archetype-webapp模版 2、添加依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.co…

每日一题——Python实现PAT乙级1059 C语言竞赛(举一反三+思想解读+逐步优化)四千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 时间复杂度分析 空间复杂度分析 代码优化建议 总结 我要更强 优化方法…

macos Darwin安装faiss-cpu

文章目录 macos 使用brew instll fass, 后python3.12执行引用faiss包功能出现的问题 安装时遇到问题如下 ModuleNotFoundError Traceback (most recent call last) File ~/Src/ai/framework/langchain/.venv/lib/python3.12/site-packages/langchain_co…

Spring事务的实现

Spring事务的实现分为编程式事务和声明式事务。 编程式事务 编程式事务管理需要开发者在代码中显式地调用事务管理相关的方法,如`beginTransaction()`、`commit()`和`rollback()`等。在Spring中,通常通过以下两种方式来实现编程式事务: 使用`TransactionTemplate`,`Tran…

macOS 安装redis

安装Redis在macOS上通常通过Homebrew进行&#xff0c;Homebrew是macOS上一个流行的包管理器。以下是安装Redis的步骤&#xff1a; 一 使用Homebrew安装Redis 1、安装Homebrew&#xff08;如果尚未安装&#xff09;&#xff1a; 打开终端&#xff08;Terminal&#xff09;并执…

.NET周刊【6月第4期 2024-06-23】

国内文章 C#.Net筑基-集合知识全解 https://www.cnblogs.com/anding/p/18229596 .Net中提供了数组、列表、字典等多种集合类型&#xff0c;分为泛型和非泛型集合。泛型集合具有更好的性能和类型安全性。集合的基础接口包括IEnumerator、IEnumerable、ICollection、IList、ID…

Gradio 4.37.1官方教程二:Blocks

文章目录 一、Blocks及事件监听器1.1 Blocks结构1.2 事件监听器的类型1.3 多数据流1.4 多输入组件1.5 多输出组件1.6 更新组件配置1.7 添加示例1.8 连续运行事件1.9 持续运行事件1.9.1 every参数1.9.2 load方法1.9.3 change方法 1.10 收集事件数据1.11 绑定多个触发器到同一函数…

基于线调频小波变换的一维时间序列时频分析方法(MATLAB)

在机械故障诊断领域,振动信号的处理常采用以快速傅立叶变换为基础的相关分析、幅值分析、频谱分析等时域和频域分析方法。但经典的FFT存在固有缺点,即它虽然在频域范围内是完全局部化的,但是它不包含任何时域信息,因而不适于分析非平稳信号。近年来涌现的各种时频分析方法(短时…

【刷题】初步认识深搜(DFS)

送给大家一句话&#xff1a; 拥有希望的人&#xff0c;和漫天的星星一样&#xff0c;是永远不会孤独的。 -- 《星游记》 初步认识深搜&#xff08;DFS&#xff09; dfs算法二叉树中的深搜Leetcode 129. 求根节点到叶节点数字之和题目描述算法思路 Leetcode 814. 二叉树剪枝题…

Redis-实战篇-缓存更新策略(内存淘汰、超时剔除、主动更新)

文章目录 1、缓存更新策略1.1、内存淘汰1.2、超时剔除1.3、主动更新 2、业务场景&#xff1a;3、主动更新在企业中业务实现有三种方式3.1、Cache Aside Pattern3.1.1、操作缓存和数据库时有三个问题需要考虑&#xff1a;3.1.1.1、删除缓存还是更新缓存&#xff1f;3.1.1.2、如何…

数据同步软件有哪些

数据同步软件有哪些呢&#xff1f;随着企业规模的扩大&#xff0c;企业数据也积累得越来越多&#xff0c;万一发生宕机风险&#xff0c;那么这个损失将不可估量。所以为了容灾备用&#xff0c;我们往往需要将数据同步到另一台备胎服务器上&#xff0c;进行冗余。 那么需要同步的…

centos7.9 python3环境(virtualenv)搭建及所遇错误

人望山&#xff0c;鱼窥荷&#xff0c;真正喜欢想要的&#xff0c;没有一样可以轻易得到。 目录 # 1. 解决版本冲突问题--建议不要跳过(一定要查看软链接是否链接正确) # 2. python3(virtualenv)环境搭建 # 3. virtualenv常用命令 # 4. 所遇错误解析 ## 4.1 遇到 No modul…