-
Notifications
You must be signed in to change notification settings - Fork 0
Migration
This page outlines how to transition from windingwind's original zotero-better-notes plugin to this updated fork. It explains the core architectural improvements, how note templates differ in the new sandboxed model, and how to migrate your existing notes, sync links, and templates.
This version is a modernized, streamlined rebuild focusing on security, efficiency, and robustness. The key differences are:
| Subsystem | windingwind's Original | This Fork | Benefit |
|---|---|---|---|
| Template Engine | Arbitrary JavaScript (AsyncFunction compiler) |
Sandboxed LiquidJS engine | No RCE security risk; templates cannot execute arbitrary system or file-access commands. |
| Data Access | Full Zotero & BetterBibTeX API exposed | Bounded, curated data model (item.*, note.*) |
Simpler authoring, robust autocomplete, and no database corruption risks. |
| Sync Efficiency | O(N) periodic polling and hashing of every file and note | Event-driven exports + stat-gated (mtime) checks | Eliminated CPU and disk churn. Sync checks only files that actually changed on disk. |
| Background Sync | Polling only ran when Zotero window was active | Background sync runs while Zotero is unfocused | Edits made in external editors (e.g. Obsidian) flow back into Zotero immediately. |
| Merge Logic | 2-way diff modal on any concurrent change |
Automatic 3-way merge (diff3) |
Sync automatically integrates concurrent, non-overlapping edits, only prompting on line-level conflicts. |
| Sync Storage | Sync/template state read and written directly through prefs.js at many call sites |
Centralized behind a single KVStore seam (LargePrefHelper); a database backend is a contained, deferred drop-in |
One isolated, swappable storage layer instead of scattered preference access (a DB swap is future groundwork, not yet shipped). |
| Front-Matter | Injected $version, $libraryID, etc. into Markdown |
Slim, human-readable Markdown front-matter (tags, parent, collections, optional CitationKey) |
Removes plugin-internal clutter from your Obsidian vault. |
In the legacy plugin, templates were compiled from arbitrary JavaScript template literals, allowing lines like topItem.getField("title") or IOUtils.writeUTF8().
In the new version, templates are sandboxed:
-
Liquid Syntax: Replace
${ expr }(one-line) and${{ ... }}$(multi-line) JavaScript with standard Liquid{{ value }}and{% logic %}tags. -
Curated Variables: Instead of querying raw Zotero XPCOM items, you read fields from a safe data model:
-
item.title,item.year,item.abstract,item.doi,item.url -
item.authors(array of{ firstName, lastName, name }creators) -
item.citekey(integrated Better BibTeX / citation key) -
note.title,note.tags,note.key
-
-
No Direct Database Writes: Side effects (such as auto-tagging notes) are declared in the Sentinel Header at the top of the file rather than through JavaScript.
- Example:
<!--addTags: ItemNote, Reference-->
- Example:
-
Custom Tags/Filters: Embedded components like annotations are rendered via custom tags (
{% annotations %}) rather than custom JavaScript loops.
To make upgrading simple, the plugin includes a built-in transpiler that automatically converts legacy JavaScript templates into Liquid templates:
-
How to Use: Open the Note Template Editor (
⌃⌥T), select your custom template, and select Options → Convert legacy JavaScript template to Liquid. - Best-Effort Translation: It translates common patterns (such as field access, year extraction, the citekey idiom, and pragma comments).
-
Manual Review Flag (
BN-MIGRATE): Any complex, arbitrary JavaScript that cannot be safely converted to Liquid is commented out inside a{% comment %} BN-MIGRATE: ... {% endcomment %}block. The output is guaranteed to be valid Liquid, but you will need to review these comments to rewrite any advanced custom JS logic using Liquid filters or loops.
If you are upgrading from windingwind's original plugin, follow these steps:
Before starting, make a backup of:
- Your Zotero profile directory.
- Your external sync folder (e.g. your Obsidian vault where synced
.mdfiles are kept). - Any custom JavaScript templates you want to preserve (copy their raw text to a safe place).
- Download the latest
enhanced-notes.xpifrom the releases page. - In Zotero: Tools → Plugins → gear icon → Install Plugin From File.
- Select the
.xpifile. (The new version will safely overwrite and replace the old plugin). - Restart Zotero.
If you have synced notes left over from prior versions:
- If Zotero prompts you with a sync conflict dialog on startup, hit Stop Syncing This Note or Keep Both.
- This clears the legacy
prefs.jssync states so the new sync engine can register and link the files cleanly.
- Open the Template Editor (
⌃⌥Tor Tools → Note Template Editor). - Select your custom template from the list.
- Click Options → Convert legacy JavaScript template to Liquid.
- Check the template for any
BN-MIGRATEcomments. If you see them, replace the JS code with equivalent Liquid expressions or tags (see the Templates reference page). - Click Save.
- Open the Sync Manager (
⌃⌥Mor Tools → Sync Manager). - Confirm that your target sync directory is still set correctly.
- Trigger a manual sync (
⌃⌥S) or edit a synced note to verify that modifications sync bidirectionally in the background.