html5

package module
v0.0.0-...-f46bc1f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 6, 2023 License: Apache-2.0 Imports: 10 Imported by: 4

README

Go package for generating HTML5

IMPORTANT: THIS IS STILL EXPERIMENTAL AND SUBJECT TO CHANGE

This package provides a template-free, declarative mechanism for generating HTML5. It has some advantages over html/template:

  • It is about 5-10 times faster
  • With careful use, allows streaming HTML without holding the entire page in memory
  • Can generate tidy output and minified output directly, without needing additional passes
  • Makes it easy to build reusable, composable pieces
  • HTML is generated from pure go code, which can sometimes improve readability and locality, especially in simple applications

Safety

Many HTML libraries divide the components of an HTML page into two categories:

  1. Trusted, static elements (the template source itself)
  2. Untrusted, dynamic elements (string values interpolated at runtime)

The above threat model is too coarse, resulting in low runtime performance and unnecessary implementation complexity.

Instead, we introduce a third category:

  1. Dynamic elements obtained from a trusted source or method of construction

Examples of this third category include:

  • Build-time constants
  • Strings generated from numbers, safe data structures, etc
  • Data loaded from the server's disk (assuming sane security properties)

This package allows the programmer to insert trusted strings into various contexts, but requires explicit trust annotations. Fully trusted strings are allowed in any context, while untrusted strings can sometimes be escaped to be made fit for use in some contexts. Some contexts always require fully trusted strings.

Performance

The runtime performance of this package compares favorably to html/template, being between 5-10 times faster in microbenchmarks.

html5 % go test -bench=. ./...
goos: darwin
goarch: amd64
pkg: github.com/the80srobot/html5
BenchmarkSmallTemplate-16    	  379461	      2996 ns/op
BenchmarkSmallPage-16        	 3247833	       391 ns/op
PASS
ok  	github.com/the80srobot/html5	2.889s
PASS
ok  	github.com/the80srobot/html5/html	0.070s

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Compact = CompileOptions{
		Indent:  "  ",
		Compact: true,
	}

	Tidy = CompileOptions{
		Indent:  "  ",
		Compact: false,
	}

	Debug = CompileOptions{
		Indent:               "  ",
		Compact:              false,
		SeparateStaticChunks: true,
	}
)

Functions

func GenerateHTML

func GenerateHTML(w io.Writer, t *Template, values ...bindings.BindArg) error

Types

type AttributeNode

type AttributeNode struct {
	Name          string
	Value         Value
	RequiredTrust safe.TrustLevel
}

func Attribute

func Attribute(name string, value Value) *AttributeNode

func DataAttribute

func DataAttribute(name string, value Value, trust safe.TrustLevel) *AttributeNode

func (*AttributeNode) Apply

func (a *AttributeNode) Apply(n Node) error

Apply will insert the attribute into the node, which must be ElementNode.

type Case

type Case struct {
	Condition Condition
	Output    Node
}

type CompileOptions

type CompileOptions struct {
	Indent               string
	Compact              bool
	SeparateStaticChunks bool
	TextWidth            int
	RootDepth            int
}

func (*CompileOptions) String

func (opts *CompileOptions) String() string

type Condition

type Condition func(*bindings.ValueMap) bool

type Content

type Content interface {
	Apply(n Node) error
}

func Indent

func Indent(is IndentStyle) Content

func SelfClosing

func SelfClosing() Content

func XMLElement

func XMLElement() Content

XMLElement marks the element as non-HTML and overrides any HTML-derived defaults based on the element name.

type ElementNode

type ElementNode struct {
	Name                string
	Attributes          []AttributeNode
	Contents            []Node
	IndentStyle         IndentStyle
	SelfClosing         bool
	XMLStyleSelfClosing bool
}

ElementNode represents an HTML element, like <p>.

func Element

func Element(name string, contents ...Content) *ElementNode

func (*ElementNode) Apply

func (e *ElementNode) Apply(n Node) error

type IndentStyle

type IndentStyle int16
const (
	Inline IndentStyle = iota
	Block
)

type MultiNode

type MultiNode struct {
	Contents []Node
}

MultiNode concatenates several other nodes.

func Multi

func Multi(contents ...Content) *MultiNode

func (*MultiNode) Apply

func (m *MultiNode) Apply(n Node) error

Apply will insert this node as a child into the other node.

type Node

type Node interface {
	Content
	// contains filtered or unexported methods
}

func Text

func Text(contents ...Value) Node

type NodeOption

type NodeOption func(n Node) error

func (NodeOption) Apply

func (f NodeOption) Apply(n Node) error

type RawNode

type RawNode struct {
	HTML Value
}

RawNode inserts a fully trusted string directly into the page.

func (*RawNode) Apply

func (r *RawNode) Apply(n Node) error

type SubsectionNode

type SubsectionNode struct {
	Prototype Node
	Name      string
}

SubsectionNode represents a self-contained part of the page, which can be repeated in the output, each time with different bindings. (For example, comments under an article might each be a subsection.)

Subsections can contain other subsections.

func (*SubsectionNode) Apply

func (ns *SubsectionNode) Apply(n Node) error

type SwitchNode

type SwitchNode struct {
	Cases   []Case
	Default Node
}

func (*SwitchNode) Apply

func (sn *SwitchNode) Apply(n Node) error

type Template

type Template struct {
	Bindings *bindings.Map
	// contains filtered or unexported fields
}

func Compile

func Compile(n Node, m *bindings.Map, opts *CompileOptions) (*Template, error)

func MustCompile

func MustCompile(n Node, m *bindings.Map, opts *CompileOptions) *Template

func (*Template) GenerateHTML

func (t *Template) GenerateHTML(w io.Writer, vm *bindings.ValueMap) error

func (*Template) String

func (t *Template) String() string

type TextNode

type TextNode struct {
	Value Value
}

func (*TextNode) Apply

func (t *TextNode) Apply(n Node) error

func (*TextNode) String

func (t *TextNode) String() string

type Value

type Value interface {
	Check(required safe.TrustLevel) bool
}

Value is a placeholder for a string value. The two types of values used in this package are binding.Var and safe.Value. The difference between the two is that Vars can be bound to a specific Value at a later time, while Strings are interpolated when we compile the template.

Value provides a way to check that the var or safe string conform to a minimal level of trust.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL