You’re reading the ZotLit v2 beta docs. Still on v1? Read the v1 docs

ZotLit

Frontmatter

Field definitions, merge strategies, reserved keys, and update behavior for literature note frontmatter.

This page documents how ZotLit manages YAML frontmatter on literature notes: system-managed fields, user-configured fields, merge strategies, and the behavior during note updates.

For step-by-step configuration, see Configure frontmatter properties.

System-managed fields

ZotLit always writes these fields. They cannot be overridden by user configuration.

FieldSourceDescription
zotero-keyzt.indexedKeyItem identity key: KEY for the user library, KEYgGROUPID for group libraries
citekeyzt.citationKeyCitation key. Written only when the item has one; deleted otherwise

User-configured fields

Configured at Settings > Templates > Frontmatter. Each field has four parts:

PartDescription
KeyThe YAML property name written to frontmatter
ExpressionProduces the value (evaluated in the declared language)
Languageliquid or javascript
Merge strategyHow the field behaves when refreshing an existing note

Default fields

Out of the box, ZotLit configures:

KeyExpressionLanguageMerge
titlezt.titleLiquidReplace
relatedzt.relatedItems | note_linksLiquidReplace
collectionszt.collections | collection_pathsLiquidReplace

Liquid expressions

Liquid expressions use the same filter vocabulary as templates (see Template syntax). They return typed values (arrays, numbers, strings), not rendered text.

zt.title                              -> "My Paper Title"
zt.authors | join: ", "               -> "Jane Smith, Bob Jones"
zt.tags | map: "name"                 -> ["methodology", "review"]
zt.collections | collection_paths     -> ["Project/Reading", "Research"]
zt.date.year                          -> 2023

JavaScript expressions

JavaScript expressions require the JavaScript Templates gate. Any valid JavaScript expression works, with the full note context available as zt:

zt.authors.map(c => c.fullName)   -> ["Jane Smith", "Bob Jones"]
zt.tags.map(t => t.name)          -> ["methodology", "review"]
zt.date?.year                     -> 2023

The return value is serialized to YAML automatically.

Merge strategies

Each user field selects one of three merge strategies that control what happens when the note is updated:

StrategyUI labelBehavior
replaceReplaceWrites the generated value unconditionally. The existing value is overwritten
appendAppend arraysAppends new generated values not already present to the existing array. Manual additions remain. If existing is blank, writes the generated value. Both the existing and generated values must be arrays; when either side is not an array (and existing is not blank), the field is left unchanged
keepKeep existingWrites the generated value only when the existing field is blank. Once the field has a value, it is never overwritten

What counts as blank

A value is blank (and treated as absent by Append arrays and Keep existing) when it is:

  • null or undefined
  • An empty string ("")
  • An empty array ([])
  • An empty plain object ({})

Undefined expressions

When an expression returns undefined, the field is untouched regardless of the merge strategy. Only defined values (including explicit null) reach the merge logic.

Append arrays detail

The Append arrays strategy preserves existing items verbatim (including any duplicates already present) and appends only generated items not already in the array.

Reserved keys

The following keys cannot be used in user field configuration:

KeyOwner
zotero-keySystem-managed (literature note identity)
citekeySystem-managed (literature note identity)
zotero-note-keyImported notes
zotero-lastmodImported notes

Attempting to use a reserved key is rejected in the settings modal.

Validation

The settings modal validates in this order:

  1. Empty key: "Enter a key."
  2. Reserved key: "'{key}' is managed by ZotLit and can't be used."
  3. Duplicate key: "'{key}' is already mapped."
  4. Empty expression: "Enter an expression."

Expression syntax errors are detected when saving. Runtime errors (e.g. accessing a property on null) are reported per-field at render time. The failing field is skipped and remaining fields still evaluate.

Merge on update

When you run ZotLit: Update literature note or ZotLit: Update literature note metadata, ZotLit refreshes frontmatter:

  1. System fields (zotero-key, citekey) are refreshed.
  2. User-configured fields are re-evaluated and applied using their merge strategy.
  3. Unmanaged keys: any frontmatter key not in the managed set (e.g. aliases, tags, cssclasses) is preserved. ZotLit never touches keys it does not own.

ZotLit: Overwrite literature note replaces the note body but applies the same frontmatter behavior: managed keys are refreshed and unmanaged keys are kept.

ZotLit writes frontmatter through Obsidian's processFrontMatter API, which preserves key ordering and formatting for unmanaged keys.

JavaScript Templates gate

A field's language determines its evaluation engine. The JavaScript Templates gate controls whether javascript fields run:

  • Gate off: JavaScript fields are inert. They are not evaluated. Any operation that depends on inert fields surfaces an error naming those fields. Liquid fields are unaffected.
  • Gate on: Both Liquid and JavaScript fields evaluate normally.

The gate never reinterprets an expression. A Liquid field always evaluates as Liquid; a JavaScript field always evaluates as JavaScript.

Inert fields block note operations

When any frontmatter field is configured with language javascript and the gate is off, literature note creation and update fail with an error listing the inert fields. Either enable the gate or switch those fields to Liquid. See Enable JavaScript templates.

See also

On this page