返回

文章详情

如何在 Go 中使用 HTMX

Hacker News2026年7月14日 19:55

当我想给 web 应用程序添加一些交互性时,我非常喜欢使用 HTMX。我喜欢它能够让交互体验更流畅,像应用程序一样,我喜欢它能够减少我所需编写的 JavaScript 代码量,我喜欢它可以让我保持使用 Go 的 html/template 包进行服务器端 HTML 渲染的一致性和安全性。在这篇文章中,我将介绍我通常如何结合使用 HTMX 和 Go。虽然我会稍微谈谈 HTMX 的工作原理,但主要重点将是 Go 方面的内容。具体来说:我如何构建 HTML 模板结构,以及如何向 HTMX 发送部分和完整的 HTML 响应,管理使用 HTMX 时的重定向和错误,我使用的 HTMX 标准配置设置,以及原因。为了说明这些内容,我们将构建一个小型应用程序,最终实现一个对用户列表进行过滤的功能,如下所示:项目设置。如果您想跟随,请运行以下命令以创建项目的骨架结构:$ go mod init example.com/htmx $ mkdir -p assets/static/css assets/static/img assets/static/js assets/html/partials assets/html/pages cmd/web $ touch assets/efs.go assets/html/base.tmpl assets/html/partials/images.tmpl assets/html/pages/home.tmpl cmd/web/main.go cmd/web/handlers.go cmd/web/html.go 这将给你一个如下所示的文件树:. ├── assets │ ├── efs.go │ ├── html │ │ ├── base.tmpl │ │ ├── pages │ │ │ └── home.tmpl │ │ └── partials │ │ └── images.tmpl │ └── static │ ├── css │ ├── img │ └── js ├── cmd │ └── web │ ├── handlers.go │ ├── html.go │ └── main.go └── go.mod 安装 HTMX。有几种不同的方法可以安装 HTMX,您可以从 CDN 加载它或使用 NPM 安装,但我几乎总是下载一个副本并将其作为静态文件从我的 web 应用程序中提供。这很简单,并且避免了使用 CDN 的缺点。为了这个演示项目,我们还将下载 Bamboo(一个无类 CSS 框架)和一个来自 github.com/egonelbre/gophers 的 gopher 图片。请运行以下命令将这三样东西下载到 assets/static 文件夹中:$ wget -P assets/static/js https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js $ wget -P assets/static/css https://cdn.jsdelivr.net/npm/[email protected]/dist/bamboo.min.css $ wget -O assets/static/img/gopher.png https://raw.githubusercontent.com/egonelbre/gophers/refs/heads/master/sketch/misc/standing-left.png 现在,assets/static 的内容应该如下所示:assets/static ├── css │ └── bamboo.min.css ├── img │ └── gopher.png └── js └── htmx.min.js HTML 模板。好吧,现在项目框架和我们的静态资产都已就位,让我们进入这篇文章的主要内容,谈谈 HTML 模板。我几乎所有项目的起点都是 assets/html 目录,其文件夹结构如下:assets/html ├── base.tmpl ├── pages │ └── home.tmpl └── partials └── images.tmpl 在这个结构下:assets/html/base.tmpl 文件包含所有网页的通用 HTML '布局' 标记。assets/html/pages 目录中的文件包含单个网页的特定内容。assets/html/partials 目录中的文件包含可以在不同地方使用的可重用 HTML 标记片段。如果您跟随,请将以下标记添加到 base.tmpl 文件中:文件:assets/html/base.tmpl {{define "base"}} <!doctype html> <html lang='en'> <head> <meta charset='utf-8'> <title>{{template "page:title" .}}</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/css/bamboo.min.css"> <script defer src="/static/js/htmx.min.js"></script> </head> <body> <h1><a href="/">示例网站</a></h1> <main> {{template "page:content" .}} </main> </body> </html> {{end}} 需要指出几点:在 <head> 部分,我们导入了 Bamboo CSS 文件和 HTMX JavaScript 文件。注意在导入 HTMX 时,我们使用了 defer 属性。这意味着 HTMX 将在浏览器解析网页 HTML 时并行获取,但该脚本不会被执行,直到 HTML 完全解析并构建了 DOM。还有一篇很好的博客文章描述了 defer 是如何工作的,以及为什么在这里选择它。编写 HTML 模板时,我喜欢通过使用 {{define}}...{{end}} 动作将我所有的模板显示明确的名称——即使(如在这种情况下)一个文件只包含一个模板并不严格必要。因人而异,但我更喜欢能够始终通过定义名称在我的 Go 代码中引用模板的方式,而不是使用定义名称和文件名的混合。在模板中,我们使用 {{template "page:title" .}} 之类的操作在正确的地方注入适当的页面特定内容。在谈论这个之前,让我们现在添加页面特定内容...

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡