Documentation ¶
Overview ¶
Package form provides utilities for creating and accessing HTML forms.
This is an abstraction for defining forms in text, and accessing them accordingly. It is partially inspired by Drupal's form library.
This generates HTML5 forms. http://www.w3.org/TR/html5/forms.html
In this package, you will find:
- a Form type for declaring a new form
- types for each form field type
- the FormHandler for automating form storage, submission, and retrieval
- secure tokens for mitigating XSS attacks
- a caching framework for storing form data (used by FormHandler)
Engine also provides templates for rendering a form into HTML. The expected form workflow goes something like this:
- Declare a form in-code
- Prepare the form, which adds security and caches a copy
- Render the form to HTML and serve it to the client
- On form submission, get the form values
- Look up the form and populate it with the submitted values
- Work with the returned form
The example below illustrates how most of this is done by the library.
Example ¶
// Create a new form: f := New("My Form", "/submit") // Add some fields f.Fields = []Field{ &Text{Name: "username"}, &Password{Name: "password"}, } // Prepare the form using the default form handler. id, err := DefaultFormHandler.Prepare(f) if err != nil { fmt.Printf("Error preparing form: %s", err) return } // Render the form to the user agent. Typlically you do this // with a template. // When the form is submitted, it will return something like this: vals := &url.Values{ "username": []string{"matt"}, "password": []string{"secret"}, SecureTokenName: []string{id}, } // We can pass in the values and retrieve the form, with the values // all entered on the appropriate element. ff, err := DefaultFormHandler.Retrieve(vals) if err != nil { fmt.Printf("Failed to retrieve form: %s", err) return } // Now we can access the fields directly user := ff.Fields[0].(*Text).Value pass := ff.Fields[1].(*Password).Value fmt.Println(user) fmt.Println(pass)
Output: matt secret
Index ¶
- Constants
- Variables
- func Reconcile(fm *Form, data *url.Values) error
- func SecurityToken() string
- type Button
- type ButtonInput
- type Cache
- type CacheVal
- type Checkbox
- type Color
- type DataList
- type Date
- type Div
- type Email
- type Field
- type FieldSet
- type File
- type Form
- type FormElement
- type FormHandler
- type HTML
- type Hidden
- type Image
- type Input
- type Keygen
- type Label
- type Meter
- type Number
- type OptGroup
- type Option
- type OptionItem
- type OptionalBool
- type Output
- type Password
- type Progress
- type Radio
- type Range
- type Reset
- type Select
- type String
- type Submit
- type Tel
- type Text
- type TextArea
- type Time
- type URL
Examples ¶
Constants ¶
const ( // Left-to-right LTR = "ltr" // Right-to-left RTL = "rtl" // Determine based on UA Auto = "auto" )
Variables ¶
var DefaultFormHandler = NewFormHandler(NewCache(), time.Hour*24)
DefaultFormHandler is a form handler initialized with an in-memory cache and a 24 hour expiration on form data.
var ErrFormNotFound = errors.New("Form not found")
FormNotFound indicates that a form is not in the cache.
Expired records should also return this error.
var ErrNoToken = errors.New("No token provided")
ErrNoToken indicates that provided form data has no security token.
var SecureTokenName = "__token__"
The name of the token that is automatically placed into a form.
This should never be modified after a form has been generated.
var SecurityTokenLength = 32
The length of the security token.
var SweepInterval = 5 * time.Minute
SweepInterval is a suggested interval for sweeping the cache.
It is not mandatory that caching backends use SweepInterval, but the default caching mechanism uses it to indicate how frequently it should purge the cache of expired records.
Functions ¶
func Reconcile ¶
Reconcile modifies a form in place, merging the data into the form's Value fields.
Validation is not handled by the reconciler.
Normally, reconciliation will happen via the FormHandler's Retrieve method.
func SecurityToken ¶
func SecurityToken() string
Generate a security token.
This uses SecurityTokenLength to determine the appropriate length. If that value is <= 0, this will panic.
Types ¶
type ButtonInput ¶
type ButtonInput Input
Button provides a generic button. This is deprecated in favor of the Button type.
type Cache ¶
type Cache interface { Get(id string) (*Form, error) Set(id string, f *Form, expires time.Time) error Remove(id string) error }
Cache provides storage for forms.
Generally, a cache is not used directly. Instead, the FormHandler is used.
Cache implementations are required to handle expiration internally.
type CacheVal ¶
type CacheVal struct {
// contains filtered or unexported fields
}
CacheVal describes a value in the cache.
Timeout indicates when the current form is no longer valid, and can be cleaned up.
type Div ¶
Divs are generic containers for fields.
Because divs are frequently used to segment forms, we support them explicitly.
type FieldSet ¶
type FieldSet struct { HTML Form, Name string Disabled bool Fields []Field // This is not an attribute, but we should auto-generate the results. Legend string }
FieldSet describes a set of form fields.
type Form ¶
type Form struct { HTML AcceptCharset, Enctype, Action, Method, Name, Target string Autocomplete, Novalidate bool Fields []Field }
Form describes an HTML5 form.
A form can encapsulate an arbitrary number of form.Field objects.
Forms can be create with the New() function, or instantiated directly. Then are typically rendered through the form templating system.
func (*Form) AsValues ¶
AsValues converts a form to its name/value pairs.
This is a "lossy" conversion. It only retains elements that have a meaningful notion of "value" (like text, select, button, and checkbox), but omits elements like Div, Output, OptGroup, and FieldSet that do not have a meaningful notion of value.
For fields that commonly can have multiple values (Select, Checkbox), values are appended. For elements that do not admit multiple values (Text, Radio, TextArea, etc), only one value is set.
type FormElement ¶
FormElement describes any form element capable of expression as an html.Node.
type FormHandler ¶
type FormHandler struct { // The duration a form will be kept before it expires. Expiration time.Duration // contains filtered or unexported fields }
FormHandler manages the cache-and-load lifecycle of forms.
FormHandler enforces security constraints on forms, and will modify forms in place.
func NewFormHandler ¶
func NewFormHandler(c Cache, expiration time.Duration) *FormHandler
NewFormHandler creates a new FormHandler.
func (*FormHandler) Prepare ¶
func (f *FormHandler) Prepare(form *Form) (string, error)
Prepare modifies the form for caching and security, then inserts it into cache.
This will add a security field to the end of the form's Fields list. The generated ID will be returned. And the form will be placed into the cache.
This form can later be retrieved using the returned ID.
func (*FormHandler) Remove ¶
func (f *FormHandler) Remove(id string) error
func (*FormHandler) Retrieve ¶
func (f *FormHandler) Retrieve(data *url.Values) (*Form, error)
Retrieve uses a request's key/value pairs to populate a cached form.
It then decodes the submission data into the relevant cached form, and returns the form. The Value fields on each form element will be set according to the data. If the form data was not set for a particular field, that field will be left alone (which means that if it had a default value, that will remain in effect).
Finally, Retrieve will remove the form from the cache, since a form cannot be re-used.
The implementing function must pass in the appropriate set of values. The "net/http" library makes Get, Post, Put, and Patch variables all available as *url.Values.
type HTML ¶
type HTML struct { Class []string AccessKey, Id, Dir, Lang, Style, TabIndex, Title, Translate string ContentEditable, Hidden OptionalBool Role string // Data stores arbitrary attributes, such as data-* fields. It is up to // the implementation to know how to deal with these fields. Data map[string]string // Attributes prefixed "aria-" Aria map[string]string }
HTML captures a group of attributes common across all HTML elements.
These attributes are all defined as Global, ARIA and Data attributes in the HTML5 specification. Because all of these can be applied to any form content, they are exposed here.
The allowed values for all of these are explained in the HTML5 spec. Because we strive more for expression in the browser than semantic correctness, here and elsewhere we rarely force a particular value to conform to the spec. Typically, typing is as close as we get to enforcement.
type Hidden ¶
type Hidden Input
Hidden provides a field that will not be displayed.
func SecurityField ¶
func SecurityField() Hidden
SecurityField returns a Hidden form element initialized with a security token.
type Input ¶
type Input struct { HTML Accept, Alt, Autocomplete, Dirname, Form, List, InputMode, Max, Min, MaxLength string Name, Pattern, Placeholder, Src, Step, Value string Autofocus, Checked, Disabled, Multiple, ReadOnly, Required bool Height, Width, Size uint64 // Technically, this is not an attribute of an Input field, but we put it here // to simplify the process of labeling fields. Label string }
Input defines a generic untyped form field.
It should not generally be used directly.
type Keygen ¶
type Keygen struct { HTML Challenge, Form, KeyType, Name string Autofocus, Disabled bool Value string }
Keygen describes the keygen form field type.
type Label ¶
Label describes a label for a field.
Because labels are almost always applied to specific fields, and because the rules for attaching a label to a field vary by field type, more often than not you should favor a field's Label property over adding a Label element directly.
type Option ¶
type Option struct { HTML Disabled, Selected bool // A label is the user-visible text, while the value is what is // sent to the server. Label may be rendered as phrasing content. Label, Value string }
Option describes an individual option in a selection, datalist, or optgroup.
type OptionItem ¶
type OptionItem interface{}
OptionItem describes any item that can be a member of an options list.
Select fields allow option items, while DataLists are more strict, and require Option types.
type OptionalBool ¶
type OptionalBool uint8
const ( // Nothing set, results in inheriting parent settings. ONone OptionalBool = iota // True OTrue // False OFalse )
type Select ¶
type Select struct { HTML Autofocus, Disabled, Multiple, Required bool Form, Name string Size uint64 Options []OptionItem Label string }
Select defines a selection list form element.
type String ¶
type String string
String is for PCData that can be arbitarily embeded in a []Field list.
type Text ¶
type Text Input
Text provides a single text entry line. See TextArea for multi-line input.