gohtmx

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2024 License: MIT Imports: 10 Imported by: 0

README

gohtmx

A component library for building composable golang APIs using HTMX and html/template.

Goals

The end goal is to have an easy to compose UI component system that allows full stack development from pure golang. The UI should be easy to pre-populate with data and support deep linking functionality as well as leave the door open for more complex functionality.

Architecture

gohtmx is in the end generating html/templates. It provides ergonomic creation of templates through compositional structs and enabling inline usage of golang functions for template data interaction.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrPrependPath

func ErrPrependPath(err error, path ...string) error

ErrPrependPath either adds the path to an existing PathError or creates a new one.

func GetDataFromRequest

func GetDataFromRequest(params ...string) func(r *http.Request) Data

GetDataFromRequest returns Data with the values from the request. Handles both GET and POST requests.

Types

type A

type A struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Href    string
	Content Component
}

A is a shorthand for an "a" Tag.

func (A) Init

func (a A) Init(p *Page) (Element, error)

type Attributes

type Attributes struct {
	Values map[string][]string
}

Attributes defines a map of attributes for use in a Tag. Attributes are rendered in alphabetical order. Attributes are stored as Elements to allow for templating.

func Attrs

func Attrs() *Attributes

Attrs creates a new Attributes. This should be used over creating them manually.

func (*Attributes) Bool

func (a *Attributes) Bool(name string, active bool) *Attributes

Bool adds a named flag to the attributes if active is true.

func (*Attributes) Copy

func (a *Attributes) Copy() *Attributes

Copy returns a shallow copy of the attributes.

func (*Attributes) Delete

func (a *Attributes) Delete(name string) *Attributes

func (*Attributes) Ensure

func (a *Attributes) Ensure() *Attributes

Ensure guarantees that the Attributes are not nil.

func (*Attributes) Get

func (a *Attributes) Get(key string) (string, bool)

Get returns the first value of the attribute if it exists.

func (*Attributes) IsEmpty

func (a *Attributes) IsEmpty() bool

IsEmpty returns true if there are no attributes.

func (*Attributes) String

func (a *Attributes) String(name string, value string) *Attributes

String adds a named value to the attributes if it is not empty.

func (*Attributes) Strings

func (a *Attributes) Strings(name string, values ...string) *Attributes

Slice adds a named list of values to the attributes if it is not empty.

func (*Attributes) Write

func (a *Attributes) Write(w io.Writer) error

Write writes the attributes to the passed io.Writer.

type Button

type Button struct {
	ID      string
	Classes []string
	Attr    *Attributes

	Content Component

	Hidden   bool
	Disabled bool
}

Button is a shorthand for a "button" Tag.

func (Button) Init

func (b Button) Init(p *Page) (Element, error)

type Component

type Component interface {
	// Init converts the component into an Element based on the contextual data of the Framework.
	Init(p *Page) (Element, error)
}

Component defines the high level abstraction of an HTML element. Components are decomposed into an Element through the Init call.

type ComponentTag

type ComponentTag struct {
	Name    string
	Attrs   *Attributes
	Content Component
}

ComponentTag creates a html tag with the given name.

func (ComponentTag) Init

func (c ComponentTag) Init(p *Page) (Element, error)

type Data

type Data map[string]any

Data represents a neutral representation of data that is passed through any method HTMX requests.

func GetAllDataFromRequest

func GetAllDataFromRequest(r *http.Request) Data

GetAllDataFromRequest returns all Data from the request. Handles both GET and POST requests.

func (Data) Merge

func (d Data) Merge(a Data) Data

Merge merges two Data maps together. The addition map will overwrite any existing keys.

func (Data) SetInResponse

func (d Data) SetInResponse(w http.ResponseWriter, r *http.Request)

SetValuesInResponse sets the data Data in the response. Handles both GET and POST requests.

func (Data) Subset

func (d Data) Subset(keys ...string) Data

Subset creates a new Data map with only the passed keys.

type Div

type Div struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Content Component
}

Div is a shorthand for a "div" Tag.

func (Div) Init

func (d Div) Init(p *Page) (Element, error)

type Document

type Document struct {
	// Header defines Component to be rendered in between the <head> tags.
	Header Component
	// Body defines the Component to be rendered in between the <body> tags.
	Body Component
}

Document the baseline component of an HTML document.

func (Document) Init

func (d Document) Init(p *Page) (Element, error)

type Element

type Element interface {
	Render(w io.Writer) error
	Validate() error
	FindAttrs() (*Attributes, error)
}

Element defines the low level abstraction of an HTML element. Elements write directly to an io.Writer and are used to build a html/template.

type Elements

type Elements []Element

Elements defines a slice of Elements that can be used as a single Element.

func (Elements) FindAttrs

func (e Elements) FindAttrs() (*Attributes, error)

func (Elements) Render

func (e Elements) Render(w io.Writer) error

func (Elements) Validate

func (e Elements) Validate() error

type Fragment

type Fragment []Component

Fragment defines a slice of Components that can be used as a single Component.

func (Fragment) Init

func (fr Fragment) Init(p *Page) (Element, error)

type Generator

type Generator interface {
	NewID(group string) string
}

Generator used to generate content for building templates.

func NewDefaultGenerator

func NewDefaultGenerator() Generator

type H

type H struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool
	Level   int

	Content Component
}

H is a shorthand for a "h*" Tag.

func (H) Init

func (h H) Init(p *Page) (Element, error)
type Header struct {
	ID      string
	Classes []string
	Attr    *Attributes
	Hidden  bool

	Content Component
}

Header is a shorthand for a "header" Tag.

func (Header) Init

func (h Header) Init(p *Page) (Element, error)

type Img

type Img struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Src string
	Alt string
}

Img is a shorthand for an "img" Tag.

func (Img) Init

func (img Img) Init(_ *Page) (Element, error)

type Input

type Input struct {
	ID      string
	Classes []string
	Attr    *Attributes
	Hidden  bool

	Type     string
	Name     string
	Value    string
	Disabled bool
}

Input is a shorthand for an "input" Tag.

func (Input) Init

func (i Input) Init(_ *Page) (Element, error)

type Interaction

type Interaction struct {
	Name string
	// contains filtered or unexported fields
}

Interaction defines a set of Swaps, Triggers, and Updates. Swaps define changes to the content of the page. Triggers define what can cause the Interaction to occur. Updates define changes to the backing data. All interactions are named to mount the interaction to the current page path.

func NewInteraction

func NewInteraction(name string) *Interaction

NewInteraction creates a new Interaction with the given name.

func (*Interaction) AddSwap

func (i *Interaction) AddSwap(a *Swap) *Interaction

AddSwap adds a Swap to the Interaction.

func (*Interaction) AddTrigger

func (i *Interaction) AddTrigger(t *Trigger) *Interaction

AddTrigger adds a Trigger to the Interaction.

func (*Interaction) Handle

func (i *Interaction) Handle(f func(*http.Request)) *Interaction

Handle adds a handler to the Interaction.

func (*Interaction) Swap

func (i *Interaction) Swap() *Swap

Swap creates a new Swap for the Interaction.

func (*Interaction) Trigger

func (i *Interaction) Trigger() *Trigger

Trigger creates a new Trigger for the Interaction.

type IterGenerator

type IterGenerator struct {
	Index map[string]int64
}

func (*IterGenerator) NewID

func (b *IterGenerator) NewID(prefix string) string

type LI

type LI struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Content Component
}

LI is a shorthand for a "li" Tag.

func (LI) Init

func (li LI) Init(p *Page) (Element, error)

type Middleware

type Middleware func(http.Handler) http.Handler

func UpdateParams

func UpdateParams(names ...string) Middleware

UpdateParams updates the passed values into the Query Params of the response. Handles both GET and POST requests.

type OL

type OL struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Items []LI
}

OL is a shorthand for an "ol" Tag.

func (OL) Init

func (ol OL) Init(p *Page) (Element, error)

type P

type P struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Content Component
}

P is a shorthand for a "p" Tag.

func (P) Init

func (p P) Init(g *Page) (Element, error)

type Page

type Page struct {
	// PathPrefix defines the current prefix for a component to build requests from.
	PathPrefix string
	// Index collects all the interactive components of the page.
	Index map[string]Request
	// The template to use for rendering components.
	Template *template.Template
	// Generator provides generated content for initializing elements.
	Generator Generator
}

Page defines a single page application.

func NewPage

func NewPage() *Page

func (*Page) Add

func (p *Page) Add(component Component)

Add adds a component to the request at this pages current path. This is when a Component is initialized through Init into elements.

func (*Page) AtPath

func (p *Page) AtPath(segments ...string) *Page

AtPath returns a new Page with the with the segments appended to the current path. Resources are shared between both new and old page, only the path is different.

func (*Page) Build

func (p *Page) Build() (http.Handler, error)

Build creates a new http.Handler for the entire page.

func (*Page) Init

func (p *Page) Init(c Component) Element

Init initializes a component and returns its created element. This handles the error without the Component from having to. This is a convenience method for Components to use to initialize other components/contents.

func (*Page) Path

func (p *Page) Path(segments ...string) string

Path returns the full path of the page with any additional segments appended.

func (*Page) Render

func (p *Page) Render(element Element) (http.Handler, error)

Render creates a new http.Handler for the given element. This will run validation and rendering on the element.

func (*Page) Use

func (p *Page) Use(middleware ...Middleware)

Use adds middleware to the request at this pages current path.

type PathError

type PathError struct {
	Path []string
	Err  error
}

PathError is a custom error for attaching a path to an error.

func (PathError) Error

func (p PathError) Error() string

func (PathError) Prepend

func (p PathError) Prepend(path ...string) PathError

func (PathError) String

func (p PathError) String() string

func (PathError) Unwrap

func (p PathError) Unwrap() error

type Raw

type Raw string

Raw defines the most simple Element that defines purely string data.

func (Raw) FindAttrs

func (r Raw) FindAttrs() (*Attributes, error)

func (Raw) Init

func (r Raw) Init(_ *Page) (Element, error)

func (Raw) Render

func (r Raw) Render(w io.Writer) error

func (Raw) Validate

func (r Raw) Validate() error

type RawError

type RawError struct {
	Err error
}

func (RawError) FindAttrs

func (r RawError) FindAttrs() (*Attributes, error)

func (RawError) Init

func (r RawError) Init(_ *Page) (Element, error)

func (RawError) Render

func (r RawError) Render(w io.Writer) error

func (RawError) Validate

func (r RawError) Validate() error

type Reference

type Reference struct {
	// Target is the Component that is being referenced.
	Target Component

	// TODO: These feel wrong
	// ValidationFunc is an optional function to run when this reference is validated.
	// This is monatomic, so will only ever be called once.
	ValidationFunc ValidationFunc
	// RenderFunc is an optional function to run when this reference is rendered.
	RenderFunc RenderFunc

	// Initialized is the initialized Element, if it has been initialized.
	Initialized Element
	// Page is the page that the Reference is rendered initialized at.
	// This is stored so any content generated during validation can be added relative to the same location the content
	// is rendered.
	Page *Page
}

Reference wraps a Component to allow for referencing during validation and rendering.

func (*Reference) FindAttrs

func (m *Reference) FindAttrs() (*Attributes, error)

func (*Reference) ID

func (m *Reference) ID() (string, error)

ID returns the ID of the initialized Target. If the Target is missing an ID, a new one is generated.

func (*Reference) Init

func (m *Reference) Init(p *Page) (Element, error)

func (*Reference) Render

func (m *Reference) Render(w io.Writer) error

func (*Reference) Validate

func (m *Reference) Validate() error

type RenderFunc

type RenderFunc func(r *Reference, w io.Writer) (io.Writer, error)

type Request

type Request struct {
	Elements   Elements
	Middleware []Middleware
}

Request defines a single interactive endpoint.

func (Request) Handler

func (r Request) Handler(p *Page) (http.Handler, error)

Handler creates a new http.Handler for the request. This will run validation and rendering on the elements.

type Scope

type Scope struct {
	Path    string
	Content Component
}

Scope defines a Component that modifies the current path of the Page.

func (Scope) Init

func (s Scope) Init(p *Page) (Element, error)

type ScrollPosition

type ScrollPosition string

ScrollPosition is the location to Scroll or Show in the SwapMethod.

const (
	ScrollTop    ScrollPosition = "top"
	ScrollBottom ScrollPosition = "bottom"
)

type Span

type Span struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Content Component
}

Span is a shorthand for a "span" Tag.

func (Span) Init

func (s Span) Init(p *Page) (Element, error)

type Swap

type Swap struct {
	// contains filtered or unexported fields
}

Swap defines the application of new content to a target. This can occur either in or out of bounds. If out of bounds, the contents will be updated to include the id of the contents.

func NewSwap

func NewSwap() *Swap

Creates a new Swap. This defines the application of new content to a target. This can occur either in or out of bounds.

func (*Swap) Content

func (s *Swap) Content(c Component) Component

Content sets the content of the Swap. Content can only be set once.

func (*Swap) Method

func (s *Swap) Method(m SwapMethod) *Swap

Method sets the swap method to replace the target with.

func (*Swap) OutOfBounds

func (s *Swap) OutOfBounds() *Swap

OutOfBounds sets the Swap to be out of bounds.

func (*Swap) Target

func (s *Swap) Target(c Component) Component

Target sets the target of the Swap. The ID is used for targeting the element to swap. If the target is missing an ID, a new one is generated for the target. Target can only be set once.

func (*Swap) Update

func (s *Swap) Update(c Component) Component

Shorthand for setting the content and target of the Swap to the same Component. Also sets the swap to OuterHTML.

type SwapMethod

type SwapMethod string

SwapMethod defines the method of swapping content. See https://htmx.org/docs/#swapping

const (
	SwapInnerHTML   SwapMethod = "innerHTML"
	SwapOuterHTML   SwapMethod = "outerHTML"
	SwapAfterBegin  SwapMethod = "afterbegin"
	SwapBeforeBegin SwapMethod = "beforebegin"
	SwapAfterEnd    SwapMethod = "afterend"
	SwapBeforeEnd   SwapMethod = "beforeend"
	SwapDelete      SwapMethod = "delete"
	SwapNone        SwapMethod = "none"
)

func (SwapMethod) FocusScroll

func (s SwapMethod) FocusScroll(enabled bool) SwapMethod

FocusScroll sets the SwapMethod to scroll to the focused element when the content is swapped.

func (SwapMethod) Scroll

func (s SwapMethod) Scroll(target ScrollPosition) SwapMethod

Scroll sets the SwapMethod to scroll the target to the given ScrollPosition when the content is swapped.

func (SwapMethod) Show

func (s SwapMethod) Show(target ScrollPosition) SwapMethod

Show sets the SwapMethod to show the target at the given ScrollPosition when the content is swapped.

type TBlock

type TBlock struct {
	Text       string
	IncludeEnd bool
	Element    Element
	Component  Component
}

func (TBlock) FindAttrs

func (t TBlock) FindAttrs() (*Attributes, error)

func (TBlock) Init

func (t TBlock) Init(p *Page) (Element, error)

func (TBlock) Render

func (t TBlock) Render(w io.Writer) error

func (TBlock) Validate

func (t TBlock) Validate() error

type TWith

type TWith struct {
	Func    func(*http.Request) any
	Content Component
}

TWith defines a template block to be executed with . being set to the result of the Func.

func (TWith) Init

func (t TWith) Init(p *Page) (Element, error)

type Tag

type Tag struct {
	// Name of this tag.
	Name string
	// Attr defines the list of Attributes for this tag.
	Attrs *Attributes
	// Content defines the contents this wraps.
	Content Element
}

Tag defines the lowest level HTML generic tag element.

func (*Tag) FindAttrs

func (t *Tag) FindAttrs() (*Attributes, error)

func (*Tag) Render

func (t *Tag) Render(w io.Writer) error

func (*Tag) Validate

func (t *Tag) Validate() error

type TemplateHandler

type TemplateHandler struct {
	Template *template.Template
	Name     string
}

func (TemplateHandler) ExecuteWith

func (t TemplateHandler) ExecuteWith(r *http.Request, data Data) ([]byte, error)

func (TemplateHandler) ServeHTTP

func (t TemplateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (TemplateHandler) ServeHTTPWithData

func (t TemplateHandler) ServeHTTPWithData(w http.ResponseWriter, r *http.Request, data Data)

type Trigger

type Trigger struct {
	Values url.Values
	// contains filtered or unexported fields
}

Trigger defines something that can cause an Interaction to occur. Each Trigger can contain a set of values to be sent with the request.

func NewTrigger

func NewTrigger() *Trigger

NewTrigger creates a new Trigger.

func (*Trigger) Init

func (t *Trigger) Init(p *Page) (Element, error)

func (*Trigger) Method

func (t *Trigger) Method(m TriggerMethod) *Trigger

func (*Trigger) Path

func (t *Trigger) Path(p *Page) string

func (*Trigger) Set

func (t *Trigger) Set(key, value string) *Trigger

func (*Trigger) Target

func (t *Trigger) Target(c Component) Component

func (*Trigger) Update

func (t *Trigger) Update(p *Page, swap *Swap) error

type TriggerMethod

type TriggerMethod string

TriggerMethod defines the method of triggering an Interaction. See https://htmx.org/docs/#triggers

const (
	TriggerLoad     TriggerMethod = "load"
	TriggerRevealed TriggerMethod = "revealed"
	TriggerClick    TriggerMethod = "click"
	TriggerChange   TriggerMethod = "change"
	TriggerSubmit   TriggerMethod = "submit"
)

func (TriggerMethod) Changed

func (t TriggerMethod) Changed() TriggerMethod

Changed sets the TriggerMethod to trigger when the value of the target changes.

func (TriggerMethod) Delay

func (t TriggerMethod) Delay(delay time.Duration) TriggerMethod

Delay sets the TriggerMethod to trigger after the given delay. If a new event is triggered before the delay, the timer is reset.

func (TriggerMethod) Throttle

func (t TriggerMethod) Throttle(delay time.Duration) TriggerMethod

Throttle sets the TriggerMethod to trigger at most once every delay. If a new event is triggered before the delay, the event is ignored.

type UL

type UL struct {
	ID      string
	Classes []string
	Attrs   *Attributes
	Hidden  bool

	Items []LI
}

UL is a shorthand for a "ul" Tag.

func (UL) Init

func (ul UL) Init(p *Page) (Element, error)

type ValidationFunc

type ValidationFunc func(r *Reference) error

Jump to

Keyboard shortcuts

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