diff options
author | Markus Wüstenberg | 2024-06-26 10:32:46 +0200 |
---|---|---|
committer | GitHub | 2024-06-26 08:32:46 +0000 |
commit | 8b43a908820fb8c6b8a0f6d68d11bb2596a9e033 (patch) | |
tree | dfa2f4903ee64a225d35f5e7c7a3f0ba193a5bb7 | |
parent | a79e6d9d10099c418846280ae4a4997e82f6efee (diff) | |
download | gomponents-8b43a908820fb8c6b8a0f6d68d11bb2596a9e033.tar.lz gomponents-8b43a908820fb8c6b8a0f6d68d11bb2596a9e033.tar.zst gomponents-8b43a908820fb8c6b8a0f6d68d11bb2596a9e033.zip |
Add links to godoc (#183)
Also add an example for `http.Adapt`. Fixes #182
-rw-r--r-- | components/components.go | 5 | ||||
-rw-r--r-- | gomponents.go | 64 | ||||
-rw-r--r-- | html/elements.go | 4 | ||||
-rw-r--r-- | http/handler.go | 12 | ||||
-rw-r--r-- | http/handler_test.go | 8 |
5 files changed, 54 insertions, 39 deletions
diff --git a/components/components.go b/components/components.go index 379d18d..5e13684 100644 --- a/components/components.go +++ b/components/components.go @@ -10,7 +10,7 @@ import ( . "github.com/maragudk/gomponents/html" ) -// HTML5Props for HTML5. +// HTML5Props for [HTML5]. // Title is set no matter what, Description and Language elements only if the strings are non-empty. type HTML5Props struct { Title string @@ -41,6 +41,7 @@ func HTML5(p HTML5Props) g.Node { // for which the corresponding map value is true. type Classes map[string]bool +// Render satisfies [g.Node]. func (c Classes) Render(w io.Writer) error { var included []string for c, include := range c { @@ -56,7 +57,7 @@ func (c Classes) Type() g.NodeType { return g.AttributeType } -// String satisfies fmt.Stringer. +// String satisfies [fmt.Stringer]. func (c Classes) String() string { var b strings.Builder _ = c.Render(&b) diff --git a/gomponents.go b/gomponents.go index d93c8ae..952e32c 100644 --- a/gomponents.go +++ b/gomponents.go @@ -1,15 +1,18 @@ -// Package gomponents provides view components in Go, that render to HTML 5. +// Package gomponents provides HTML components in Go, that render to HTML 5. // -// The primary interface is a Node. It describes a function Render, which should render the Node +// The primary interface is a [Node]. It describes a function Render, which should render the [Node] // to the given writer as a string. // -// All DOM elements and attributes can be created by using the El and Attr functions. -// The functions Text, Textf, Raw, and Rawf can be used to create text nodes, either HTML-escaped or unescaped. -// See also helper functions Group, Map, and If for mapping data to Nodes and inserting them conditionally. +// All DOM elements and attributes can be created by using the [El] and [Attr] functions. +// The functions [Text], [Textf], [Raw], and [Rawf] can be used to create text nodes, either HTML-escaped or unescaped. +// See also helper functions [Group], [Map], [If], and [Iff] for mapping data to nodes and inserting them conditionally. // // For basic HTML elements and attributes, see the package html. +// // For higher-level HTML components, see the package components. +// // For SVG elements and attributes, see the package svg. +// // For HTTP helpers, see the package http. package gomponents @@ -20,14 +23,14 @@ import ( "strings" ) -// Node is a DOM node that can Render itself to a io.Writer. +// Node is a DOM node that can Render itself to a [io.Writer]. type Node interface { Render(w io.Writer) error } -// NodeType describes what type of Node it is, currently either an ElementType or an AttributeType. -// This decides where a Node should be rendered. -// Nodes default to being ElementType. +// NodeType describes what type of [Node] it is, currently either an [ElementType] or an [AttributeType]. +// This decides where a [Node] should be rendered. +// Nodes default to being [ElementType]. type NodeType int const ( @@ -35,16 +38,17 @@ const ( AttributeType ) -// nodeTypeDescriber can be implemented by Nodes to let callers know whether the Node is -// an ElementType or an AttributeType. This is used for rendering. +// nodeTypeDescriber can be implemented by Nodes to let callers know whether the [Node] is +// an [ElementType] or an [AttributeType]. +// See [NodeType]. type nodeTypeDescriber interface { Type() NodeType } -// NodeFunc is a render function that is also a Node of ElementType. +// NodeFunc is a render function that is also a [Node] of [ElementType]. type NodeFunc func(io.Writer) error -// Render satisfies Node. +// Render satisfies [Node]. func (n NodeFunc) Render(w io.Writer) error { return n(w) } @@ -54,19 +58,19 @@ func (n NodeFunc) Type() NodeType { return ElementType } -// String satisfies fmt.Stringer. +// String satisfies [fmt.Stringer]. func (n NodeFunc) String() string { var b strings.Builder _ = n.Render(&b) return b.String() } -// El creates an element DOM Node with a name and child Nodes. +// El creates an element DOM [Node] with a name and child Nodes. // See https://dev.w3.org/html5/spec-LC/syntax.html#elements-0 for how elements are rendered. // No tags are ever omitted from normal tags, even though it's allowed for elements given at // https://dev.w3.org/html5/spec-LC/syntax.html#optional-tags // If an element is a void element, non-attribute children nodes are ignored. -// Use this if no convenience creator exists. +// Use this if no convenience creator exists in the html package. func El(name string, children ...Node) Node { return NodeFunc(func(w2 io.Writer) error { w := &statefulWriter{w: w2} @@ -156,11 +160,11 @@ func isVoidElement(name string) bool { return ok } -// Attr creates an attribute DOM Node with a name and optional value. +// Attr creates an attribute DOM [Node] with a name and optional value. // If only a name is passed, it's a name-only (boolean) attribute (like "required"). // If a name and value are passed, it's a name-value attribute (like `class="header"`). -// More than one value make Attr panic. -// Use this if no convenience creator exists. +// More than one value make [Attr] panic. +// Use this if no convenience creator exists in the html package. func Attr(name string, value ...string) Node { switch len(value) { case 0: @@ -177,7 +181,7 @@ type attr struct { value *string } -// Render satisfies Node. +// Render satisfies [Node]. func (a *attr) Render(w io.Writer) error { if a.value == nil { _, err := w.Write([]byte(" " + a.name)) @@ -187,19 +191,19 @@ func (a *attr) Render(w io.Writer) error { return err } -// Type satisfies nodeTypeDescriber. +// Type satisfies [nodeTypeDescriber]. func (a *attr) Type() NodeType { return AttributeType } -// String satisfies fmt.Stringer. +// String satisfies [fmt.Stringer]. func (a *attr) String() string { var b strings.Builder _ = a.Render(&b) return b.String() } -// Text creates a text DOM Node that Renders the escaped string t. +// Text creates a text DOM [Node] that Renders the escaped string t. func Text(t string) Node { return NodeFunc(func(w io.Writer) error { _, err := w.Write([]byte(template.HTMLEscapeString(t))) @@ -207,7 +211,7 @@ func Text(t string) Node { }) } -// Textf creates a text DOM Node that Renders the interpolated and escaped string format. +// Textf creates a text DOM [Node] that Renders the interpolated and escaped string format. func Textf(format string, a ...interface{}) Node { return NodeFunc(func(w io.Writer) error { _, err := w.Write([]byte(template.HTMLEscapeString(fmt.Sprintf(format, a...)))) @@ -215,7 +219,7 @@ func Textf(format string, a ...interface{}) Node { }) } -// Raw creates a text DOM Node that just Renders the unescaped string t. +// Raw creates a text DOM [Node] that just Renders the unescaped string t. func Raw(t string) Node { return NodeFunc(func(w io.Writer) error { _, err := w.Write([]byte(t)) @@ -223,7 +227,7 @@ func Raw(t string) Node { }) } -// Rawf creates a text DOM Node that just Renders the interpolated and unescaped string format. +// Rawf creates a text DOM [Node] that just Renders the interpolated and unescaped string format. func Rawf(format string, a ...interface{}) Node { return NodeFunc(func(w io.Writer) error { _, err := w.Write([]byte(fmt.Sprintf(format, a...))) @@ -235,12 +239,12 @@ type group struct { children []Node } -// String satisfies fmt.Stringer. +// String satisfies [fmt.Stringer]. func (g group) String() string { panic("cannot render group directly") } -// Render satisfies Node. +// Render satisfies [Node]. func (g group) Render(io.Writer) error { panic("cannot render group directly") } @@ -252,9 +256,9 @@ func Group(children []Node) Node { return group{children: children} } -// If condition is true, return the given Node. Otherwise, return nil. +// If condition is true, return the given [Node]. Otherwise, return nil. // This helper function is good for inlining elements conditionally. -// If it's important that the given Node is only evaluated if condition is true +// If it's important that the given [Node] is only evaluated if condition is true // (for example, when using nilable variables), use [Iff] instead. func If(condition bool, n Node) Node { if condition { diff --git a/html/elements.go b/html/elements.go index 35e5b74..f676462 100644 --- a/html/elements.go +++ b/html/elements.go @@ -1,5 +1,7 @@ // Package html provides common HTML elements and attributes. +// // See https://developer.mozilla.org/en-US/docs/Web/HTML/Element for a list of elements. +// // See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes for a list of attributes. package html @@ -9,7 +11,7 @@ import ( g "github.com/maragudk/gomponents" ) -// Doctype returns a special kind of Node that prefixes its sibling with the string "<!doctype html>". +// Doctype returns a special kind of [g.Node] that prefixes its sibling with the string "<!doctype html>". func Doctype(sibling g.Node) g.Node { return g.NodeFunc(func(w io.Writer) error { if _, err := w.Write([]byte("<!doctype html>")); err != nil { diff --git a/http/handler.go b/http/handler.go index 9f47bff..c53655b 100644 --- a/http/handler.go +++ b/http/handler.go @@ -7,18 +7,18 @@ import ( g "github.com/maragudk/gomponents" ) -// Handler is like http.Handler but returns a Node and an error. -// See Adapt for how errors are translated to HTTP responses. +// Handler is like [http.Handler] but returns a [g.Node] and an error. +// See [Adapt] for how errors are translated to HTTP responses. type Handler = func(http.ResponseWriter, *http.Request) (g.Node, error) type errorWithStatusCode interface { StatusCode() int } -// Adapt a Handler to a http.Handlerfunc. -// The returned Node is rendered to the ResponseWriter, in both normal and error cases. -// If the Handler returns an error, and it implements a "StatusCode() int" method, that HTTP status code is sent -// in the response header. Otherwise, the status code http.StatusInternalServerError (500) is used. +// Adapt a [Handler] to a [http.HandlerFunc]. +// The returned [g.Node] is rendered to the [http.ResponseWriter], in both normal and error cases. +// If the [Handler] returns an error, and it implements a "StatusCode() int" method, that HTTP status code is sent +// in the response header. Otherwise, the status code [http.StatusInternalServerError] (500) is used. func Adapt(h Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { n, err := h(w, r) diff --git a/http/handler_test.go b/http/handler_test.go index 822d69a..706e9eb 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -112,3 +112,11 @@ func get(t *testing.T, h http.Handler) (int, string) { } return result.StatusCode, string(body) } + +func ExampleAdapt() { + h := ghttp.Adapt(func(w http.ResponseWriter, r *http.Request) (g.Node, error) { + return g.El("div"), nil + }) + mux := http.NewServeMux() + mux.Handle("/", h) +} |