docs(cabana): document preset on mltext fields
- schema_types.go and the form-schema swag description name text or mltext - regenerated admin/openapi/admin.json and admin/src/api/schema.d.ts - README and docs/backend/forms.md describe the per-locale rules
This commit is contained in:
@@ -843,7 +843,7 @@
|
|||||||
"$ref": "#/components/schemas/cabana.FieldPreset"
|
"$ref": "#/components/schemas/cabana.FieldPreset"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Preset makes a text field follow another field of the form while the\nadministrator has not edited it, on create only (fields.yaml preset)."
|
"description": "Preset makes a text or mltext field follow another text or mltext\nfield of the form while the administrator has not edited it, on create\nonly (fields.yaml preset). An mltext pair follows per locale; a mixed\npair follows the active locale."
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"description": "Prompt is the upload button text, localized per request.",
|
"description": "Prompt is the upload button text, localized per request.",
|
||||||
@@ -3488,7 +3488,7 @@
|
|||||||
},
|
},
|
||||||
"/{vendor}/{plugin}/{controller}/schema/form": {
|
"/{vendor}/{plugin}/{controller}/schema/form": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text field names the field it follows on the create form (type slug or exact) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.",
|
"description": "The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text or mltext field names the text or mltext field it follows on the create form (type slug or exact; an mltext pair follows per locale) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "Vendor",
|
"description": "Vendor",
|
||||||
|
|||||||
8
admin/src/api/schema.d.ts
vendored
8
admin/src/api/schema.d.ts
vendored
@@ -1305,7 +1305,7 @@ export interface paths {
|
|||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Admin form schema
|
* Admin form schema
|
||||||
* @description The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text field names the field it follows on the create form (type slug or exact) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.
|
* @description The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text or mltext field names the text or mltext field it follows on the create form (type slug or exact; an mltext pair follows per locale) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.
|
||||||
*/
|
*/
|
||||||
get: {
|
get: {
|
||||||
parameters: {
|
parameters: {
|
||||||
@@ -4565,8 +4565,10 @@ export interface components {
|
|||||||
*/
|
*/
|
||||||
permissionOptions?: components["schemas"]["cabana.PermissionOption"][];
|
permissionOptions?: components["schemas"]["cabana.PermissionOption"][];
|
||||||
/**
|
/**
|
||||||
* @description Preset makes a text field follow another field of the form while the
|
* @description Preset makes a text or mltext field follow another text or mltext
|
||||||
* administrator has not edited it, on create only (fields.yaml preset).
|
* field of the form while the administrator has not edited it, on create
|
||||||
|
* only (fields.yaml preset). An mltext pair follows per locale; a mixed
|
||||||
|
* pair follows the active locale.
|
||||||
*/
|
*/
|
||||||
preset?: components["schemas"]["cabana.FieldPreset"];
|
preset?: components["schemas"]["cabana.FieldPreset"];
|
||||||
/** @description Prompt is the upload button text, localized per request. */
|
/** @description Prompt is the upload button text, localized per request. */
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ The WinterCMS widgets that are not in this list (the rich editor, the code edito
|
|||||||
|
|
||||||
### Field options
|
### Field options
|
||||||
|
|
||||||
A field takes `label`, `comment`, `type`, `required`, `default`, `tab`, `span` (`left`, `right`, `full`, `auto`, `row`), `size` (`tiny`, `small`, `large`, `huge`, `giant`), `context`, `attributes` (scalar HTML attributes for the input), `options` and `emptyOption`, plus `nameFrom` and `relation` on relation fields and `preset` on text fields. WinterCMS keys outside this set, such as `readOnly`, `disabled`, `trigger` or `dependsOn`, are refused.
|
A field takes `label`, `comment`, `type`, `required`, `default`, `tab`, `span` (`left`, `right`, `full`, `auto`, `row`), `size` (`tiny`, `small`, `large`, `huge`, `giant`), `context`, `attributes` (scalar HTML attributes for the input), `options` and `emptyOption`, plus `nameFrom` and `relation` on relation fields and `preset` on text and mltext fields. WinterCMS keys outside this set, such as `readOnly`, `disabled`, `trigger` or `dependsOn`, are refused.
|
||||||
|
|
||||||
`context: update` shows a field only on the update form, and `context: create` only on the create form; a list of contexts is also accepted, and `context: preview` shows a field only on the [preview screen](#preview-screen). The context is enforced on the server too: a field that is hidden on a form is never written by that form's save, whatever the request body holds.
|
`context: update` shows a field only on the update form, and `context: create` only on the create form; a list of contexts is also accepted, and `context: preview` shows a field only on the [preview screen](#preview-screen). The context is enforced on the server too: a field that is hidden on a form is never written by that form's save, whatever the request body holds.
|
||||||
|
|
||||||
`preset` makes a `text` field follow another text field of the same form while the administrator has not edited it, as a slug field follows a title. It is the source field's name, or a mapping with `field` and `type`:
|
`preset` makes a `text` or `mltext` field follow another text or mltext field of the same form while the administrator has not edited it, as a slug field follows a title. It is the source field's name, or a mapping with `field` and `type`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
slug:
|
slug:
|
||||||
@@ -120,7 +120,11 @@ slug:
|
|||||||
type: slug
|
type: slug
|
||||||
```
|
```
|
||||||
|
|
||||||
`type: slug` (the default, and what the short form `preset: title` means) lower-cases the text and turns every run of characters other than ASCII letters and digits into one hyphen; `type: exact` copies the text. The admin SPA applies it on the create form only, and the first manual edit of the field stops it. The server does not fill the field: a model that needs a slug even when none is sent sets it in its own `BeforeValidate`. The schema reports the key as `preset` (a `cabana.FieldPreset`). A `preset` on another field type, an unknown type, or a source that is not a text field of the same form stops the start-up, and the key is not accepted on settings forms or relation forms.
|
`type: slug` (the default, and what the short form `preset: title` means) lower-cases the text and turns every run of characters other than ASCII letters and digits into one hyphen; `type: exact` copies the text. The admin SPA applies it on the create form only, and the first manual edit of the field stops it. The server does not fill the field: a model that needs a slug even when none is sent sets it in its own `BeforeValidate`. The schema reports the key as `preset` (a `cabana.FieldPreset`).
|
||||||
|
|
||||||
|
Multilingual pairs follow the locale the administrator works in. An `mltext` target follows an `mltext` source per locale: typing in one locale of the source rewrites the same locale of the target, and a hand edit of one locale of the target stops only that locale. An `mltext` source drives a `text` target from the active locale. A `text` source fills only the active locale of an `mltext` target, so locales nobody looked at stay empty.
|
||||||
|
|
||||||
|
A `preset` on another field type (`mlmarkdown` included), an unknown type, or a source that is not a text or mltext field of the same form stops the start-up, and the key is not accepted on settings forms or relation forms.
|
||||||
|
|
||||||
## Date pickers
|
## Date pickers
|
||||||
|
|
||||||
@@ -325,7 +329,7 @@ func (MembersController) AdminSetPermissionValues(_ context.Context, field strin
|
|||||||
|
|
||||||
`type: markdown` edits markdown source on a host text column. The admin SPA shows a source editor with a Preview toggle. When Preview opens, and again shortly after the source changes while it is open, the SPA posts the field's source (the active locale's text for `mlmarkdown`) to the preview route below and renders only the server's answer; when the output is refused it shows the server's message as text. The server renders through `cabana.RenderMarkdown`, which uses the pinned goldmark engine without unsafe HTML. Output that still contains a script or iframe tag, an event handler, or a javascript, vbscript or data URL is refused, so translated raw HTML cannot become executable preview content. `POST <prefix>/api/v1/markdown/preview` renders a `{markdown}` source through `cabana.RenderMarkdown` for any signed-in administrator and answers `{html}`, or a 422 `validation_failed` on `markdown` when the output is refused.
|
`type: markdown` edits markdown source on a host text column. The admin SPA shows a source editor with a Preview toggle. When Preview opens, and again shortly after the source changes while it is open, the SPA posts the field's source (the active locale's text for `mlmarkdown`) to the preview route below and renders only the server's answer; when the output is refused it shows the server's message as text. The server renders through `cabana.RenderMarkdown`, which uses the pinned goldmark engine without unsafe HTML. Output that still contains a script or iframe tag, an event handler, or a javascript, vbscript or data URL is refused, so translated raw HTML cannot become executable preview content. `POST <prefix>/api/v1/markdown/preview` renders a `{markdown}` source through `cabana.RenderMarkdown` for any signed-in administrator and answers `{html}`, or a 422 `validation_failed` on `markdown` when the output is refused.
|
||||||
|
|
||||||
`type: mltext` and `type: mlmarkdown` reuse the ordinary text and markdown editors with a locale selector. `mlmarkdown` composes the markdown control rather than a second parser. Each ML field shows its own selector; changing one selector changes every ML control on the form. Selector options come from `cabana.FormMeta.EnabledLocales` on the form schema (filled from `cabana.TranslationWriter.EnabledLocales` after Lookup; `FormSchema.Localize` stays cache-only). Create seeds `{[code]: ""}` for every enabled code. A GET or save of a host scalar is merged onto that seed so sibling locales are not dropped.
|
`type: mltext` and `type: mlmarkdown` reuse the ordinary text and markdown editors with a locale selector. `mlmarkdown` composes the markdown control rather than a second parser. Each ML field shows its own selector; changing one selector changes every ML control on the form. Selector options come from `cabana.FormMeta.EnabledLocales` on the form schema (filled from `cabana.TranslationWriter.EnabledLocales` after Lookup; `FormSchema.Localize` stays cache-only). Create seeds `{[code]: ""}` for every enabled code. A GET or save of a host scalar is merged onto that seed so sibling locales are not dropped. An `mltext` field can carry a `preset`; it follows per locale as described under [Field options](#field-options).
|
||||||
|
|
||||||
The save body sends every locale as a JSON object of code to string. Extra YAML keys are not accepted: the types reuse `label`, `comment`, `span`, `size`, `required`, `tab` and `context`. An unknown type such as `mlunknown` stops the start-up.
|
The save body sends every locale as a JSON object of code to string. Extra YAML keys are not accepted: the types reuse `label`, `comment`, `span`, `size`, `required`, `tab` and `context`. An unknown type such as `mlunknown` stops the start-up.
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Schema-driven admin backend that compiles WinterCMS-style YAML list, form, filte
|
|||||||
- Form-only fields: a controller implementing `pact.FormVirtualFields` lists fields of its `fields.yaml` that are not columns of the form. They are exempt from the column binding, never filled into the model and never part of a record response; the values an administrator submits reach the Form hooks through `cabana.VirtualFieldsFromContext`, only for fields whose `context` allows the operation, and a nested value is a 422 on the field. `type: password` is a masked field that must be listed this way, so a password is sent in a save body and never comes back. A controller implementing `pact.FormRules` supplies the validation rules per operation (`create` or `update`), which replace the model's `Rules()` for admin saves; a rule on a virtual field is checked against the submitted value, never against a model column of the same name. Neither is available on settings forms or relation forms.
|
- Form-only fields: a controller implementing `pact.FormVirtualFields` lists fields of its `fields.yaml` that are not columns of the form. They are exempt from the column binding, never filled into the model and never part of a record response; the values an administrator submits reach the Form hooks through `cabana.VirtualFieldsFromContext`, only for fields whose `context` allows the operation, and a nested value is a 422 on the field. `type: password` is a masked field that must be listed this way, so a password is sent in a save body and never comes back. A controller implementing `pact.FormRules` supplies the validation rules per operation (`create` or `update`), which replace the model's `Rules()` for admin saves; a rule on a virtual field is checked against the submitted value, never against a model column of the same name. Neither is available on settings forms or relation forms.
|
||||||
- Permission editor: a `type: permissioneditor` field with `mode: radio` (allow `1`, inherit, deny `-1`) or `mode: checkbox` (allow `1`) edits a record's permission set as a JSON object of code to integer. The controller implements `cabana.PermissionEditorProvider`: it returns the offered `cabana.PermissionOption` list per request (served on the field as `permissionOptions`, with `locked` for permissions the administrator may not change) and reads and stores the record's values, so the storage shape is the plugin's. A save answers 422 on the field for a value that is not an object of integers, a code that is not offered or a value outside the mode's set, and 403 `forbidden` when a locked code's value changes; stored codes that are not offered are kept. The widget fill contract is unchanged: a widget still writes scalar fields only.
|
- Permission editor: a `type: permissioneditor` field with `mode: radio` (allow `1`, inherit, deny `-1`) or `mode: checkbox` (allow `1`) edits a record's permission set as a JSON object of code to integer. The controller implements `cabana.PermissionEditorProvider`: it returns the offered `cabana.PermissionOption` list per request (served on the field as `permissionOptions`, with `locked` for permissions the administrator may not change) and reads and stores the record's values, so the storage shape is the plugin's. A save answers 422 on the field for a value that is not an object of integers, a code that is not offered or a value outside the mode's set, and 403 `forbidden` when a locked code's value changes; stored codes that are not offered are kept. The widget fill contract is unchanged: a widget still writes scalar fields only.
|
||||||
- Markdown and multilingual fields: `type: markdown` edits source on a host text column; `cabana.RenderMarkdown` turns that source into HTML with the pinned goldmark engine and no unsafe HTML, and leftover script or iframe tags, event handlers, or javascript, vbscript or data URLs are rejected; the admin form preview renders through it via POST `/markdown/preview`. `type: mltext` and `type: mlmarkdown` take a JSON object of locale code to string. The form schema's `cabana.FormMeta.EnabledLocales` lists every enabled code when a `cabana.TranslationWriter` is published; create seeds an empty string per code, and Show/save replace the host scalar with that map via `hydrateMLRecord` and `TranslationWriter.TranslatedExact` (missing non-default codes stay empty; D-11 fallback is not applied). A GET host string is merged onto the seed so sibling locales are not dropped. The default locale fills the host column; other locales reach a plugin-published `cabana.TranslationWriter` after the host row has a primary key, still inside the controller's permissioned save transaction. Relation-child create, update and show on `cabana.RelationService` use the same lift, apply and `hydrateMLRecord` path as controller save, still with no standalone translate-write route. An unknown field type, including an unknown `ml*` type, fails boot.
|
- Markdown and multilingual fields: `type: markdown` edits source on a host text column; `cabana.RenderMarkdown` turns that source into HTML with the pinned goldmark engine and no unsafe HTML, and leftover script or iframe tags, event handlers, or javascript, vbscript or data URLs are rejected; the admin form preview renders through it via POST `/markdown/preview`. `type: mltext` and `type: mlmarkdown` take a JSON object of locale code to string. The form schema's `cabana.FormMeta.EnabledLocales` lists every enabled code when a `cabana.TranslationWriter` is published; create seeds an empty string per code, and Show/save replace the host scalar with that map via `hydrateMLRecord` and `TranslationWriter.TranslatedExact` (missing non-default codes stay empty; D-11 fallback is not applied). A GET host string is merged onto the seed so sibling locales are not dropped. The default locale fills the host column; other locales reach a plugin-published `cabana.TranslationWriter` after the host row has a primary key, still inside the controller's permissioned save transaction. Relation-child create, update and show on `cabana.RelationService` use the same lift, apply and `hydrateMLRecord` path as controller save, still with no standalone translate-write route. An unknown field type, including an unknown `ml*` type, fails boot.
|
||||||
- Preset fields: `preset` on a `type: text` field (a source field name, or a mapping with `field` and `type`, `slug` or `exact`) makes the field follow another text field of the same form on the create screen until the administrator edits it. The schema reports it as `preset` (`cabana.FieldPreset`); the server does not fill the field.
|
- Preset fields: `preset` on a `type: text` or `type: mltext` field (a source field name, or a mapping with `field` and `type`, `slug` or `exact`) makes the field follow another text or mltext field of the same form on the create screen until the administrator edits it, per locale for an mltext pair. The schema reports it as `preset` (`cabana.FieldPreset`); the server does not fill the field.
|
||||||
- Server-rendered partials: `headerPartial: <name>` in `config_list.yaml` (a strip above the list) and `type: partial` with `path: <name>` in `fields.yaml` render the template `{ConfigDir}/_<name>.htm` with `html/template` against a view model from the controller's `pact.AdminPartialData`. The result reaches the SPA as an allowlisted node tree, never as an HTML string. A missing or unparsable template, a free-form path or a controller without `pact.AdminPartialData` fails boot.
|
- Server-rendered partials: `headerPartial: <name>` in `config_list.yaml` (a strip above the list) and `type: partial` with `path: <name>` in `fields.yaml` render the template `{ConfigDir}/_<name>.htm` with `html/template` against a view model from the controller's `pact.AdminPartialData`. The result reaches the SPA as an allowlisted node tree, never as an HTML string. A missing or unparsable template, a free-form path or a controller without `pact.AdminPartialData` fails boot.
|
||||||
- Date pickers: a `type: datepicker` field in `fields.yaml` edits a date (`mode: date`, a `lagoon.Date` column), a date and time (`mode: datetime`, the default, a `time.Time` column stored in UTC) or a time of day (`mode: time`, a `lagoon.TimeOfDay` column); pointers to the three types make the value optional. It accepts WinterCMS's `mode`, `format` (a PHP `date()` format, served also as `displayFormat` in the SPA's tokens), `minDate`, `maxDate`, `yearRange`, `firstDay`, `twelveHour` and `ignoreTimezone`; any other key, a format letter with no equivalent, bounds on `mode: time`, `ignoreTimezone` outside `mode: datetime` or a column whose Go type does not match the mode fails boot. The save rechecks `minDate` and `maxDate` on the calendar date and answers 422 on the field. List columns take `type: date` and `type: time` for these columns; when `type` is omitted, a `time.Time` column is compiled as `datetime`, a `lagoon.Date` column as `date` and a `lagoon.TimeOfDay` column as `time`. A struct column that implements `sql.Scanner` or `driver.Valuer` is never taken for a relation.
|
- Date pickers: a `type: datepicker` field in `fields.yaml` edits a date (`mode: date`, a `lagoon.Date` column), a date and time (`mode: datetime`, the default, a `time.Time` column stored in UTC) or a time of day (`mode: time`, a `lagoon.TimeOfDay` column); pointers to the three types make the value optional. It accepts WinterCMS's `mode`, `format` (a PHP `date()` format, served also as `displayFormat` in the SPA's tokens), `minDate`, `maxDate`, `yearRange`, `firstDay`, `twelveHour` and `ignoreTimezone`; any other key, a format letter with no equivalent, bounds on `mode: time`, `ignoreTimezone` outside `mode: datetime` or a column whose Go type does not match the mode fails boot. The save rechecks `minDate` and `maxDate` on the calendar date and answers 422 on the field. List columns take `type: date` and `type: time` for these columns; when `type` is omitted, a `time.Time` column is compiled as `datetime`, a `lagoon.Date` column as `date` and a `lagoon.TimeOfDay` column as `time`. A struct column that implements `sql.Scanner` or `driver.Valuer` is never taken for a relation.
|
||||||
- File uploads: a `type: fileupload` field in `fields.yaml` edits an attachOne or attachMany relation the record model declares through `attach.HasRelations` (its `AttachRelations` method) next to `attach.Owner`. The field accepts WinterCMS's `mode` (`image` or `file`), `fileTypes`, `mimeTypes`, `maxFilesize` (megabytes), `maxFiles` (attachMany only), `imageWidth`, `imageHeight`, `thumbOptions` (only `mode`: `auto`, `exact`, `crop` or `fit`), `useCaption` and `prompt`; any other key, an image-mode file type outside jpg, jpeg, png, gif and webp, a name that is not a declared relation or a `maxFilesize` whose file plus 64 KiB of multipart framing exceeds `http.body_limits.upload_bytes` fails boot. Uploads and removals are deferred, as in WinterCMS: the SPA sends a random form session key in the `X-Session-Key` header (`cabana.SessionKeyHeader`) with every file call and with the save, the server keeps the pending work in `deferred_bindings` against that key and the signed-in administrator, and the record's next create or update save applies it inside its transaction. A retry of the same upload may send `X-Upload-Id` so the server returns the already stored file. A save that fails with 422 keeps the pending uploads; another administrator's key matches nothing. The upload route caps the request body at the smaller of `http.body_limits.upload_bytes` and `maxFilesize` plus 64 KiB and answers 413 `payload_too_large` past it; the size, type and image checks run on the server (through `attach.Store`) and answer 422 on the field. A file list (`cabana.FileItem`) carries `url` and `thumb_url` only for a public relation.
|
- File uploads: a `type: fileupload` field in `fields.yaml` edits an attachOne or attachMany relation the record model declares through `attach.HasRelations` (its `AttachRelations` method) next to `attach.Owner`. The field accepts WinterCMS's `mode` (`image` or `file`), `fileTypes`, `mimeTypes`, `maxFilesize` (megabytes), `maxFiles` (attachMany only), `imageWidth`, `imageHeight`, `thumbOptions` (only `mode`: `auto`, `exact`, `crop` or `fit`), `useCaption` and `prompt`; any other key, an image-mode file type outside jpg, jpeg, png, gif and webp, a name that is not a declared relation or a `maxFilesize` whose file plus 64 KiB of multipart framing exceeds `http.body_limits.upload_bytes` fails boot. Uploads and removals are deferred, as in WinterCMS: the SPA sends a random form session key in the `X-Session-Key` header (`cabana.SessionKeyHeader`) with every file call and with the save, the server keeps the pending work in `deferred_bindings` against that key and the signed-in administrator, and the record's next create or update save applies it inside its transaction. A retry of the same upload may send `X-Upload-Id` so the server returns the already stored file. A save that fails with 422 keeps the pending uploads; another administrator's key matches nothing. The upload route caps the request body at the smaller of `http.body_limits.upload_bytes` and `maxFilesize` plus 64 KiB and answers 413 `payload_too_large` past it; the size, type and image checks run on the server (through `attach.Store`) and answer 422 on the field. A file list (`cabana.FileItem`) carries `url` and `thumb_url` only for a public relation.
|
||||||
@@ -222,7 +222,7 @@ func (p *Plugin) AdminFS() fs.FS { return adminFS }
|
|||||||
| `cabana.TranslationWriter.TranslatedExact` | Returns the stored value for a field in a locale without D-11 fallback; `ok` is false when the non-default key is missing. The default locale still reads the host column. |
|
| `cabana.TranslationWriter.TranslatedExact` | Returns the stored value for a field in a locale without D-11 fallback; `ok` is false when the non-default key is missing. The default locale still reads the host column. |
|
||||||
| `hydrateMLRecord` | Replaces host scalars of declared `mltext`/`mlmarkdown` fields on a Show/save record — host CRUD and relation-child create, update and show — with a locale map for every enabled code. Not used from list row projection. |
|
| `hydrateMLRecord` | Replaces host scalars of declared `mltext`/`mlmarkdown` fields on a Show/save record — host CRUD and relation-child create, update and show — with a locale map for every enabled code. Not used from list row projection. |
|
||||||
| `cabana.RenderMarkdown` | Converts markdown source to HTML with the pinned goldmark engine without unsafe HTML; leftover script or iframe tags, event handlers, or javascript, vbscript or data URLs are rejected. |
|
| `cabana.RenderMarkdown` | Converts markdown source to HTML with the pinned goldmark engine without unsafe HTML; leftover script or iframe tags, event handlers, or javascript, vbscript or data URLs are rejected. |
|
||||||
| `cabana.FieldPreset` | A text field's `preset` in the form schema: the source field and the type, `slug` or `exact`. |
|
| `cabana.FieldPreset` | A text or mltext field's `preset` in the form schema: the source field and the type, `slug` or `exact`. |
|
||||||
| `cabana.WriteData` / `cabana.WriteError` / `cabana.WriteErrorDetails` | Write the admin success and error envelopes. |
|
| `cabana.WriteData` / `cabana.WriteError` / `cabana.WriteErrorDetails` | Write the admin success and error envelopes. |
|
||||||
| `cabana.ValidationError` / `cabana.ListValidationError` | Field-level `validation_failed` errors. A `pact.AdminAction` may return a `cabana.ValidationError` to answer 422. |
|
| `cabana.ValidationError` / `cabana.ListValidationError` | Field-level `validation_failed` errors. A `pact.AdminAction` may return a `cabana.ValidationError` to answer 422. |
|
||||||
| `cabana.ForbiddenError` | A write controller code refuses: a hook or an action returns it and the route answers 403 `forbidden` with its localized `Message` and `Details`; the transaction is rolled back. |
|
| `cabana.ForbiddenError` | A write controller code refuses: a hook or an action returns it and the route answers 403 `forbidden` with its localized `Message` and `Details`; the transaction is rolled back. |
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ func AdminListSchema() {}
|
|||||||
// AdminFormSchema documents the form schema route.
|
// AdminFormSchema documents the form schema route.
|
||||||
//
|
//
|
||||||
// @Summary Admin form schema
|
// @Summary Admin form schema
|
||||||
// @Description The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text field names the field it follows on the create form (type slug or exact) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.
|
// @Description The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text or mltext field names the text or mltext field it follows on the create form (type slug or exact; an mltext pair follows per locale) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.
|
||||||
// @Tags admin
|
// @Tags admin
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Security BackendBearer
|
// @Security BackendBearer
|
||||||
|
|||||||
@@ -309,8 +309,10 @@ type FormField struct {
|
|||||||
// managed before the record is first saved (RelationSchema.Deferrable):
|
// managed before the record is first saved (RelationSchema.Deferrable):
|
||||||
// the SPA shows it on the create screen.
|
// the SPA shows it on the create screen.
|
||||||
Deferrable bool `json:"deferrable,omitempty"`
|
Deferrable bool `json:"deferrable,omitempty"`
|
||||||
// Preset makes a text field follow another field of the form while the
|
// Preset makes a text or mltext field follow another text or mltext
|
||||||
// administrator has not edited it, on create only (fields.yaml preset).
|
// field of the form while the administrator has not edited it, on create
|
||||||
|
// only (fields.yaml preset). An mltext pair follows per locale; a mixed
|
||||||
|
// pair follows the active locale.
|
||||||
Preset *FieldPreset `json:"preset,omitempty"`
|
Preset *FieldPreset `json:"preset,omitempty"`
|
||||||
// PermissionOptions are the permissions a `type: permissioneditor` field
|
// PermissionOptions are the permissions a `type: permissioneditor` field
|
||||||
// offers the requesting administrator, in display order. They are filled
|
// offers the requesting administrator, in display order. They are filled
|
||||||
@@ -320,11 +322,12 @@ type FormField struct {
|
|||||||
optionsMethod string
|
optionsMethod string
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldPreset is a text field's `preset`: Field names the text field of the
|
// FieldPreset is a text or mltext field's `preset`: Field names the text or
|
||||||
// same form whose value it follows, and Type is how the value is taken over,
|
// mltext field of the same form whose value it follows, and Type is how the
|
||||||
// slug (lower-case ASCII with hyphens) or exact (the same text). The admin SPA
|
// value is taken over, slug (lower-case ASCII with hyphens) or exact (the same
|
||||||
// applies it on the create form until the administrator edits the field; the
|
// text). The admin SPA applies it on the create form until the administrator
|
||||||
// server does not fill the field.
|
// edits the field; an mltext pair follows per locale and a mixed pair follows
|
||||||
|
// the active locale. The server does not fill the field.
|
||||||
type FieldPreset struct {
|
type FieldPreset struct {
|
||||||
Field string `json:"field"`
|
Field string `json:"field"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
|||||||
Reference in New Issue
Block a user