Documentation
¶
Overview ¶
Package forms is the error model of vuka's forms: what is wrong with a field or a whole form, as data — its path, the rule it broke, the rule's parameters and a message key — and the one function that turns an error into the words a visitor reads.
A form is a Go struct embedding ui.FormState; package ui binds, validates and renders it. This package holds what both a form's own methods and the rest of an app need without the component library: Errorf for a Clean method's error, Live to tell a check run while the visitor types from one run on submit, and Text for the message — through the app's message catalogue (Messages, Translations) in the request's language (WithLocale).
func (f *Signup) CleanEmail(ctx context.Context, users *Users) error {
if forms.Live(ctx) {
return nil // checked on submit only
}
if users.Exists(ctx, f.Email) {
return forms.Errorf("That email address is already registered")
}
return nil
}
Every error carries one dotted path naming its field — "email", "address.city" — the same path the markup's ids, the error summary's links, tests and message keys use. A form-level error has the path "".
Index ¶
- func DefaultKey(e Error) string
- func Detach(ctx context.Context) context.Context
- func Live(ctx context.Context) bool
- func Locales(ctx context.Context) []string
- func Param(n float64) string
- func ParseAcceptLanguage(h string) []string
- func PluralCategory(locale string, n float64, frac int) string
- func SetPlural(lang string, rule PluralRule)
- func Text(ctx context.Context, e Error, label string) string
- func Translate(ctx context.Context, text string) string
- func WithBase(ctx context.Context, c Catalogue) context.Context
- func WithCatalogue(ctx context.Context, c Catalogue) context.Context
- func WithLive(ctx context.Context) context.Context
- func WithLocale(ctx context.Context, tags ...string) context.Context
- type Catalogue
- type Error
- type Errors
- type LocaleCatalogue
- type Messages
- type PluralRule
- type Translations
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultKey ¶
DefaultKey is the message key of an error that names none: "validate." and its rule, with the kind of value the rule measured when the wording differs by it ("validate.max.string", "validate.required.choice").
func Detach ¶
Detach is a context carrying only what ctx's messages are resolved with — its catalogues and languages — for a value that renders messages after ctx's request has ended.
func Live ¶
Live reports whether the check running with ctx is a live one — the visitor is typing, or left a field — rather than the submit's. A Clean method that is slow or has side effects returns nil early when it is: its error then shows on submit, and stays until the field changes.
func ParseAcceptLanguage ¶
ParseAcceptLanguage is the languages an Accept-Language header names, the preferred first: "sw-TZ, en;q=0.8, *;q=0.1" is ["sw-TZ", "en"]. A wildcard and a language weighted 0 are left out.
func PluralCategory ¶
PluralCategory is the CLDR plural category of n, written with frac digits after its point, in locale's language.
func SetPlural ¶
func SetPlural(lang string, rule PluralRule)
SetPlural sets the plural rule of a language ("ar", "cy"), for one the built-in rules don't cover or cover differently. The built-in rules follow CLDR for English and the languages counting as it does (one for 1, other for the rest: the default), French, Portuguese and Hindi (one for 0 and 1), Russian, Ukrainian and Belarusian, Polish, Czech and Slovak (one, few, many), and the languages with one form (Chinese, Japanese, Korean, Indonesian, Malay, Thai, Vietnamese).
func Text ¶
Text is the message a visitor reads for e, label being its field's label ("Email", "Full name"): e's key looked up in ctx's catalogues, the app's (WithBase), then the default wording; a key none has is the message itself. The label is translated (Translate), then put in the placeholders with e.Params: {label} is the label in a sentence ("full name"), {Label} as it starts one ("Full name"), {n} and the rule's other parameters their values. A plural form chooses its words by a number, in the message's language:
"{Label} must be {n, plural, one {# character} other {# characters}} or less"
It is the one place a message is made, so a catalogue (an app's, a translation's) changes every message the same way: the field's error, the error summary and tests' expectations.
func Translate ¶
Translate is text in ctx's language: the catalogue's entry for it when it has one, text itself otherwise. A label, a hint or a legend is translated by its text ("Full name"), the form components' own words by their keys ("form.problem", "form.optional").
func WithBase ¶
WithBase is ctx resolving message keys with c after its catalogues (WithCatalogue) and before the default wording: an app's catalogue, which a request's own override. Package ui adds its Config.Messages so.
func WithCatalogue ¶
WithCatalogue is ctx resolving message keys with c before the catalogues ctx had, and the default wording.
func WithLive ¶
WithLive is ctx for checks run while the visitor is typing, which Live reports. Package ui sets it; a test of a Clean method may too.
func WithLocale ¶
WithLocale is ctx whose messages are in the languages tags name, the preferred first ("sw", "en-GB"): what Translations look up. Package web sets a request's from its Accept-Language header; a middleware choosing another (a signed-in visitor's setting) sets it before.
Types ¶
type Catalogue ¶
type Catalogue interface {
// Message is key's text, its placeholders ({label}, {n}, plural forms)
// still in it; ok is false when the catalogue has no such key.
Message(ctx context.Context, key string) (text string, ok bool)
}
A Catalogue gives the text of a message key: an app's own wording (Messages), or its translations (Translations).
type Error ¶
Error is one thing wrong with a form: Path names the field ("email", "address.city"; "" for the form as a whole), Rule the rule it broke ("required", "max", "email", "number"; "" for a Clean method's error), Params the rule's values ({"n": "80"}), and Key the message to show — a key of the message catalogue, or the message itself when the catalogue has no such key.
func Errorf ¶
Errorf is an error of the form, or of the field whose Clean method returns it: its Key is format formatted with args. The key is looked up in the message catalogue (see Text); one the catalogue doesn't have is the message as written, so write it as a sentence a visitor can act on: "That email address is already registered", or as a key a catalogue gives the words of: "signup.email.taken".
type LocaleCatalogue ¶
type LocaleCatalogue interface {
Catalogue
// MessageIn is key's text and its language tag ("sw", "pt-BR").
MessageIn(ctx context.Context, key string) (text, locale string, ok bool)
}
A LocaleCatalogue is a Catalogue that knows the language of the text it gives, which chooses the text's plural forms: Translations is one.
type Messages ¶
Messages is a catalogue of texts by key, in one language:
forms.Messages{
"validate.required": "{Label} can't be empty",
"signup.agree": "Accept the terms to continue",
"Full name": "Your name", // a label, by its text
}
A key is a message key — the default wording's ("validate.required", "form.problem", see DefaultMessages), or one an app names in a msg: tag, SetError, Fail or Errorf — or a label's, hint's or legend's text, which the catalogue's entry translates.
func DefaultMessages ¶
func DefaultMessages() Messages
DefaultMessages is a copy of the default wording, by key: what an app's catalogue overrides, and a translation translates.
type PluralRule ¶
A PluralRule is a language's plural category of a number n, written with frac digits after its point: "one", "few", "many" or "other", as the Unicode CLDR names them ("zero" and "two" too, for the languages having them).
type Translations ¶
Translations are catalogues by language tag ("en", "sw", "pt-BR"): a message is looked up in the catalogue of the request's first language that has it (WithLocale), a regional tag falling back to its language's ("pt-BR" to "pt"):
ui.Configure(ui.Config{Messages: forms.Translations{
"sw": forms.Messages{"validate.required": "Weka {label}", "Full name": "Jina kamili"},
"fr": forms.Messages{"validate.required": "Saisissez {label}"},
}})
A key no language of the request's has falls back to the default English wording.