New features
- `Note.sync_template()`: Synchronize this note with a template note, recursively adding and re-ordering child notes matched by title
- Useful for updating template instances when you modify a template
- Replicates any cloned notes within the template
- `Note.copy()`: Create a shallow or deep copy of this note
- Label/relation accessors: `Note.labels`, `Note.relations`
- Can each be filtered by owned vs inherited: `Note.labels.owned`, `Note.labels.inherited`, `Note.relations.owned`, `Note.relations.inherited`
- Uses list semantics with additional getters/setters like `Note.labels.get()`, `Note.labels.get_value()`, `Note.labels.get_values()` (see the documentation for all interfaces)
- Indexing into a note (e.g. `note["myLabel"]`) now supports single-valued labels only (not relations) to improve type strictness
- Support subclassing `Note` to add custom accessors, subclass `BaseDeclarativeNote` for notes as code
Breaking changes
- `Note.attributes` no longer settable; set owned attribute list by setting `Note.attributes.owned`
- This is more consistent with the semantics of `Note.attributes` as a list of all owned and inherited attributes
- `Note.attributes` no longer indexable by attribute name; use new getters/setters like `Note.labels.get_value()`, `Note.labels.set_value()`
- Restructured subpackages
Project direction
- Offline bidirectional Markdown conversion and sync mechanism is deprioritized for the foreseeable future
- There are a number of design/implementation and practical challenges:
- Violates "single source of truth" principle
- Inherently lossy conversion from Trilium HTML format to Markdown, and challenges achieving feature parity in Markdown (e.g. links to other notes)
- Instead, possible custom export/import interface and command-line hook
- E.g.: `trilium-alchemy export --exporter my_pkg.my_exporter path/to/destination`