关于 gomponents
gomponents 是用于 Go 应用的纯 Go HTML 组件库,将 HTML 元素表示为可组合、类型安全的 Go 值。它适合构建服务器端视图和可复用组件,并提供渲染及 HTTP 辅助工具。
主要功能
- 01以 Node 接口构建组件
- 02创建 HTML 元素与属性
- 03转义文本并支持原始 HTML
- 04条件渲染与列表映射
- 05通过 HTTP 辅助工具响应请求
适用场景
- 01构建 Go 应用的服务器端 HTML 视图
- 02创建可复用的 Go HTML 组件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ maragudk/ skills --skill gomponents安装后在 Claude Code 中输入/gomponents确认已加载。
详细介绍
gomponents
概述
gomponents 是一个纯 Go HTML 组件库,将 HTML 元素视为可组合的 Go 值。所有内容都基于 Node 接口构建,使 HTML 构造具备类型安全性和可组合性。
何时使用此技能
在以下情况使用此技能:
- 阅读或编写 gomponents 代码
- 在 Go 应用中构建服务器端 HTML 视图
- 在 Go 中创建可复用的 HTML 组件
核心接口
gomponents 中的所有内容都实现了 Node 接口:
type Node interface {
Render(w io.Writer) error
}
基本函数
元素和属性创建
El(name string, children ...Node)- 创建自定义 HTML 元素Attr(name string, value ...string)- 创建自定义属性
html 包中提供了大多数标准 HTML5 元素和属性的函数:
- 元素:
Div()、Span()、P()、A()等 - 属性:
Class()、ID()、Href()、Src()等
注意: 渲染时会忽略 nil 节点,因此可以放心将 nil 节点传递给元素。
文本内容
Text(string)- HTML 转义的文本内容Textf(format string, args...)- 格式化并转义文本Raw(string)- 未转义的 HTMLRawf(format string, args...)- 格式化的未转义内容
组合
Group([]Node)- 组合多个节点Map[T]([]T, func(T) Node)- 将切片转换为节点序列If(condition bool, node Node)- 条件渲染Iff(condition bool, func() Node)- 延迟条件渲染(延迟求值)
导入约定
与 Go 的常见习惯不同,gomponents 推荐使用点导入,以实现类似 DSL 的语法:
import (
. "maragu.dev/gomponents"
. "maragu.dev/gomponents/html"
. "maragu.dev/gomponents/components"
)
这样可以编写简洁、类似 HTML 的代码:
Div(Class("container"),
H1(Text("Hello World")),
P(Text("Welcome to gomponents")),
)
包组织
maragu.dev/gomponents- 核心接口和辅助函数maragu.dev/gomponents/html- 所有 HTML5 元素和属性maragu.dev/gomponents/http- 将组件渲染为响应的 HTTP 辅助函数maragu.dev/gomponents/components- 更高层级的实用工具(HTML5 文档结构、动态类名)
常见模式
基本组件
func UserCard(name, email string) Node {
return Div(Class("user-card"),
H2(Text(name)),
P(Text(email)),
)
}
条件渲染
func Alert(message string, isError bool) Node {
return Div(
If(isError, Class("error")),
If(!isError, Class("info")),
P(Text(message)),
)
}
如果节点总是可以安全求值,请使用 If。如果节点可能为 nil,且只有在条件为 true 时才应对其求值,请使用 Iff。
func UserProfile(user *User) Node {
return Div(
H1(Text(user.Name)),
// Use Iff to avoid nil pointer dereference when user.Avatar is nil
Iff(user.Avatar != nil, func() Node {
return Img(Src(user.Avatar.URL))
}),
)
}
不使用父元素进行分组
使用 Group 将多个节点组合起来,而不将它们包裹在父元素中:
func FormFields(required bool) Node {
return Group{
Label(For("email"), Text("Email")),
Input(Type("email"), ID("email")),
If(required, Span(Class("required"), Text("*"))),
}
}
列表渲染
func TodoList(todos []Todo) Node {
return Ul(Class("todo-list"),
Map(todos, func(t Todo) Node {
return Li(Text(t.Title))
}),
)
}
HTML 文档
func Page(title string, body Node) Node {
return HTML5(HTML5Props{
Title: title,
Language: "en",
Head: []Node{
Link(Rel("stylesheet"), Href("/styles.css")),
},
Body: []Node{body},
})
}
HTTP 处理器
import ghttp "maragu.dev/gomponents/http"
func HomeHandler(w http.ResponseWriter, r *http.Request) (Node, error) {
return Page("My App",
Div(Class("container"),
H1(Text("Hello, World!")),
),
), nil
}
// In main:
http.HandleFunc("/", ghttp.Adapt(HomeHandler))
http 包提供:
Handler类型 - 返回(Node, error)的函数签名Adapt(Handler)- 将 Handler 转换为http.HandlerFunc- 通过
StatusCode() int接口使用自定义状态码处理错误
评论
支持 Markdown