Documentation ¶
Index ¶
- Constants
- func DecodeLen(data []byte) (uint, int)
- func DecodeStrMap(data []byte, yield StrmapYield)
- func EncodeLen(val uint) []byte
- func EncodeStrMap(iter StrmapIter) []byte
- func SprintBytes(data []byte) string
- func SprintMap(data []byte) string
- type FieldHandler
- type Form
- func (self *Form) Clear()
- func (self *Form) HandleInput(w server.ResponseWriter, r *server.Request) bool
- func (self *Form) IsStale(maxAge time.Duration) bool
- func (self *Form) LoadData(data FormData) error
- func (self *Form) MarshalBinary() ([]byte, error)
- func (self *Form) MarshalText() ([]byte, error)
- func (self *Form) SaveData() (FormData, error)
- func (self *Form) UnmarshalBinary(data []byte) error
- func (self *Form) UnmarshalText(data []byte) error
- type FormData
- type SequenceField
- type SmorgasField
- type SmorgasHome
- type StrmapIter
- type StrmapYield
Constants ¶
const FormDone string = "$done"
const FormStart string = ""
Variables ¶
This section is empty.
Functions ¶
func DecodeStrMap ¶
func DecodeStrMap(data []byte, yield StrmapYield)
func EncodeStrMap ¶
func EncodeStrMap(iter StrmapIter) []byte
func SprintBytes ¶
Types ¶
type FieldHandler ¶
Handle the input for a specific field
Return true if a response was sent to w; false otherwise.
type Form ¶
type Form struct { // Map of field handlers Fields map[string]FieldHandler // If Field is unset, use DefaultField DefaultField string // Current field being processed Field string // The last time the form has been handled LastUsed time.Time // The form data Data FormData }
func NewForm ¶
func NewForm(fields map[string]FieldHandler) *Form
Create a new SequenceForm using a map of field Handlers.
FieldHandler is very versatile, but can be difficult to use. There are several form builders that will cover most use cases:
* NewSequenceForm
func NewSequenceForm ¶
func NewSequenceForm(fields []SequenceField) *Form
Create a new Sequential Form using SequenceField
The provided field options are requested in order.
After the form is complete, all the fields will be populated in Data using the key Field from the SequenceField options.
form := NewSequenceForm([]SequenceField{ { Field: "username", Prompt: "Enter your username", }, { Field: "password", Prompt: "Enter your password", Sensitive: true, Redirect: true, }, }) form.UnmarshalBinary(saveData) if form.HandleInput(w, r) { saveData, err = form.MarshalBinary() ... } deleteSaveData() username := form.Data["username"] password := form.Data["password"]
func NewSmorgasForm ¶
func NewSmorgasForm(home SmorgasHome, doneField string, fields []SmorgasField) *Form
Create a new smorgasboard form. This is a form where there is one main page generated by `home`. There are links on this page to the fields of the form in the format `=> {r.Path}?{field}`.
When a link is clicked, the mode is changed and a input response is sent for the corresponding field. Keep in mind that to maintain a good user experience, Field names entered as the value will change the mode to that field. This is so that if a client uses the back button instead of entering nothing to go back, the user interface will still act how they expect it to.
`doneField` is the field name that will mark the form as complete.
func (*Form) Clear ¶
func (self *Form) Clear()
Clear the form data
This is generally used in conjunction with IsStale.
func (*Form) HandleInput ¶
Handle the form input
When true is returned, that means that a response has been sent and that the form is not yet complete and no data should be sent to the client.
When false is returned, that means that nothing has been sent to the client and the form is complete.
After the form handles its input, the form data will have been updated so it should be saved to whichever medium is being used.
func (*Form) IsStale ¶
Check if the form has not used for maxAge time.
An unused form is not considered stale.
func (*Form) MarshalBinary ¶
Marshal the data into binary
func (*Form) MarshalText ¶
Marshal the data into json
func (*Form) UnmarshalBinary ¶
Unmarshal the data from binary
func (*Form) UnmarshalText ¶
Unmarshal the data from json
type FormData ¶
func (FormData) MarshalBinary ¶
Marshal the form data into binary data
func (FormData) MarshalText ¶
Marshal the form data into json
func (FormData) UnmarshalBinary ¶
func (FormData) UnmarshalText ¶
type SequenceField ¶
type SequenceField struct { // The name of the field (Required) Field string // The prompt sent for this field (Required) Prompt string // Whether true 11 (sensitive input) or false 10 (input) should be sent Sensitive bool // Whether the response should first redirect to the current Path // // This effectively erases the query from the clients path before prompting the // next field. // // gemini://my.site/foo/bar // 11 Enter your password // gemini://my.site/foo/bar?mysecretpassword // 30 /foo/bar // gemini://my.site/foo/bar // 20 text/gmini // ... Redirect bool // Validate the Input // // If err is an empty string, then the input is replaced with output and the // next field is requested. // If err is not empty, then the same field is requested with the given error // message Validator func(form *Form, input string) (output, err string) // Perform an action after the validator is called // // Returns the next field to change to. `forms.FormDone` to finish the form. // // If both nextField and err is empty, then the next field is the default // next field. Action func(form *Form, input string) (nextField, err string) }
type SmorgasField ¶
type SmorgasField struct { // The name of the field (Required) Field string // The prompt sent for this Field (Required) Prompt string // Whether true 11 (sensitive input) or false 10 (input) should be sent Sensitive bool // Whether the response should first redirect to the current Path // // This effectively erases the query from the clients path before prompting the // next field. Redirect bool // Validate the Input // // If err is an empty string, then the input is replaced with output and the // next field is requested. // If err is not empty, then the same field is requested with the given error // message Validator func(input string) (output, err string) // A custom handler for the input // // If Validator is not nil, then Validator will be called before Handler and // the transformed input will be provided. // // When Handler is provided, no logic will happen outside of Handler. So it's // the job of Handler to set the field value in form. // // Returns true if a response was made, and an error message if an error // occurred. Handler func(form *Form, input string, w server.ResponseWriter, r *server.Request) (responded bool, error string) // If the validator returns an error, should the response be the home page or // send the prompt again // // true -> send the prompt again // false -> send the home page RepromptOnErr bool }
type SmorgasHome ¶
type SmorgasHome func(form *Form, errors map[string]string, w server.ResponseWriter, r *server.Request) bool
Render the home page of a smorgasboard form.
The data sent to the client should be a gemini page with links to all the available fields. Each of these links should look something like this
=> {r.Path}?{field}
`errors` is a map of field -> error for each field. These should be rendered alongside the link to the matching field.
Return true if a response was sent to the client ¶
type StrmapIter ¶
type StrmapIter func(yield StrmapYield)