h package helpers
Full reference for github.com/go-via/via/h.
Grouped by responsibility; go doc github.com/go-via/via/h has each
symbol’s contract.
Iteration
h.Each(items, fn)— one node per slice element, nil-pruned.h.EachIndexed(items, fn)— same with(i, v)passed to fn.h.EachSeq(seq, fn)—iter.Seqvariant (slices.Values,maps.Values, …).h.EachSeq2(seq, fn)—iter.Seq2variant (slices.All,maps.All, …).
Conditional
h.If(cond, n),h.IfElse(cond, then, els)— eager.h.When(cond, build),h.WhenElse(cond, then, els)— lazy; only the winning branch is constructed.h.Maybe(v, fn)— renderfn(v)only when v ≠ zero(T) (T must becomparable).h.Switch(value, h.Case(...), h.Default[K](...))— tab-style equality;valueand everyCasekey share one comparable typeK.Defaultneeds the type spelled out (nothing to infer it from).h.IfStr(cond, s)—sif cond,""otherwise; pairs withh.Classandh.Styles.
Composition
h.Fragment(items...)— bundle many nodes into oneh.H. Pass a slice withitems.... Content nodes only: an attribute argument panics at construction (a fragment has no tag to receive it).h.With(base, more...)— return a copy ofbaseextended withmore. Non-destructive; supports chaining without variadic signatures.h.Static(n)— pre-rendernonce into bytes; every later Render writes them verbatim. Use for layout chrome that doesn’t depend on per-request state. See Held fragments below.
Attributes
h.Class(parts...)— variadic class names; empty parts skipped; returns nil (omits the attribute) when nothing remains.h.Classes(parts...)— deprecated alias forh.Class; kept so a slice in hand can spread without a rename.h.ClassMap(m)— emit each true key in sorted order.h.Style(v)— inlinestyle="..."attribute. For<style>...</style>useh.StyleEl.h.Styles(parts...)— join non-empty CSS declarations with;and emit one inlinestyleattribute.h.Checked(),h.Required(),h.Disabled(),h.Selected()— boolean attributes (<input required>).h.Role,h.Min,h.Max,h.Step,h.For,h.Lang,h.Content,h.Charset— common single-string attributes.
Custom tags
h.Tag(name, children...),h.VoidTag(name, children...)— escape hatch for tags absent from the static list (web components, SVG). The name is written verbatim; callers remain responsible for validity.h.NewTag(name),h.NewVoidTag(name)— reusable constructors with the same shape as the built-ins.
Text
h.Text(s),h.T(s)— HTML-escaped text node (Tis the short alias).h.Textf(f, args...)formats first.h.Raw(s)— emitsverbatim without escaping. Caller-trusted.h.RawAttr(name, value)— emit a rawname="value"attribute pair without escaping the value. The sanctioned plugin escape hatch for attribute-shaped output (theattributemarker is unexported on purpose — seeonfor the canonical pattern).
Held fragments
For fragments that don’t change between renders, h.Static pre-renders
once and writes the captured bytes on every later Render — no
per-tick allocation for the chrome subtree:
chrome := h.Static(h.Fragment(
h.Nav(h.Class("container-fluid"),
h.Ul(h.Li(h.Strong(h.T("System Monitor"))))),
))
func (p *Page) View(ctx *via.CtxR) h.H {
return h.Div(chrome, p.body(ctx))
}
internal/examples/sysmon uses this pattern; the
BenchmarkSysmonShape_staticChrome_render bench shows the per-tick
allocation win versus rebuilding the same chrome on each tick.
Custom elements
For tags absent from the static constructor list — web components,
SVG, MathML — declare them once with h.NewTag (or h.NewVoidTag for
void elements):
var SVG = h.NewTag("svg")
SVG(h.Attr("xmlns", "http://www.w3.org/2000/svg"), shapes...)
The tag name is written verbatim; supply a valid HTML element name.