Collection plugins
Every collection is defined by a JSON configuration plus optional JavaScript. Collection Settings… → Edit Code opens both. The settings dialog edits the same configuration with forms, so you can mix: define fields and views in the dialog, add behavior in code.
Configuration
A field has a stable id, a label, a type and a few options:
{
"id": "hours",
"label": "Hours",
"type": "number",
"icon": "ti-clock",
"many": false,
"read_only": false,
"active": true
}
Views have an id, a label, a type, the field_ids they show, and their sort, grouping and query. Keep ids stable when you rename things: values and views refer to fields by id. A managed section can mark fields, views or sidebar settings as controlled by the plugin, which disables them in the settings dialog.
Formulas and property behavior
this.properties.formula(name, fn) computes a property; see Formulas. render() draws a property your own way, customSort() sorts it your own way, and the choice hooks fill a Choice property’s options from code.
Custom views
Add a view with "type": "custom" to the configuration, then register its behavior:
class Plugin extends CollectionPlugin {
onLoad() {
this.views.register("Timeline", (ctx) => {
let nodes = new Map();
return {
onLoad() { /* build the view in ctx.element */ },
onRefresh({records, invalidatedGuids}) { /* update changed records */ },
onDestroy() { nodes.clear(); },
};
});
}
}
ctx gives you the view’s element, the visible properties, the records and navigation helpers. Keep the view’s state inside the registration function: two panels can show the same view at once. onRefresh tells you which records changed; null means all of them, an empty set none. Update what changed instead of rebuilding everything.
Built-in views have hooks too, such as afterRenderBoardCard() for adding buttons to board cards.
Commands and interface
| Extension | API |
|---|---|
| Command palette command | this.ui.addCommandPaletteCommand() |
| Status bar item | this.ui.addStatusBarItem() |
| Notification | this.ui.addToaster() |
| Custom panel | this.ui.registerCustomPanelType() |
| Sidebar widget | this.ui.addSidebarWidget() |
| Button on this collection | this.addCollectionNavigationButton() |
Use the UI API’s buttons, icons and panels so your plugin looks like Thymer in every theme. Release timers and listeners in onUnload(); with hot reload, a plugin is unloaded and loaded many times.