Appearance
Types and templates
Types
json
"types": [
{
"key": "movie",
"name": "Movie",
"fields": [
{ "key": "poster", "name": "Poster", "kind": "asset" },
{ "key": "year", "name": "Year", "kind": "number" },
{
"key": "timesWatched",
"name": "Times watched",
"kind": "formula",
"formula": { "op": "count", "of": "viewing", "via": "movie" }
}
]
},
{
"key": "viewing",
"name": "Viewing",
"fields": [
{ "key": "movie", "name": "Movie", "kind": "reference", "target": "movie", "required": true },
{ "key": "watchedOn", "name": "Watched on", "kind": "dateTime" },
{ "key": "rating", "name": "Rating", "kind": "number" }
]
}
]| Key | |
|---|---|
key | The type's key, which your code uses. |
name | Its name in Sorus. |
extends | pages/event, pages/task or pages/entry, to build on one of Sorus's types. Its objects are then events, tasks or day-log entries too. |
from | Another extension's type, <extension id>/<type key>, to add fields to instead of bringing a type. |
fields | Its fields. |
Fields
| Key | |
|---|---|
key | The field's key. |
name | Its name in Sorus; the key if left out. |
kind | text, number, dateTime, date, url, email, boolean, asset, choice, reference, computed or formula. |
list | 0 for one value (the default), 1 for a list, up to 4 for lists of lists. |
required | true to require a value. |
target | For reference: the key of one of your types, or leave it out for any object. |
options | For choice: [{ "key": "done", "name": "Done" }, …]. |
function | For computed: created, edited, createdBy, editedBy or links. |
formula | For formula: see below. |
A formula works something out from the objects that link to this one:
json
{ "op": "max", "of": "viewing", "via": "movie", "value": "watchedOn" }of: one of your types;via: its reference field that points here.op:count,sum,average,minormax. All butcountneed avalue: the field ofofto combine.
Computed fields and formulas hold one value and are never required.
IDs
Sorus makes each type, field and option an ID worked out from your extension's id and their keys, so every device makes the same ones. Your code reaches them through pages.types:
js
pages.types.movie.id // the Movie type
pages.types.movie.fields.year // its Year field
pages.types.project.options.status.done // an option of a choice fieldAlways use these IDs. Never look a type or field up by its name: the person may rename it, or have mapped your type onto one of their own.
Mapped onto the person's type
When someone installs your extension and already has a similar type, they can choose to use theirs. Sorus then adds your fields to their type (by matching names, where the kinds agree), and pages.types.<key> points at their type and fields. Your code doesn't change.
Adding to another extension's type
A type with from adds fields to another extension's type rather than bringing its own. Letterboxd does this to Movies:
json
{
"key": "movie",
"from": "dev.pages.movies/movie",
"fields": [
{ "key": "poster", "name": "Poster", "kind": "asset" },
{ "key": "year", "name": "Year", "kind": "number" },
{ "key": "letterboxd", "name": "Letterboxd URI", "kind": "text" }
]
}Here poster and year are Movies' own fields, named so Letterboxd's code can use them; letterboxd is new.
The other extension must be installed first. Fields named with that extension's keys are its own: checked, and left as they are. from and extends can't be used together.
Templates
json
"templates": [
{
"type": "book",
"name": "Reading notes",
"fields": { "readingStatus": "reading" },
"body": "## Why I picked it up\n\n## Notes\n"
}
]| Key | |
|---|---|
type | One of your type keys. |
name | Up to 80 characters. |
fields | Starting values by field key: text, a number, or true/false. For a choice, the option's key. |
body | The page's starting text, up to 20,000 characters. |
Templates appear when someone makes a new object of the type. See Templates.