Documentation ¶
Overview ¶
Package formulate is a set of tools for building HTML forms from structs, and parsing HTTP form values back into structs.
Index ¶
- func AppendClass(n *html.Node, classes ...string)
- func BuildBoolField(v reflect.Value, key string, field StructField) *html.Node
- func BuildField(v reflect.Value, key string, field StructField, parent *html.Node, ...) error
- func BuildHelpText(parent *html.Node, field StructField, decorator Decorator)
- func BuildLabel(label string, parent *html.Node, field StructField, decorator Decorator)
- func BuildNumberField(v reflect.Value, key string, field StructField) *html.Node
- func BuildRadioButtons(r RadioList, key string, field StructField, decorator Decorator) *html.Node
- func BuildSelectField(s Select, key string, field StructField) *html.Node
- func BuildStringField(v reflect.Value, key string, field StructField) *html.Node
- func BuildTimeField(t time.Time, key string, field StructField) *html.Node
- func HasAttribute(n *html.Node, attr string) bool
- func OptGroup(name string) *string
- type BoolNumber
- type Condition
- type CustomDecoder
- type CustomEncoder
- type Decorator
- type Email
- type HTMLEncoder
- type HTTPDecoder
- type Option
- type Password
- type RadioList
- type Raw
- type Select
- type ShowConditionFunc
- type StructField
- func (sf StructField) BuildFieldset() bool
- func (sf StructField) Elem() string
- func (sf StructField) GetHelpText() string
- func (sf StructField) GetName() string
- func (sf StructField) HasMax() bool
- func (sf StructField) HasMin() bool
- func (sf StructField) HasStep() bool
- func (sf StructField) Hidden(showConditions map[string]ShowConditionFunc) bool
- func (sf StructField) InputType(original string) string
- func (sf StructField) Max() string
- func (sf StructField) Min() string
- func (sf StructField) Pattern() string
- func (sf StructField) Placeholder() string
- func (sf StructField) Required() bool
- func (sf StructField) Step() string
- type Tel
- type URL
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendClass ¶
AppendClass adds a class to a HTML node.
func BuildBoolField ¶ added in v1.0.1
func BuildField ¶ added in v1.0.2
func BuildField(v reflect.Value, key string, field StructField, parent *html.Node, decorator Decorator, showConditions map[string]ShowConditionFunc) error
func BuildHelpText ¶ added in v1.0.2
func BuildHelpText(parent *html.Node, field StructField, decorator Decorator)
func BuildLabel ¶ added in v1.0.2
func BuildLabel(label string, parent *html.Node, field StructField, decorator Decorator)
func BuildNumberField ¶ added in v1.0.1
func BuildRadioButtons ¶ added in v1.0.1
func BuildSelectField ¶ added in v1.0.1
func BuildSelectField(s Select, key string, field StructField) *html.Node
func BuildStringField ¶ added in v1.0.1
func BuildTimeField ¶ added in v1.0.1
func HasAttribute ¶
HasAttribute returns true if n has the attribute named attr.
Types ¶
type BoolNumber ¶
type BoolNumber int
BoolNumber represents an int (0 or 1) which should actually be rendered as a checkbox. It is provided here as a convenience, as many structures use 0 or 1 to represent booleans values.
func (*BoolNumber) Bool ¶
func (bn *BoolNumber) Bool() bool
Bool returns true if the underlying value is 1.
func (BoolNumber) DecodeFormValue ¶
func (bn BoolNumber) DecodeFormValue(form url.Values, name string, values []string) (reflect.Value, error)
DecodeFormValue implements the CustomDecoder interface.
type Condition ¶
type Condition bool
Condition are optional booleans for Options.
func NewCondition ¶
NewCondition creates a new condition based on a bool value.
type CustomDecoder ¶
type CustomDecoder interface { // DecodeFormValue is passed the whole form values, the name of the element that it is decoding, // and the values for that specific element. It must return a reflect.Value of equal type to the // type which is implementing the CustomDecoder interface. If err != nil, the error will propagate // back through to the Decode() call. DecodeFormValue(form url.Values, name string, values []string) (reflect.Value, error) }
CustomDecoder allows for custom decoding behavior to be specified for an element. If a type implements the CustomDecoder interface, DecodeFormValue is called in place of any other decoding behavior.
type CustomEncoder ¶
type CustomEncoder interface { // BuildFormElement is passed the key of the form element as computed by formulate, // the parent node of the element, the field of the struct // that is currently being rendered, and the form's decorator. // Note that the built element must be appended to the parent or it will not be shown in the form! // Errors returned from BuildFormElement propagate back through to the formulate.Encoder.Encode call. BuildFormElement(key string, parent *html.Node, field StructField, decorator Decorator) error }
CustomEncoder allows for custom rendering behavior of a type to be implemented. If a type implements the CustomEncoder interface, BuildFormElement is called in place of any other formulate rendering behavior for inputs. The label and help text of the element will still be rendered within the row as normal.
type Decorator ¶
type Decorator interface { // RootNode decorates the root <div> of the returned HTML. RootNode(n *html.Node) // Fieldset decorates each <fieldset>. Fieldsets are created for each // non-anonymous struct within the encoded data structure. Fieldset(n *html.Node, field StructField) // Row decorates the parent of each label, input and help text, for each field within the encoded data structure. Row(n *html.Node, field StructField) // FieldWrapper decorates the div which wraps the input and help text within a form FieldWrapper(n *html.Node, field StructField) // Label decorates the <label> for the form element Label(n *html.Node, field StructField) // HelpText decorates the text which is displayed below each form element. // The HelpText is generated from the "help" struct tag. HelpText(n *html.Node, field StructField) // TextField decorates an <input type="text"> TextField(n *html.Node, field StructField) // NumberField decorates an <input type="number"> or equivalent (e.g. Tel) NumberField(n *html.Node, field StructField) // CheckboxField decorates an <input type="checkbox">, displayed for boolean values. CheckboxField(n *html.Node, field StructField) // TextareaField decorates a <textarea> tag. TextareaField(n *html.Node, field StructField) // TimeField decorates an <input type="datetime-local"> used to represent time values. TimeField(n *html.Node, field StructField) // SelectField decorates a <select> dropdown SelectField(n *html.Node, field StructField) // RadioButton decorates an individual <input type="radio"> RadioButton(n *html.Node, field StructField) }
Decorator is used to customise node elements that are built by the HTMLEncoder. Custom decorators can be passed into the HTMLEncoder. If no decorator is specified, a nil decorator is used. This applies no decoration to the output HTML.
type HTMLEncoder ¶
type HTMLEncoder struct {
// contains filtered or unexported fields
}
HTMLEncoder is used to generate a HTML form from a given struct.
func NewEncoder ¶
func NewEncoder(w io.Writer, decorator Decorator) *HTMLEncoder
NewEncoder returns a HTMLEncoder which outputs to w. A Decorator can be passed to NewEncoder, which will then be used to style the outputted HTML. If nil is passed in, no decorator is used, and a barebones HTML form will be returned.
Example ¶
type Address struct { HouseName string `help:"You can leave this blank."` AddressLine1 string AddressLine2 string Postcode string TelephoneNumber Tel CountryCode string `pattern:"[A-Za-z]{3}"` } buf := new(bytes.Buffer) address := Address{ AddressLine1: "Fake Street", } encoder := NewEncoder(buf, nil) encoder.SetFormat(true) if err := encoder.Encode(&address); err != nil { panic(err) } fmt.Println(buf.String())
Output: <div> <fieldset> <div> <label for="HouseName"> House Name </label> <div> <input type="text" name="HouseName" id="HouseName" value=""/> <div> You can leave this blank. </div> </div> </div> <div> <label for="AddressLine1"> Address Line 1 </label> <div> <input type="text" name="AddressLine1" id="AddressLine1" value="Fake Street"/> <div></div> </div> </div> <div> <label for="AddressLine2"> Address Line 2 </label> <div> <input type="text" name="AddressLine2" id="AddressLine2" value=""/> <div></div> </div> </div> <div> <label for="Postcode"> Postcode </label> <div> <input type="text" name="Postcode" id="Postcode" value=""/> <div></div> </div> </div> <div> <label for="TelephoneNumber"> Telephone Number </label> <div> <input type="tel" name="TelephoneNumber" id="TelephoneNumber" value=""/> <div></div> </div> </div> <div> <label for="CountryCode"> Country Code </label> <div> <input type="text" name="CountryCode" id="CountryCode" value="" pattern="[A-Za-z]{3}"/> <div></div> </div> </div> </fieldset> </div>
func (*HTMLEncoder) AddShowCondition ¶
func (h *HTMLEncoder) AddShowCondition(key string, fn ShowConditionFunc)
AddShowCondition allows you to determine visibility of certain form elements. For example, given the following struct:
type Example struct { Name string SecretOption bool `show:"adminOnly"` }
If you wanted to make the SecretOption field only show to admins, you would call AddShowCondition as follows:
AddShowCondition("adminOnly", func() bool { // some code that determines if we are 'admin' })
You can add multiple ShowConditions, but they must have different keys.
func (*HTMLEncoder) Encode ¶
func (h *HTMLEncoder) Encode(i interface{}) error
Encode takes a struct (or struct pointer) and produces a HTML form from all elements in the struct. The encoder deals with most simple types and structs, but more complex types (maps, slices, arrays) will render as a JSON blob in a <textarea>.
The rendering behavior of any element can be replaced by implementing the CustomEncoder interface.
func (*HTMLEncoder) SetFormat ¶
func (h *HTMLEncoder) SetFormat(b bool)
SetFormat tells the HTMLEncoder to output formatted HTML. Formatting is provided by the https://github.com/yosssi/gohtml package.
type HTTPDecoder ¶
type HTTPDecoder struct {
// contains filtered or unexported fields
}
HTTPDecoder takes a set of url values and decodes them.
func NewDecoder ¶
func NewDecoder(form url.Values) *HTTPDecoder
NewDecoder creates a new HTTPDecoder.
Example ¶
type Address struct { HouseName string `help:"You can leave this blank."` AddressLine1 string AddressLine2 string Postcode string TelephoneNumber Tel CountryCode string `pattern:"[A-Za-z]{3}"` } // formValues - usually these would come from *http.Request.Form! formValues := url.Values{ "HouseName": {"1 Example Road"}, "AddressLine1": {"Fake Town"}, "AddressLine2": {"Fake City"}, "Postcode": {"Postcode"}, "TelephoneNumber": {"012345678910"}, "CountryCode": {"GBR"}, } var address Address decoder := NewDecoder(formValues) if err := decoder.Decode(&address); err != nil { panic(err) } fmt.Printf("House Name: %s\n", address.HouseName) fmt.Printf("Line 1: %s\n", address.AddressLine1) fmt.Printf("Line 2: %s\n", address.AddressLine2) fmt.Printf("Postcode: %s\n", address.Postcode) fmt.Printf("Telephone: %s\n", address.TelephoneNumber) fmt.Printf("CountryCode: %s\n", address.CountryCode)
Output: House Name: 1 Example Road Line 1: Fake Town Line 2: Fake City Postcode: Postcode Telephone: 012345678910 CountryCode: GBR
func (*HTTPDecoder) Decode ¶
func (h *HTTPDecoder) Decode(data interface{}) error
Decode a the given values into a provided interface{}. Note that the underlying value must be a pointer.
type Option ¶
type Option struct { Value interface{} Label string Group *string Disabled bool Checked *Condition Attr []html.Attribute }
Option represents an option in Select inputs and Radio inputs.
type RadioList ¶
type RadioList interface { CustomDecoder RadioOptions() []Option }
RadioList represents a list of <input type="radio">. Radio lists must implement their own decoder.
type Raw ¶
type Raw []byte
Raw is byte data which should be rendered as a string inside a textarea.
func (Raw) BuildFormElement ¶
func (r Raw) BuildFormElement(key string, parent *html.Node, field StructField, decorator Decorator) error
BuildFormElement implements the CustomEncoder interface.
type Select ¶
type Select interface { // SelectMultiple indicates whether multiple options can be selected at once. SelectMultiple() bool // SelectOptions are the available options SelectOptions() []Option }
Select represents a HTML <select> element.
type ShowConditionFunc ¶
type ShowConditionFunc func() bool
ShowConditionFunc is a function which determines whether or not to show a form element. See: HTMLEncoder.AddShowCondition
type StructField ¶
type StructField struct {
reflect.StructField
}
StructField is a wrapper around the reflect.StructField type. The rendering behavior of form elements is controlled by Struct Tags. The following tags are currently available:
- name (e.g. name:"Phone Number") - this overwrites the name used in the label. This value can be left empty.
- help (e.g. help:"Enter your phone number, including area code") - this text is displayed alongside the input field as a prompt.
- show (e.g. show:"adminOnly") - controls visibility of elements. See HTMLEncoder.AddShowCondition for more details. if "contents" is used, the field is shown and the parent fieldset (if any) will be omitted.
- type (e.g. type:"tel") - sets the HTML input "type" attribute
- elem (elem:"textarea") - used to specify that a text input should use a <textarea> rather than an input field.
- min (e.g. min:"0") - minimum value for number inputs
- max (e.g. max:"10") - maximum value for number inputs
- step (e.g. step:"0.1") - step size for number inputs
- pattern (e.g. pattern:"[a-z]+" - regex pattern for text inputs
These can all be used in combination with one another in a struct field. A full example of the above types is:
type Address struct { HouseNumber int `min:"0" help:"Please enter your house number" name:"House Number (if any)" AddressLine1 string DeliveryInstructions string `elem:"textarea"` CountryCode string `pattern:"[A-Za-z]{3}"` }
func (StructField) BuildFieldset ¶
func (sf StructField) BuildFieldset() bool
BuildFieldset determines whether a given struct should be inside its own fieldset. Use the Struct Tag show:"contents" to indicate that a fieldset should not be built for this struct.
func (StructField) Elem ¶
func (sf StructField) Elem() string
Elem returns the element to be used. Currently the only supported value is <textarea>. <input> will be used if not specified.
func (StructField) GetHelpText ¶
func (sf StructField) GetHelpText() string
GetHelpText returns the help text for the field.
func (StructField) GetName ¶
func (sf StructField) GetName() string
GetName returns the name of the StructField, taking into account tag name overrides.
func (StructField) HasMax ¶
func (sf StructField) HasMax() bool
HasMax determines if a StructField has a maximum value
func (StructField) HasMin ¶
func (sf StructField) HasMin() bool
HasMin determines if a StructField has a minimum value
func (StructField) HasStep ¶
func (sf StructField) HasStep() bool
HasStep determines if a StructField has a step value
func (StructField) Hidden ¶
func (sf StructField) Hidden(showConditions map[string]ShowConditionFunc) bool
Hidden determines if a StructField is hidden based on the showConditions.
func (StructField) InputType ¶
func (sf StructField) InputType(original string) string
InputType returns the HTML <input> element type attribute
func (StructField) Max ¶
func (sf StructField) Max() string
Max is the maximum value of the StructField
func (StructField) Min ¶
func (sf StructField) Min() string
Min is the minimum value of the StructField
func (StructField) Pattern ¶
func (sf StructField) Pattern() string
func (StructField) Placeholder ¶ added in v1.0.2
func (sf StructField) Placeholder() string
func (StructField) Required ¶ added in v1.0.2
func (sf StructField) Required() bool