Schemas
Summary
Schema help you apply consistent structure to all your notes.
As you end up creating more notes, it can be hard to manage them at scale. Think of schemas as an optional type system for your notes that describe the hierarchy of your data and are represented as a hierarchy, themselves.
One of the primary capabilities for schema is to automatically insert templates into new notes.
Features
Schema Completions
Schemas will autosuggest valid children when you create a new project.
Schema Hints
Schemas show up as icons next to lookup results.
Schema Anatomy
A schema is a YAML file with the following naming scheme {name}.schema.yml
Below is an example of a four-level hierarchy describing cli commands. The id
field of the schema is used to build a glob pattern which will be used to match notes matching the schema.
version: 1
schemas:
# this will match "cli.*" notes
- id: cli
# human readable description of hierarchy
desc: command line interface reference
# add this to the domain of your schema hierarchy
parent: root
# when a schema is a namespace, it can have arbitrary children. equivalent to cli.* glob pattern
namespace: true
children:
- cmd
- env
# will match cli.*.env
- id: env
desc: cli specific env variables
# will match cli.*.cmd.*
- id: cmd
desc: subcommands
namespace: true
Below is another way of representing the above schema
.
└── cli # matches cli
└── {cli child} # matches cli.*
├── env # matches cli.*.env
└── cmd # matches cli.*.cmd
└── {cmd child} # matches cli.*.cmd.*
Inline Schema Anatomy
Another way to specify schemas is to use inline schemas. Which can be simpler to create and maintain.
When we are creating inline schemas only the topmost schema must have an identifier id
(this identifier will be used when looking up schemas). Note that this identifier is global and will be applied across all vaults. Child schemas are inlined under children
and just require to contain pattern
.
While using inline schemas you can take advantage of collapsibility of YAML config.
Here is an example of inline daily journal schema it will match notes such as 'daily.journal.2021.11.12'
version: 1
schemas:
# Daily is the top most schema since its parent is 'root' it must have an identifier
# this identifier 'daily' will be used when using 'Lookup (schema)' command.
- id: daily
parent: root
# Children of the top most schema do not need to contain identifier and just
# require a 'pattern' to be set to match the hierarchy of notes.
children:
- pattern: journal
children:
- pattern: "[0-2][0-9][0-9][0-9]"
children:
- pattern: "[0-1][0-9]"
children:
- pattern: "[0-3][0-9]"
# As with regular schema we can set the template to be used with
# the match of our notes. Below is an example usage of shorthand template
# definition (which defaults to type: note).
template: templates.daily
Properties
version (optional): number
- values:
0|1
- default: 1
- description: schema version number
imports
-
(optional): str[]
-
values: list of schemas to import
-
default: []
-
description: import schemas from another schema into the current schema
- when using schemas from an external schema file, you will need to prefix the schema with the file name without the
schema.yml
suffix
- when using schemas from an external schema file, you will need to prefix the schema with the file name without the
-
NOTE:
import
is only available in schema version1
Example:
- foo.schema. yml
version: 1
imports:
- bar
schemas:
- id: foo
parent: root
children:
- bar.bar # notice that we prefix the id bar with the filename
- bar.schema.yml
version: 1
schemas:
- id: bar
parent: root
children:
- one
- id: one
The above would match the following files
foo.bar # match
foo.bar.one #match
schemas
- list of schema definitions
id
the identifier of the schema. also designates the glob pattern match. this is the only required part of a schema. all other fields are optional
title
This value shows up in the lookup bar, if you have it in your schema configuration file, instead of just showing the pattern value. The title
is also applied within the Schema Graph View.
desc
human readable description of the schema node. these will automatically when creating notes that match the schema.
parent
- only required for schema domain
- NOTE: at least one schema MUST have
parent: root
set
namespace
making a schema node a namespace automatically brings its immediate children as part of the schema, even if they are not explicitly defined in the schema definition. it will also automatically set the pattern to {namespace}.*
- example:
schemas:
- id: project
parent: root
namespace: true
- this will match:
project
project.foo
project.bar
- it will not match
project.foo.bar
pattern
The glob pattern that schema matches. by default, this is the id
of the schema. you can override this.
NOTE: Patterns are not supported at the first level of a hierarchy, and can only be defined within children.
For example, take a look at the journal schema below
schemas:
- id: journal
title: journal
desc: ""
parent: root
children:
- year
- id: year
title: year
pattern: "[0-2][0-9][0-9][0-9]"
children:
- month
- id: month
title: month
pattern: "[0-9][0-9]"
children:
- day
- id: day
title: day
pattern: "[0-9][0-9]"
namespace: true
This will match the following queries
# journal
# journal.2020
# journal.2020.09
# journal.2020.09.12
# journal.2020.09.12.foo.md
The glob patterns used here are the same as the Bash Extended Glob patterns, with a few . We can use the extended globs to match interesting patterns. Here's a few examples:
"[0-9]"
will match any digit"[!0-9]"
will match anything that's not a digit"*([0-9])"
will match 0 or more digits"+([0-9])"
will match 1 or more digits"*"
will match 0 or more of any character"+([!])"
will match 1 or more of any character"@(left|right)"
will matchleft
orright
, but nothing else"!(thing)"
will match anything other thanthing
We can then combine these to get interesting patters. Here are more examples:
"+([0-9])-+([!])"
matches10-test
, but nottest
or10
or10-
."!(temp|scratch)"
matchesnotes
,recipes
etc. but nottemp
orscratch
, if you are trying to exclude just those hierarchies
children
list of ids of schemas that are the child of the current schema
template
a template you can apply to all notes that match this schema. See Schema Templates for more details.
template:
# identifier for the template (for a note based template, it would be the name of the note)
id: journal.template.daily
# what sort of template we are creating. currently, only 'note' is supported
type: note
If a template does not exist, a warning message will be shown and the note will created without a schema applied.
Shortened template syntax
# identifier for the template (the name of the note)
# The type will be set to 'note'
template: journal.template.daily
Shortened template syntax will always uses type: note
If there are multiple templates with the same identifier in multiple vaults, you will be prompted to pick the vault when trying to apply a note template.
Cross-vault template syntax
# Use this to specify a template (If there are multiple or if it lies in a vault separate from your schema)
template: dendron://myVault/journal.template.daily
If the vault does not exist, a warning message will be shown and the note will created without a schema applied.
Schema Templates
Automatically apply a template when it matches a particular hierarchy pattern This is extremely useful whenever you want to re-use the outline of a note. Examples include daily journals, weekly shopping lists, and weekly reviews.
Unknown Schema
Dendron doesn't force you to use schemas if you don't want to. This is why you can create notes that don't match any schema. Dendron will show you a ?
next to these results.
Sometimes
rulesschemas are meant to be broken
Working with Schemas
Schemas can be modified, created and deleted using the same lookup interface that you use for regular notes. See lookup for further details about working with schemas.
Examples
You can find a vault with templates and schema examples here
Troubleshooting
Error with parsing some schemas during initialization
If you get this error, it means that Dendron encountered some malformed schemas during initialization. You can open the error message to see what schemas are affected.
Common errors:
- the YAML isn't valid (use http://www.yamllint.com/ to validate)
- there is no schema with
parent: root
property
parent
- only required for schema domain
- NOTE: at least one schema MUST have
parent: root
set
Cookbook
Testing schemas
If you want to test what your schemas will match, you can use a glob tester like Glob tester to do so
Children
Backlinks