mcpField
G
gomponents

gomponents

github.com/maragudk开发4941 次安装31 周前更新
代码仓库

关于 gomponents

gomponents 是用于 Go 应用的纯 Go HTML 组件库,将 HTML 元素表示为可组合、类型安全的 Go 值。它适合构建服务器端视图和可复用组件,并提供渲染及 HTTP 辅助工具。

主要功能

  1. 01以 Node 接口构建组件
  2. 02创建 HTML 元素与属性
  3. 03转义文本并支持原始 HTML
  4. 04条件渲染与列表映射
  5. 05通过 HTTP 辅助工具响应请求

适用场景

  1. 01构建 Go 应用的服务器端 HTML 视图
  2. 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) - 未转义的 HTML
  • Rawf(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