Display hints

How a type says what names an item, where its text is, whether that text can name it and which icon it shows, how Marfa names an item from them, and the icon the owner chooses.

A type's display_hints tell an app how to show its items: the field that names an item, the field that holds its text, whether that text can name it, and an icon. Type rules has the rest of what a type you register must meet, and Define a type shows how to set them.

The hints

display_hints takes four optional hints:

HintWhat it holdsMarfa refuses
title_fieldThe name of the field that names an item.A field the type and its ancestors don't declare, or a thumbnail field.
body_fieldThe name of the field that holds the item's text, in Markdown. Apps render it, and a device makes edges from its links.The same as title_field.
name_from_bodyfalse where the item's text never names it, however short, as on core.highlight, whose passage is its text but never its name. Unset, the text can name an item.Anything but true or false.
iconAn Iconify icon ID, <set>:<name>, from the lucide set (@iconify-json/lucide 1.2.149) or, for brand marks, the simple-icons set (@iconify-json/simple-icons 1.2.101), such as lucide:star or simple-icons:github.A bare name such as star, another set, a name the set's version lacks, an alias such as lucide:alert-circle, an icon the set marks hidden, or a wrong-case or padded ID.

Marfa refuses a hint with 400 invalid_schema, naming the member, such as display_hints.icon.

Marfa doesn't check the text in body_field. It stores the value as sent and never refuses it as malformed Markdown, so a connector converts a vendor's HTML first, or an app shows the tags.

The icon sets are fixed because apps carry their own copy, so an icon draws offline and looks the same in every app. The accepted IDs are in icon-set-lucide.json and icon-set-simple-icons.json.

Each hint comes from the nearest type that sets it, so a type that sets only an icon keeps the title and body its parent names. GET /types/{id} answers each hint after inheritance, and GET /types lists only the hints each type sets itself.

Names and previews

The server and a device name an item by one rule, so they show the same name, offline included.

  • The name comes from the first of these fields that holds text: title_field, title, name, body_field, body, text, filename, url and address, leaving out body_field, body and text where name_from_body is false. Marfa takes the first line, collapses each run of whitespace and keeps at most 120 characters, ending in … where it cuts.
  • A name taken from body_field, body or text loses its Markdown, so a note whose body starts # Plan is named Plan. A name from any other field keeps every character.
  • A part or an excerpt with no title of its own is named after the item it belongs to, by the edge's label and that item's name: a comment is "Comment on Plan" and a highlight "Excerpt from Thinking, Fast and Slow". Several highlights can share a name. Where it has more than one such item, the oldest edge to one out of the bin that the reader may read names it, and with none, its own fields do.
  • An item with no name is Untitled to the server. A device answers that it has none, so each app chooses its own word.
  • A preview is the body field's text without its Markdown, at most 240 characters. Where the name came from the body field, the preview leaves out that line and every line before it. Only a device makes one.

A Swift app reads both with displays(of:).

The owner's icon

The owner can choose the icon of any type, a shipped or connector type included, without replacing it. The choice sits beside the type's definition, so the author's icon stays the default. Set a type's icon and clear a type's icon are the operations:

marfa types set-icon user.recipe lucide:chef-hat
marfa types clear-icon user.recipe
  • Reads answer it in place of the author's icon, and a subtype with no icon of its own shows it.
  • Replacing the type keeps it, and deleting the type discards it. A type registered again under the same identifier starts without one.
  • Devices take it at their next catch-up, or when a follow next opens its stream. No event announces it.
  • The icon follows the same rules as the author's. One the sets don't hold is refused 400 invalid_schema, naming icon, and a type nothing registered is refused 404 type_not_found. A refused call leaves the icon the type had.
  • Who can change it: the owner, a local process, or a key with schema.write and write on the type. A key without schema.write is refused 403 forbidden, and one without write on the type 403 type_not_permitted.

Change a type explains what a replacement does with the owner's icon when you send back what a GET answered.

The rules behind this page are in the types and device chapters of the contract.

On this page