gomponents

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

gomponents

gomponents

Overview

概述

gomponents is a pure Go HTML component library that treats HTML elements as composable Go values. Everything is built on the
Node
interface, making HTML construction type-safe and composable.
gomponents是一个纯Go语言的HTML组件库,它将HTML元素视为可组合的Go值。所有内容都基于
Node
接口构建,让HTML构建具备类型安全性和可组合性。

When to Use This Skill

何时使用这份技能文档

Use this skill when:
  • Reading or writing gomponents code
  • Building server-side HTML views in Go applications
  • Creating reusable HTML components in Go
在以下场景中使用本指南:
  • 阅读或编写gomponents代码时
  • 在Go应用中构建服务端HTML视图时
  • 在Go中创建可复用HTML组件时

Core Interface

核心接口

Everything in gomponents implements the
Node
interface:
go
type Node interface {
    Render(w io.Writer) error
}
gomponents中的所有内容都实现了
Node
接口:
go
type Node interface {
    Render(w io.Writer) error
}

Essential Functions

核心函数

Element and Attribute Creation

元素与属性创建

  • El(name string, children ...Node)
    - Create custom HTML elements
  • Attr(name string, value ...string)
    - Create custom attributes
Most standard HTML5 elements and attributes are available as functions in the
html
package:
  • Elements:
    Div()
    ,
    Span()
    ,
    P()
    ,
    A()
    , etc.
  • Attributes:
    Class()
    ,
    ID()
    ,
    Href()
    ,
    Src()
    , etc.
Note:
nil
Nodes are ignored during rendering, so it's safe to pass nil nodes to elements.
  • El(name string, children ...Node)
    - 创建自定义HTML元素
  • Attr(name string, value ...string)
    - 创建自定义属性
大多数标准HTML5元素和属性都作为
html
包中的函数提供:
  • 元素:
    Div()
    Span()
    P()
    A()
  • 属性:
    Class()
    ID()
    Href()
    Src()
注意: 渲染时会忽略
nil
类型的Node,因此向元素传递nil节点是安全的。

Text Content

文本内容

  • Text(string)
    - HTML-escaped text content
  • Textf(format string, args...)
    - Formatted, escaped text
  • Raw(string)
    - Unescaped HTML
  • Rawf(format string, args...)
    - Formatted, unescaped content
  • Text(string)
    - 经过HTML转义的文本内容
  • Textf(format string, args...)
    - 格式化后的转义文本
  • Raw(string)
    - 未转义的HTML内容
  • Rawf(format string, args...)
    - 格式化后的未转义内容

Composition

组合功能

  • Group([]Node)
    - Combine multiple nodes
  • Map[T]([]T, func(T) Node)
    - Transform slices into node sequences
  • If(condition bool, node Node)
    - Conditional rendering
  • Iff(condition bool, func() Node)
    - Lazy conditional rendering (deferred evaluation)
  • Group([]Node)
    - 组合多个节点
  • Map[T]([]T, func(T) Node)
    - 将切片转换为节点序列
  • If(condition bool, node Node)
    - 条件渲染
  • Iff(condition bool, func() Node)
    - 延迟条件渲染(仅在条件为真时执行求值)

Import Convention

导入约定

Contrary to common Go idioms, dot imports are recommended for gomponents to achieve DSL-like syntax:
go
import (
    . "maragu.dev/gomponents"
    . "maragu.dev/gomponents/html"
    . "maragu.dev/gomponents/components"
)
This allows writing clean, HTML-like code:
go
Div(Class("container"),
    H1(Text("Hello World")),
    P(Text("Welcome to gomponents")),
)
与常见的Go语言惯例不同,推荐使用点导入gomponents以实现类DSL的语法:
go
import (
    . "maragu.dev/gomponents"
    . "maragu.dev/gomponents/html"
    . "maragu.dev/gomponents/components"
)
这样可以编写简洁、类HTML的代码:
go
Div(Class("container"),
    H1(Text("Hello World")),
    P(Text("Welcome to gomponents")),
)

Package Organization

包结构

  • maragu.dev/gomponents
    - Core interface and helper functions
  • maragu.dev/gomponents/html
    - All HTML5 elements and attributes
  • maragu.dev/gomponents/http
    - HTTP helpers for rendering components as responses
  • maragu.dev/gomponents/components
    - Higher-level utilities (HTML5 document structure, dynamic classes)
  • maragu.dev/gomponents
    - 核心接口与辅助函数
  • maragu.dev/gomponents/html
    - 所有HTML5元素和属性
  • maragu.dev/gomponents/http
    - 用于将组件渲染为响应的HTTP辅助工具
  • maragu.dev/gomponents/components
    - 高级工具(HTML5文档结构、动态类等)

Common Patterns

常见模式

Basic Component

基础组件

go
func UserCard(name, email string) Node {
    return Div(Class("user-card"),
        H2(Text(name)),
        P(Text(email)),
    )
}
go
func UserCard(name, email string) Node {
    return Div(Class("user-card"),
        H2(Text(name)),
        P(Text(email)),
    )
}

Conditional Rendering

条件渲染

go
func Alert(message string, isError bool) Node {
    return Div(
        If(isError, Class("error")),
        If(!isError, Class("info")),
        P(Text(message)),
    )
}
Use
If
when the node is always safe to evaluate. Use
Iff
when the node might be nil and shouldn't be evaluated unless the condition is true.
go
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))
        }),
    )
}
go
func Alert(message string, isError bool) Node {
    return Div(
        If(isError, Class("error")),
        If(!isError, Class("info")),
        P(Text(message)),
    )
}
当节点始终可以安全求值时使用
If
。当节点可能为nil且仅在条件为真时才应求值时,使用
Iff
go
func UserProfile(user *User) Node {
    return Div(
        H1(Text(user.Name)),
        // 当user.Avatar为nil时,使用Iff避免空指针引用
        Iff(user.Avatar != nil, func() Node {
            return Img(Src(user.Avatar.URL))
        }),
    )
}

Grouping Without a Parent Element

无父元素分组

Use
Group
to group multiple nodes without wrapping them in a parent element:
go
func FormFields(required bool) Node {
    return Group{
        Label(For("email"), Text("Email")),
        Input(Type("email"), ID("email")),
        If(required, Span(Class("required"), Text("*"))),
    }
}
使用
Group
可以在不包裹父元素的情况下对多个节点进行分组:
go
func FormFields(required bool) Node {
    return Group{
        Label(For("email"), Text("Email")),
        Input(Type("email"), ID("email")),
        If(required, Span(Class("required"), Text("*"))),
    }
}

List Rendering

列表渲染

go
func TodoList(todos []Todo) Node {
    return Ul(Class("todo-list"),
        Map(todos, func(t Todo) Node {
            return Li(Text(t.Title))
        }),
    )
}
go
func TodoList(todos []Todo) Node {
    return Ul(Class("todo-list"),
        Map(todos, func(t Todo) Node {
            return Li(Text(t.Title))
        }),
    )
}

HTML Document

HTML文档

go
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},
    })
}
go
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 Handler

HTTP处理器

go
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))
The
http
package provides:
  • Handler
    type - function signature that returns
    (Node, error)
  • Adapt(Handler)
    - converts Handler to
    http.HandlerFunc
  • Error handling with custom status codes via
    StatusCode() int
    interface
go
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
}

// 在main函数中:
http.HandleFunc("/", ghttp.Adapt(HomeHandler))
http
包提供了以下功能:
  • Handler
    类型 - 返回
    (Node, error)
    的函数签名
  • Adapt(Handler)
    - 将Handler转换为
    http.HandlerFunc
  • 通过
    StatusCode() int
    接口实现带自定义状态码的错误处理