Skip to content

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
keyThe type's key, which your code uses.
nameIts name in Sorus.
extendspages/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.
fromAnother extension's type, <extension id>/<type key>, to add fields to instead of bringing a type.
fieldsIts fields.

Fields ​

Key
keyThe field's key.
nameIts name in Sorus; the key if left out.
kindtext, number, dateTime, date, url, email, boolean, asset, choice, reference, computed or formula.
list0 for one value (the default), 1 for a list, up to 4 for lists of lists.
requiredtrue to require a value.
targetFor reference: the key of one of your types, or leave it out for any object.
optionsFor choice: [{ "key": "done", "name": "Done" }, …].
functionFor computed: created, edited, createdBy, editedBy or links.
formulaFor 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, min or max. All but count need a value: the field of of to 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 field

Always 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
typeOne of your type keys.
nameUp to 80 characters.
fieldsStarting values by field key: text, a number, or true/false. For a choice, the option's key.
bodyThe page's starting text, up to 20,000 characters.

Templates appear when someone makes a new object of the type. See Templates.