Zotero Plugin Template
This is a plugin template for Zotero. Plugins using this template are shown above.
📖Plugin Development Documentation(Chinese, provides English translation)
🛠️Zotero Plugin Toolkit | API Documentation
📌Zotero Plugin Template(This repo)
👍You are currently in
bootstrapextension mode. To useoverlaymode, plsase switch tooverlaybranch in git.
👁 Watch this repo so that you can be notified whenever there are fixes & updates.
Features
- Event-driven, functional programming, under extensive skeleton;
 - Simple and user-friendly, works out-of-the-box.
 - Abundant examples in 
src/modules/examples.ts, covering most of the commonly used APIs in plugins(using zotero-plugin-toolkit); - TypeScript support:
- Full type definition support for the whole Zotero project, which is written in JavaScript(using zotero-types);
 - Global variables and environment setup;
 
 - Plugin build/test/release workflow:
- Automatically generate/update plugin id/version, update configrations, and set environment variables(
development/production); - Automatically build and reload code in Zotero;
 - Automatically release to GitHub(using release-it);
 
 - Automatically generate/update plugin id/version, update configrations, and set environment variables(
 - ⭐[New!]Compatibilities for Zotero 6 & Zotero 7.(using zotero-plugin-toolkit)
 
Examples
This repo provides examples for zotero-plugin-toolkit APIs.
Search @example in src/examples.ts. The examples are called in src/hooks.ts.
Basic Examples
- registerNotifier
 - registerPrefs, unregisterPrefs
 
Shortcut Keys Examples
- registerShortcuts
 - exampleShortcutLargerCallback
 - exampleShortcutSmallerCallback
 - exampleShortcutConflictionCallback
 
UI Examples
- registerStyleSheet(the official make-it-red example)
 - registerRightClickMenuItem
 - registerRightClickMenuPopup
 - registerWindowMenuWithSeprator
 - registerExtraColumn
 - registerExtraColumnWithCustomCell
 - registerCustomCellRenderer
 - registerLibraryTabPanel
 - registerReaderTabPanel
 
Preference Pane Examples
- Preferences bindings
 - UI Events
 - Tabel
 - Locale
 
See src/modules/preferenceScript.ts
HelperExamples
- dialogExample
 - clipboardExample
 - filePickerExample
 - progressWindowExample
 - vtableExample(See Preference Pane Examples)
 
Quick Start Guide
Install Pre-built xpi
See how the examples work by directly downloading the xpi file from GitHub release and install it to your Zotero.
This is also how your plugin will be released and used by others.
The release do not promise any real functions. It is probably not up-to-date.
The
xpipackage is a zip file. However, please don't modify it directly. Modify the source code and build it.
Build from Source
- Fork this repo/Click 
Use this template; - Git clone the forked repo;
 - Enter the repo folder;
 - Modify the settings in 
./package.json, including: 
  version,
  author,
  description,
  homepage,
  config {
    releasepage,
    updaterdf,
    addonName,
    addonID,
    addonRef
  }
Be careful to set the addonID and addonRef to avoid confliction.
- Run 
npm installto set up the plugin and install dependencies. If you don't have NodeJS installed, please download it here; - Run 
npm run buildto build the plugin in production mode. Runnpm run build-devto build the plugin in development mode. The xpi for installation and the built code is underbuildsfolder. 
What the difference between dev & prod?
- This environment variable is stored in
 Zotero.AddonTemplate.data.env. The outputs to console is disabled in prod mode.- You can decide what users cannot see/use based on this variable.
 
Release
To build and release, use
# A release-it command: version increase, npm run build, git push, and GitHub release
# You need to set the environment variable GITHUB_TOKEN https://github.com/settings/tokens
# release-it: https://github.com/release-it/release-it
npm run release
Setup Development Environment
- 
Install a beta version of Zotero: https://www.zotero.org/support/beta_builds (Zotero 7 beta: https://www.zotero.org/support/dev/zotero_7_for_developers)
 - 
Install Firefox 60(for Zotero 6)/Firefox 102(for Zotero 7)
 - 
Copy zotero command line config file. Modify the commands that starts your installation of the beta Zotero.
 
(Optional) Do this only once: Start the beta Zotero with
/path/to/zotero -p. Create a new profile and use it as your development profile. Use/path/to/zotero -p {profile_name}to specify which profile to run with.
cp ./scripts/zotero-cmd-default.json ./scripts/zotero-cmd.json
vim ./scripts/zotero-cmd.json
- 
Setup plugin development environment following this link.
 - 
Build plugin and restart Zotero with
npm run restart. - 
Launch Firefox 60(Zotero 6)/Firefox 102(Zotero 7)
 - 
In Firefox, go to devtools, go to settings, click "enable remote debugging" and the one next to it that's also about debugging
 
Press
shift+F8in FF 60, or enterabout:debugging#/setupin FF 102.
- 
In Zotero, go to setting, advanced, config editor, look up "debugging" and click on "allow remote debugging".
 - 
Connect to Zotero in Firefox.
 
In FF 60, click the hamburger menu in the top right -> web developer -> Connect..., then enter
localhost:6100.
In FF 102, enter
localhost:6100in the bottom input of remote-debugging page and clickadd.
- 
Click
connectin the leftside-bar of Firefox remote-debugging page. - 
Click "Inspect Main Process"
 
Debug in Zotero
You can also:
- Test code snipastes in Tools->Developer->Run Javascript;
 - Debug output with 
Zotero.debug(). Find the outputs in Help->Debug Output Logging->View Output; - Debug UI. Zotero is built on the Firefox XUL framework. Debug XUL UI with software like XUL Explorer.
XUL Documentation: http://www.devdoc.net/web/developer.mozilla.org/en-US/docs/XUL.html
 
Details
About Hooks
See also
src/hooks.ts
- When install/enable/startup triggered from Zotero, 
bootstrap.js>startupis called- Wait for Zotero ready
 - Load 
index.js(the main entrance of plugin code, built fromindex.ts) - Register resources if Zotero 7+
 
 - In the main entrance 
index.js, the plugin object is injected underZoteroandhooks.ts>onStartupis called.- Initialize anything you want, including notify listeners, preference panes, and UI elements.
 
 - When uninstall/disabled triggered from Zotero, 
bootstrap.js>shutdownis called.events.ts>onShutdownis called. Remove UI elements, preference panes, or anything created by the plugin.- Remove scripts and release resources.
 
 
About Global Variables
See also
src/index.ts
The bootstrapped plugin runs in a sandbox, which does not have default global variables like Zotero or window, which we used to have in the overlay plugins' window environment.
This template registers the following variables to the global scope:
Zotero, ZoteroPane, Zotero_Tabs, window, document, rootURI, ztoolkit, addon;
About Preference
Zotero 6 doesn't support preference pane injection in bootstrap mode, thus I write a register for Zotero 6 or lower.
You only need to maintain one preferences.xhtml which runs natively on Zotero 7 and let the plugin template handle it when it is running on Zotero 6.
           
          Zotero 7 
         | 
        
           
          Zotero 6 
         | 
    
08d72a4e2b/src/modules/examples.ts (L73-L85)
<preferences>element is deprecated. Please use the full pref-key in the elements'preferenceattribute. Like:
<checkbox label="&zotero.__addonRef__.pref.enable.label;" preference="extensions.zotero.__addonRef__.enable" />
The elements with preference attributes will bind to Zotero preferences.
Remember to call unregister() on plugin unload.
Create Elements API
The plugin template provides new APIs for bootstrap plugins. We have two reasons to use these APIs, instead of the createElement/createElementNS:
- In bootstrap mode, plugins have to clean up all UI elements on exit (disable or uninstall), which is very annoying. Using the 
createElement, the plugin template will maintain these elements. JustunregisterAllat the exit. - Zotero 7 requires createElement()/createElementNS() → createXULElement() for remaining XUL elements, while Zotero 6 doesn't support 
createXULElement. The React.createElement-like APIcreateElementdetects namespace(xul/html/svg) and creates elements automatically, with the return element in the corresponding TS element type. 
createElement(document, "div"); // returns HTMLDivElement
createElement(document, "hbox"); // returns XUL.Box
createElement(document, "button", { namespace: "xul" }); // manually set namespace. returns XUL.Button
About Build
Use Esbuild to build .ts source code to .js.
Use replace-in-file to replace keywords and configurations defined in package.json in non-build files (.xul/xhtml, .dtd, and .properties).
Steps in scripts/build.js:
- Clean 
./builds - Copy 
./addonto./builds - Esbuild to 
./builds/addon/chrome/content/scripts - Replace 
__buildVersion__and__buildTime__in./builds/addon - Zip the 
./builds/addonto./builds/*.xpi 
About Zotero API
Zotero docs are outdated and incomplete. Clone https://github.com/zotero/zotero and search the keyword globally.
⭐The zotero-types provides most frequently used Zotero APIs. It's included in this template by default. Your IDE would provide hint for most of the APIs.
A trick for finding the API you want:
Search the UI label in .xul(.xhtml)/.dtd/.properties files, find the corresponding key in locale file. Then search this keys in .js/.jsx files.
Directory Structure
This section shows the directory structure of a template.
- All 
.js/.tscode files are in./src; - Addon config files: 
./addon/chrome.manifest,./addon/install.rdf, and./addon/manifest.json; - UI files: 
./addon/chrome/content/*.xhtml. - Locale files: 
./addon/chrome/locale/[*.dtd, *.properties]; - Resource files: 
./addon/chrome/skin/default/__addonRef__/*.dtd; - Preferences file: 
./addon/chrome/defaults/preferences/defaults.js;Don't break the lines in the
defaults.js 
│  .gitignore
│  .release-it.json # release-it conf
|  tsconfig.json    # https://code.visualstudio.com/docs/languages/jsconfig#
│  build.js         # esbuild
│  LICENSE
│  package.json     # npm conf
│  README.md        # readme
│  update.rdf       # addon update
│
├─.github           # github conf
│
├─addon             # addon dir
│  │  chrome.manifest  # for Zotero 6
│  │  manifest.json # for Zotero 7
│  │  install.rdf   # addon install conf, for Zotero 6
│  │  bootstrap.js  # addon load/unload script, like a main.c
│  │
│  └─chrome
│      ├─content    # UI
│      │  │  preferences.xhtml
│      │  │
│      │  ├─icons
│      │  │      favicon.png
│      │  │      favicon@0.5x.png
│      │  │
│      │  └─scripts
│      └─locale     # locale
│         ├─en-US
│         │      overlay.dtd
│         │      addon.properties
│         │
│         ├─zh-CN
│         |      overlay.dtd
│         └─     addon.properties
│
├─builds            # build dir
│  └─.xpi
│
└─src               # source code
    │  index.ts     # main entry
    │  addon.ts     # base class
    │  hooks.ts     # lifecycle hooks
    |
    └─modules       # sub modules
       │  examples.ts           # examples factory
       │  locale.ts             # locale .properties
       │  preferenceScript.ts   # script runs in preferences.xhtml
       └─ progressWindow.ts     # progressWindow tool
Disclaimer
Use this code under AGPL. No warranties are provided. Keep the laws of your locality in mind!
If you want to change the license, please contact me at wyzlshx@foxmail.com
Part of the code of this repo refers to other open-source projects within the allowed scope.
- zotero-better-bibtex(
d.ts) 

