ADR-230: An alternative text for one use of an image
- Status
-
Accepted
- Date
-
2026-10-25
- Amends
-
ADR-198 (the rights
replace_asks, for a content element that is an inline child), ADR-212 (the rightsfile_ reference attach_asks, for a record that is an inline child)file_ to_ record - Authors
-
Netresearch DTT GmbH
Context
An alternative text belongs to one use of an image: the file reference
(sys_). The file's own text
(sys_) is the default every use without a text
of its own falls back to. set_
(ADR-135) writes that default, so it changes the text of
every use of the file that has no text of its own, all at once, and the
writers that touch a reference
(ADR-198, ADR-212) set texts only on a
reference they create.
A site-wide check for missing alternative texts in EXT:nr_mcp_agent (its
ADR-026) lists each use of an image whose effective text is empty, and asks
the assistant for a text per hit. That extension decided that the writer
belongs here, next to set_: every content write the
assistant makes is an nr-llm tool with an approval card, and the tool is
useful without that extension.
Decision
set_ sets
alternative on one existing sys_, in place. It keeps
the terms of the other writers (ADR-134,
ADR-135, ADR-136,
ADR-198, ADR-213,
ADR-214):
- One column of one row, through the DataHandler as the acting backend user, in the live workspace only; read back afterwards, and reported as a failure when the value did not land.
- Any table. The reference may sit in a
type => filecolumn of any table the TCA declares: a content element, a page's own file field, a record of another extension. A table on the read-side denylist, and one declaredreador (for a non-admin)Only admin, is refused.Only - The reference's own language. A translated reference is written as it is; the tool takes no language argument and changes no other language.
- The acting user's rights, before the write: "edit content" on the
record's page, and for a page's own file field "edit page" as well. The
form edits a page's file field as a page property, while the DataHandler,
writing the reference row alone, asks "edit content" on its page (it asks
"edit page" only when
pagesis in the same datamap), so a page's reference needs both. Then: the page's edit lock (pages.) for a non-admin, which the permission bits do not carry and the DataHandler refuses;editlock tables_formodify sys_; the record-level rights of the record (file_ reference tables_on its table, its language,modify auth, the record's own edit lock); the reference's language; and the field-level grants forMode sys_and for the record's file field. A reference or record that is not there, a workspace version, a reference outside a file field and a page or record the user may not edit share one neutral refusal; a page's file field without "edit content", a page edit lock, a missing language right and a missing field grant are named.file_ reference: alternative - The owner chain. Where the record is an inline child (a carousel item
inside a content element), every record that holds it is asked the same
questions as the record — table, page, record-level rights — up the chain
until a record no inline column holds, with the same neutral refusal. The
DataHandler does not ask this (checked in 13.4.37 and 14.3.10: neither
checknor the datamap's update check looks at inline parents), but where a child sits in a table of its own (a carousel item, a content element of a news record) the backend form reaches it only through its owners, so an edit lock or a content type outside the editor'sRecord Edit Access () authgrant on the outer record would otherwise be passed by. An owner is any record anMode inlinecolumn of another table points to through the row'sforeign_, where itsfield foreign_andtable_ field foreign_agree; without amatch_ fields foreign_every table that holds the uid counts. An inline relation of a table to itself is not followed: that is the container pattern (EXT:gridelements declarestable_ field tt_as an inline relation tocontent. tx_ gridelements_ children tt_), where the page module edits each child on its own and the DataHandler asks about the child only, so the container does not stand between the editor and the child. A pointer no claiming table holds (the owner is gone) is refused as a gone record is, and a cycle ends at a record already asked. The same walk guards the two other writers that write a file reference on an existing record,content attach_(ADR-212) andfile_ to_ record replace_(ADR-198; a content element is an inline child of another table where an extension such as EXT:news holds content elements); all three share it infile_ reference Asks.Inline Owners Trait - Root level. A record on the root level (pid 0) is written by an admin
only. A table that sets
security.is not treated differently; no core table with a file field sets it.ignore Root Level Restriction - No empty text. An empty string, and a text of whitespace only, is
refused. This deviates from
set_,file_ alternative_ text attach_andfile_ to_ record replace_, wherefile_ reference ''is a valid value (an explicit empty override, or a decorative image). Whether an image is decorative is a decision of its own, which EXT:nr_mcp_agent records in a field of its own, and an empty alternative text cannot be told apart from a forgotten one. - The card names the record, its page, the language, the field and the
file, and shows the reference's own text before and after. Where the
reference has none (
NULL), the card says that the file's text applies today. - Disabled by default, in the
editinggroup, an idempotent write, usable by non-admins.
The read side exists already: read_ on sys_
returns alternative and keeps NULL apart from an empty text.
get_ is not extended.
Consequences
- The assistant can describe one use of an image without changing the text of every other use of the same file.
- The tool has no editor action, like the writers of ADR-198: it is reached through the assistant.
- A use of an image that exists only in a draft workspace cannot be written; the check in EXT:nr_mcp_agent overlays workspace rows, this tool does not write to them.
- The three reference writers are stricter than the DataHandler for an inline child: an editor whom the DataHandler would let write a carousel item's reference is refused while the content element holding the item is locked or of a type they may not edit. The first version of this tool, and the other two until this record, walked no chain and authorised the reference against the child record and its page only.
Revisit when
- Workspaces are supported by the writers as a whole: this tool follows them then.
- A consumer needs the empty text as a value after all; that is a second decision, recorded where the decorative concept lives.