3.8 KiB
#level/hardcore
Object decorators are an advanced technique that can be used to add attributes to Objects dynamically whose values are calculated dynamically (on-the-fly) based on an Expression Language.
warning Warning This feature is still experimental and may change in the (near) future.
The primary use case is Page Decorations, but it is a powerful mechanism that probably has wider applications. As always, with great power comes great responsibility.
Syntax
Object decorations are specified using Space Config (either in ^SETTINGS or elsewhere):
```space-config
objectDecorators:
- where: '<<filter expression>>'
attributes:
<<attributePath>>: '<<value expression>>'
```
note Note For changes to take effect you may have to reload your client (just refresh the page).
A few things of note:
<<filter expression>>
is a YAML string-encoded expression using SilverBullet’s Expression Language. Some examples:where: 'tags = "book"'
to make this apply to all objects that hasbook
as one of its tags.
<<attributePath>>
can either be a simple attribute name, or a nested one using theattribute.subAttribute
syntax. Some examples:fullName
pageDecoration.prefix
<<value expression>>
like<<expression>>
must be a YAML string-encoded expression using the Expression Language, some examples together with the attribute path:alwaysTen: '10'
(attaches an attribute namedalwaysTen
with the numeric value10
to all objects matching thewhere
clause)alwaysTrue: 'true'
(same asalwaysTen
but with a boolean value)fullName: 'firstName + " " + lastName'
(attaches afullName
attribute that concatenates thefirstName
andlastName
attributes with a space in between)nameLength: 'count(name)'
(attaches an attributenameLength
with the string length ofname
— not particularly useful, but to demonstrate you can call Functions here too).
Rules
A few rules and best practices to keep things civil:
- It is recommended to always filter based on
tag
(so by adding e.g.tag = "page"
to yourwhere
clause) to limit the radius of impact. Otherwise you may accidentally apply new attributes of all your Objects (items, tasks, pages, etc.). - Dynamic attributes cannot override already existing attributes. If the object already has an attribute with the same name, this value will be kept as is.
- For performance reasons, all expressions (both filter and value expressions) need to be synchronously evaluatable.
- Generally, this means they need to be “simple expressions” that require no expensive calls.
- Simple expressions include simple things like literals, arithmetic, calling some of the cheap Functions such as
today()
or string manipulation functions. - Expensive calls include any additional database queries, or any function call (custom or otherwise) that are asynchronous. These are not supported.
- This requirement will be checked at runtime. Watch your server logs and browser’s JavaScript JavaScript console to see these errors.
Example
Let’s say that you use the human
tag to track various humans in your space, as follows:
firstName: Steve
lastName: Bee
---
firstName: Stephanie
lastName: Bee
This will get you the following data set:
human select firstName, lastName
However, you would like to dynamically compute an additional attribute for all humans, namely fullName
. This can be done as follows with Space Config:
objectDecorators:
- where: 'tag = "human"'
attributes:
fullName: 'firstName + " " + lastName'
Which will give you the following:
human select fullName, firstName, lastName
As the French say: Voila!