Documentation
¶
Overview ¶
Package htmlbind is the rendering runtime for generated HTML templates.
Generation produces one immutable Plan per component: an ordered instruction list typed by that component's parameter struct. A shared coordinator walks the plan and writes HTML, so composition concerns such as slots, chain nesting, and document head merging live here rather than in generated code.
The package depends on the standard library only, and never on net/http, so generated code stays usable on TinyGo and WebAssembly targets. Response concerns such as content type and content encoding belong to the caller.
Index ¶
- Variables
- func Escape(value string) string
- func MergeHead(wrappers []Wrapper, leaf Fragment) []string
- func Render(w io.Writer, leaf Fragment) error
- func RenderChain(w io.Writer, wrappers []Wrapper, leaf Fragment) error
- type Builder
- func (Builder[P]) Attr(name string, value func(P) (string, bool)) Op[P]
- func (Builder[P]) BoolAttr(name string, value func(P) bool) Op[P]
- func (Builder[P]) Component(bind func(P) Fragment) Op[P]
- func (Builder[P]) If(condition func(P) bool, then, otherwise []Op[P]) Op[P]
- func (Builder[P]) MergedHead() Op[P]
- func (Builder[P]) Raw(value func(P) string) Op[P]
- func (Builder[P]) Slot(value func(P) Fragment, fallback []Op[P]) Op[P]
- func (Builder[P]) Static(text string) Op[P]
- func (Builder[P]) Text(value func(P) string) Op[P]
- type Fragment
- type Op
- type Plan
- type Renderer
- type Wrapper
Constants ¶
This section is empty.
Variables ¶
var ErrNilWrapper = errors.New("htmlbind: chain contains an unset wrapper")
ErrNilWrapper reports a wrapper that was left unset.
var ErrNoLeaf = errors.New("htmlbind: chain needs a leaf component")
ErrNoLeaf reports a chain assembled without an innermost component.
Functions ¶
func Escape ¶ added in v0.1.15
Escape applies HTML text and attribute escaping. It is exported so generated helpers can reuse exactly the runtime's rules.
func MergeHead ¶ added in v0.1.15
MergeHead collects head contributions in composition order, outermost first, dropping later duplicates so two components declaring the same stylesheet emit one tag.
func RenderChain ¶ added in v0.1.15
RenderChain writes a composed document to w. Wrappers apply outermost first, so RenderChain(w, []Wrapper{document, layout}, page) renders page inside layout inside document. An empty wrapper list renders the leaf alone.
Head contributions are merged before the first byte is written, so the shell can emit them without buffering the body. Assembly is validated up front, so a malformed chain cannot leave a partial response behind.
Types ¶
type Builder ¶ added in v0.1.15
type Builder[P any] struct{}
Builder constructs instructions for one component. Generated code declares one per component so the parameter type is written once instead of on every instruction.
func (Builder[P]) Attr ¶ added in v0.1.15
Attr writes one attribute. The value arrives already escaped, because a mixed value concatenates author literals with escaped expressions and only the expressions may be escaped. present reports whether an optional value exists; an absent value omits the whole attribute.
func (Builder[P]) BoolAttr ¶ added in v0.1.15
BoolAttr writes a bare attribute name when the value is true and omits it otherwise.
func (Builder[P]) Component ¶ added in v0.1.15
Component renders another component. bind pairs the callee's plan with arguments derived from the caller's parameters.
func (Builder[P]) MergedHead ¶ added in v0.1.15
MergedHead writes every chain member's head contributions. The document shell places it inside its own head element.
func (Builder[P]) Raw ¶ added in v0.1.15
Raw writes a value that the template already marked trusted for its context.
func (Builder[P]) Slot ¶ added in v0.1.15
Slot inserts a bound slot argument. When the argument is absent the fallback instructions run, which is how default slot content is expressed. An absent slot with no fallback emits nothing at all.
type Fragment ¶ added in v0.1.15
type Fragment struct {
// contains filtered or unexported fields
}
Fragment is a component with its parameters already bound. It is the runtime value behind the html template type, so a slot argument can be passed between components and across template files without either side naming the other's parameter struct.
The zero Fragment is absent, which is how an optional slot with no argument is represented.
type Op ¶ added in v0.1.15
type Op[P any] interface { // Exec writes this instruction's output. Implementations are immutable and // safe to share across goroutines. Exec(r *Renderer, params P) error }
Op is one instruction of a render plan. P is the parameter struct of the component the instruction belongs to, so every step stays statically typed and no reflection is needed.
type Plan ¶ added in v0.1.15
type Plan[P any] struct { // Head holds this component's document head contributions as ready to // write HTML. They merge into the shell head before any body byte. Head []string // Ops is the instruction list executed in order. Ops []Op[P] }
Plan is a component compiled to instructions. A plan is built once at package initialization and shared by every render.
type Renderer ¶ added in v0.1.15
type Renderer struct {
// contains filtered or unexported fields
}
Renderer is the coordinator walking plans. It owns the output stream and the merged head, so instructions never touch either directly.
func (*Renderer) MergedHead ¶ added in v0.1.15
MergedHead returns the head contributions collected for this render.
type Wrapper ¶ added in v0.1.15
type Wrapper struct {
// contains filtered or unexported fields
}
Wrapper is a component that renders another one into its unnamed slot. Generated code returns one from Bind<Name> for a component with a children parameter.
func BindWrapper ¶ added in v0.1.15
BindWrapper pairs a plan with parameters and the setter that installs the child fragment. Generated code supplies the setter because only it knows which field the unnamed slot binds to.