- Strict config_form and fields documents keep source order and JSON scalar types - Unknown keys, partials, path escape, and a mismatched modelClass fail activation with plugin context - List-only controllers still activate when config_form.yaml is absent
72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
package cabana
|
|
|
|
import "encoding/json"
|
|
|
|
// FormSchema is the locale-neutral form contract compiled once at boot.
|
|
// Display strings stay as source keys until a request localizes a copy.
|
|
type FormSchema struct {
|
|
Name string `json:"name,omitempty"`
|
|
ModelClass string `json:"modelClass,omitempty"`
|
|
Fields []FormField `json:"fields"`
|
|
}
|
|
|
|
// FormField is one Winter field in source order. JSON keys keep Winter spelling.
|
|
type FormField struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Label string `json:"label,omitempty"`
|
|
Comment string `json:"comment,omitempty"`
|
|
Span string `json:"span,omitempty"`
|
|
Tab string `json:"tab,omitempty"`
|
|
Size string `json:"size,omitempty"`
|
|
Context *fieldContext `json:"context,omitempty"`
|
|
NameFrom string `json:"nameFrom,omitempty"`
|
|
EmptyOption string `json:"emptyOption,omitempty"`
|
|
Relation string `json:"relation,omitempty"`
|
|
Required bool `json:"required,omitempty"`
|
|
Default *jsonScalar `json:"default,omitempty"`
|
|
Attributes map[string]jsonScalar `json:"attributes,omitempty"`
|
|
Options []FormOption `json:"options,omitempty"`
|
|
|
|
optionsMethod string
|
|
}
|
|
|
|
// FormOption is one dropdown choice. Value keeps the YAML scalar's JSON type.
|
|
type FormOption struct {
|
|
Value jsonScalar `json:"value"`
|
|
Label string `json:"label"`
|
|
}
|
|
|
|
// jsonScalar is a JSON scalar that still emits false, 0, and empty string.
|
|
type jsonScalar struct {
|
|
raw json.RawMessage
|
|
}
|
|
|
|
func (s jsonScalar) MarshalJSON() ([]byte, error) {
|
|
if len(s.raw) == 0 {
|
|
return []byte("null"), nil
|
|
}
|
|
return s.raw, nil
|
|
}
|
|
|
|
// fieldContext preserves a single Winter context string or a source-ordered list.
|
|
type fieldContext struct {
|
|
single bool
|
|
values []string
|
|
}
|
|
|
|
func (c fieldContext) MarshalJSON() ([]byte, error) {
|
|
if c.single {
|
|
text := ""
|
|
if len(c.values) > 0 {
|
|
text = c.values[0]
|
|
}
|
|
return json.Marshal(text)
|
|
}
|
|
values := c.values
|
|
if values == nil {
|
|
values = []string{}
|
|
}
|
|
return json.Marshal(values)
|
|
}
|