Skip to content

windingwind/zotero-plugin-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

author
xiangyu
Jan 11, 2023
33ccc61 · Jan 11, 2023
Nov 28, 2022
Jan 11, 2023
Jan 10, 2023
Jan 11, 2023
Jan 11, 2023
Jan 11, 2023
Aug 19, 2022
Aug 19, 2022
Aug 19, 2022
Jan 9, 2023
Jan 11, 2023
Jan 5, 2023
Nov 28, 2022
Dec 15, 2022
Jan 11, 2023
Jan 11, 2023

Repository files navigation

Zotero Plugin Template

GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars

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 Type Definitions

📜Zotero Source Code

📌Zotero Plugin Template(This repo)

👍You are currently in bootstrap extension mode. To use overlay mode, plsase switch to overlay branch 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);
  • ⭐[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

image

  • registerStyleSheet(the official make-it-red example)
  • registerRightClickMenuItem
  • registerRightClickMenuPopup
  • registerWindowMenuWithSeprator
  • registerExtraColumn
  • registerExtraColumnWithCustomCell
  • registerCustomCellRenderer
  • registerLibraryTabPanel
  • registerReaderTabPanel
  • unregisterUIExamples

Quick Start Guide

  • Fork this repo;
  • 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 install to set up the plugin and install dependencies. If you don't have NodeJS installed, please download it here;
  • Run npm run build to build the plugin in production mode. Run npm run build-dev to build the plugin in development mode. The xpi for installation and the built code is under builds folder.

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.

About Hooks

See also src/hooks.ts

  1. When install/enable/startup triggered from Zotero, bootstrap.js > startup is called
    • Wait for Zotero ready
    • Load index.js (the main entrance of plugin code, built from index.ts)
    • Register resources if Zotero 7+
  2. In the main entrance index.js, the plugin object is injected under Zotero and hooks.ts > onStartup is called.
    • Initialize anything you want, including notify listeners, preference panes, and UI elements.
  3. When uninstall/disabled triggered from Zotero, bootstrap.js > shutdown is called.
    • events.ts > onShutdown is 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

@example
static registerPrefs() {
const prefOptions = {
pluginID: config.addonID,
src: rootURI + "chrome/content/preferences.xhtml",
label: getString("prefs.title"),
image: `chrome://${config.addonRef}/content/icons/favicon.png`,
extraDTD: [`chrome://${config.addonRef}/locale/overlay.dtd`],
defaultXUL: true,
};
ztoolkit.PreferencePane.register(prefOptions);
}
}

<preferences> element is deprecated. Please use the full pref-key in the elements' preference attribute. 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. Just unregister on exit.
  • Zotero 7 requires createElement()/createElementNS() → createXULElement() for remaining XUL elements, while Zotero 6 doesn't support createXULElement. Using createElement, it switches API depending on the current platform automatically.

There are more advanced APIs for creating elements in batch: creatElementsFromJSON. Input an element tree in JSON and return a fragment/element. These elements are also maintained by this plugin template.

Directory Structure

This section shows the directory structure of a template.

  • All .js/.ts code 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

Build

# 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

Alternatively, build it directly using build.js: npm run build

Build Steps

  1. Clean ./builds
  2. Copy ./addon to ./builds
  3. Esbuild to ./builds/addon/chrome/content/scripts
  4. Replace __buildVersion__ and __buildTime__ in ./builds/addon
  5. Zip the ./builds/addon to ./builds/*.xpi

Debug

  1. Copy zotero command line config file. Modify the commands.
cp ./scripts/zotero-cmd-default.json ./scripts/zotero-cmd.json
vim ./scripts/zotero-cmd.json
  1. Setup plugin development environment following this link.

  2. Build plugin and restart Zotero with this npm command.

  3. Launch Firefox 60

  4. In Firefox, go to devtools, go to settings, click "enable remote debugging" and the one next to it that's also about debugging(or press shift+F8).

  5. In Zotero, go to setting, advanced, config editor, look up "debugging" and click on "allow remote debugging"

  6. In Firefox, click the hamburger menu in the top right -> web developer -> Connect...

  7. Enter localhost:6100

  8. Connect

  9. Click "Inspect Main Process"

npm run restart

You can also debug code in these ways:

Development

Search for a Zotero API
Zotero docs are outdated or incomplete. Searching the source code of Zotero is unavoidable.
Clone https://github.com/zotero/zotero and search the keyword globally. You can search the UI text in .xul/.dtd files, and then search the keys of the text value in .js/.xul files.

⭐The zotero-types provides most frequently used Zotero APIs. It's included in this template by default.

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)