Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

test2 source realm

Package test2 is a Google-Forms-shaped questionnaire realm: publish a form, collect responses on chain, read them bac...

Overview

Package test2 is a Google-Forms-shaped questionnaire realm: publish a form, collect responses on chain, read them back rendered — with gnoweb as the only UI.

How it works

The realm renders each form with p/jeronimoalbi/mdform. gnoweb turns that markdown into a real HTML form whose submit builds a /vm.m_call to Submit, mapping every input to the Submit parameter of the same name. A respondent fills the form in a browser, signs with their wallet, and the answers land in realm state. No frontend, no backend, no indexer.

Slugs

A form's ID is a slug chosen at creation — lowercase letters, digits and single hyphens, 3 to 48 characters, unique per realm. It is the URL segment: /r/<ns>/forms:valoper-questionnaire. Response IDs are sequential.

Field encoding

Create takes four parallel, pipe-separated strings so it stays usable from gnokey and gnoweb without structured arguments:

Example
1labels:   "Name|Why gno.land?|Server type"
2kinds:    "text|textarea|select"
3required: "1|1|0"
4options:  "||cloud,on-prem,data-center"

Kinds are text, textarea, number and select. Options are comma-separated and only read for select fields. A form has at most MaxFields (8) fields; Submit accordingly takes eight answer slots, of which the form's field count are read and the rest must be empty. gnoweb passes "" for any parameter the form does not render an input for.

Who pays

Respondents pay the storage deposit for their own answers, which is the spam resistance. Withdraw deletes a response and the chain refunds the deposit to the caller — which is why only the author may withdraw: a deletion by the owner would refund the owner with the respondent's coins.

What is public

Everything. Answers, who gave them, and when are all readable by anyone from realm state and from the transactions themselves. This realm is for information that can be public. Sealed responses would need encryption on the respondent's side before the transaction exists, which gnoweb cannot do on a realm's behalf; that is a deliberate non-goal of v1.

Routes

Example
1/r/<ns>/forms                     index
2/r/<ns>/forms:<id>                a form, fillable
3/r/<ns>/forms:<id>/responses      responses, paginated
4/r/<ns>/forms:<id>/responses.csv  responses as CSV in a code block

Constants 3

const MinSlugLen, MaxSlugLen

1const (
2	MinSlugLen = 3
3	MaxSlugLen = 48
4)
source

Slug rules. A slug is the form's ID and its URL segment, chosen at creation: lowercase letters and digits, single hyphens between words, 3–48 characters.

Variables 1

var ErrFormNotFound, ErrBadSlug, ErrSlugTaken, ErrFormClosed, ErrFormOpen, ErrNotOwner, ErrNoFields, ErrTooManyFields, ErrFieldSpecMismatch, ErrBadFieldKind, ErrSelectNoOptions, ErrEmptyLabel, ErrPipeInField, ErrEmptyTitle, ErrTitleTooLong, ErrDescriptionTooLong, ErrBadDeadline, ErrDeadlinePassed, ErrAlreadyResponded, ErrNoResponse, ErrRequired, ErrNotANumber, ErrNotAnOption, ErrAnswerTooLong, ErrTooManyAnswers, ErrNotUserCall

 1var (
 2	ErrFormNotFound       = errors.New("form not found")
 3	ErrBadSlug            = errors.New("slug must be 3-48 lowercase letters, digits and single hyphens, e.g. valoper-questionnaire")
 4	ErrSlugTaken          = errors.New("a form with this slug already exists")
 5	ErrFormClosed         = errors.New("form is closed")
 6	ErrFormOpen           = errors.New("form is already open")
 7	ErrNotOwner           = errors.New("caller is not the form owner")
 8	ErrNoFields           = errors.New("a form needs at least one field")
 9	ErrTooManyFields      = errors.New("a form can have at most 8 fields")
10	ErrFieldSpecMismatch  = errors.New("labels, kinds and required must describe the same number of fields")
11	ErrBadFieldKind       = errors.New("field kind must be one of text, textarea, number, select")
12	ErrSelectNoOptions    = errors.New("a select field needs at least one option")
13	ErrEmptyLabel         = errors.New("field label cannot be empty")
14	ErrPipeInField        = errors.New("field labels and options cannot contain |")
15	ErrEmptyTitle         = errors.New("form title cannot be empty")
16	ErrTitleTooLong       = errors.New("form title is too long")
17	ErrDescriptionTooLong = errors.New("form description is too long")
18	ErrBadDeadline        = errors.New("deadline must be a future chain height or 0")
19	ErrDeadlinePassed     = errors.New("form deadline has passed")
20	ErrAlreadyResponded   = errors.New("this address has already responded to this form")
21	ErrNoResponse         = errors.New("no response from this address to withdraw")
22	ErrRequired           = errors.New("required field is empty")
23	ErrNotANumber         = errors.New("field expects a number")
24	ErrNotAnOption        = errors.New("value is not one of the select options")
25	ErrAnswerTooLong      = errors.New("answer exceeds the field's maximum length")
26	ErrTooManyAnswers     = errors.New("more answers than the form has fields")
27	ErrNotUserCall        = errors.New("this function must be called by a user account")
28)
source

Functions 11

func Close

crossing Action
1func Close(cur realm, id string)
source

Close stops a form from accepting responses. Owner only.

func Create

crossing Action
1func Create(cur realm, slug, title, description, labels, kinds, required, options string, onePerAddr bool, deadline int64) string
source

Create publishes a new form under slug, which becomes its ID and its URL segment (/r/<ns>/forms:<slug>). Slugs are unique per realm.

Fields are described by four parallel, pipe-separated strings so the call stays usable from gnokey and gnoweb without structured arguments:

Example
1labels:   "Name|Why gno.land?|Server type"
2kinds:    "text|textarea|select"
3required: "1|1|0"
4options:  "||cloud,on-prem,data-center"   (comma-separated; only select uses it)

deadline is a chain height after which the form stops accepting responses, or 0 for none. onePerAddr limits each address to a single response.

func CreateForm

crossing Action
 1func CreateForm(cur realm,
 2	slug, title, description string,
 3	l1, k1, r1, o1 string,
 4	l2, k2, r2, o2 string,
 5	l3, k3, r3, o3 string,
 6	l4, k4, r4, o4 string,
 7	l5, k5, r5, o5 string,
 8	l6, k6, r6, o6 string,
 9	l7, k7, r7, o7 string,
10	l8, k8, r8, o8 string,
11	onePerAddr, deadline string,
12) string
source

CreateForm is Create for the browser: the index page renders it as a gnoweb form, one row per field, so nothing has to be typed into the wallet.

Every parameter is a string because gnoweb submits "" for an empty or unchecked input, and "" is not a bool or an int64 as far as the VM is concerned. Checkboxes send "1" when ticked. Blank rows are skipped; a row with an empty kind is text. deadline "" means none.

func Render

1func Render(path string) string
source

Render routes:

Example
1/r/<ns>/forms                     index of forms
2/r/<ns>/forms:<id>                a form, fillable in gnoweb
3/r/<ns>/forms:<id>/responses      its responses, paginated
4/r/<ns>/forms:<id>/responses.csv  its responses as CSV

func Reopen

crossing Action
1func Reopen(cur realm, id string)
source

Reopen lets a closed form accept responses again. Owner only. A form whose deadline has passed stays closed regardless.

func ResponseCount

Action
1func ResponseCount(id string) int
source

ResponseCount returns the number of responses a form has, or 0 if the form does not exist.

func Submit

crossing Action
1func Submit(cur realm, id string, a1, a2, a3, a4, a5, a6, a7, a8 string)
source

Submit records a response to a form. Answers a1..a8 align with the form's fields in order; slots beyond the form's field count must be empty.

gnoweb builds this call from the rendered form: each input is named after the parameter it fills, and parameters with no input arrive as "".

The respondent pays the storage deposit for their own answers, and gets it back on Withdraw.

func TransferOwnership

crossing Action
1func TransferOwnership(cur realm, id string, to address)
source

TransferOwnership hands a form to another address. Owner only.

func Withdraw

crossing Action
1func Withdraw(cur realm, id string)
source

Withdraw deletes the caller's response to a form. The storage deposit the answers were holding is refunded to the caller by the chain.

Only the author can withdraw. Owners cannot delete responses: the refund goes to whoever deletes, which would hand the owner the respondent's deposit.

Types 4

type Field

struct
1type Field struct {
2	Label    string
3	Kind     FieldKind
4	Required bool
5	Options  []string // select only
6}
source

Field is one question on a form.

Methods on Field

func MaxLen

method on Field
1func (f Field) MaxLen() int
source

MaxLen is the longest answer the field accepts.

type FieldKind

ident
1type FieldKind string
source

FieldKind is the input type a field renders as, and the validation it gets.

type Form

struct
 1type Form struct {
 2	ID          string // the slug
 3	Title       string
 4	Description string
 5	Fields      []Field
 6	OnePerAddr  bool
 7	Deadline    int64 // chain height; 0 means none
 8	Closed      bool
 9	CreatedAt   int64
10
11	owner     *ownable.Ownable
12	responses *avl.Tree // response id -> *Response
13	byAddr    *avl.Tree // author address -> response id
14}
source

Form is a published questionnaire and its responses.

Methods on Form

func IsOpen

method on Form
1func (f *Form) IsOpen(height int64) bool
source

IsOpen reports whether the form accepts submissions at the given height.

func Owner

method on Form
1func (f *Form) Owner() address
source

Owner returns the form owner's address.

func ResponseCount

method on Form
1func (f *Form) ResponseCount() int
source

ResponseCount returns how many responses the form currently holds.

type Response

struct
1type Response struct {
2	ID      seqid.ID
3	Form    string // the form slug
4	Author  address
5	Height  int64
6	Answers []string
7}
source

Response is one submission to a form. Answers align with Form.Fields.

Imports 17

Source Files 7