Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
dev:client_coding:javascript_api [2018/09/08 17:16] – [API Methods] new subsubsection about creating a new collection zuphilip | dev:client_coding:javascript_api [2019/01/22 04:26] – [API Methods] dstillman | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | < | + | < |
- | in the process of updating the documentation | + | |
- | <a href=" | + | |
- | may be outdated in the meantime. Thanks for your understanding.</ | + | |
====== Zotero JavaScript API ====== | ====== Zotero JavaScript API ====== | ||
- | Whereas Zotero' | + | Whereas Zotero' |
Note that the (mostly user-contributed) documentation of the JavaScript API is not comprehensive. If you use the JavaScript API in ways beyond what's described here, please consider expanding this wiki page. | Note that the (mostly user-contributed) documentation of the JavaScript API is not comprehensive. If you use the JavaScript API in ways beyond what's described here, please consider expanding this wiki page. | ||
- | ===== Helpful Resources ===== | ||
- | For this section, you’ll likely find the following helpful: | + | ===== Running Ad Hoc JavaScript in Zotero ===== |
- | * A basic understanding of how to create a Firefox extension | + | Zotero 5.0.61 and later include |
- | * [[http:// | + | |
- | * [[https:// | + | |
- | * A decent grasp of object-oriented JavaScript | + | |
- | * [[http:// | + | |
- | * [[http:// | + | |
- | ===== An Easy Debugging Environment ===== | + | - In the Advanced pane of the Zotero preferences, |
+ | - In the Tools menu, select Run JavaScript. Open the Error Console, which also appears in Tools, will also be helpful. | ||
+ | - In the window that opens, enter JavaScript in the Code textbox and click Run or press Cmd-R/ | ||
- | Various Firefox extensions create servers within Firefox that expose | + | To run asynchronous code, check the "Run as async function" |
- | * [[https:// | + | In synchronous mode, the value of the final line will appear |
- | * [[http:// | + | |
- | * [[http:// | + | |
- | * **Potential MozRepl Problems**: Longer scripts can time out non-deterministically. A solution to this is to either send the code to the terminal application | + | |
- | Perl programmers should be aware of the [[http:// | + | (Before Zotero 5.0.61 is released, you'll need to install |
+ | ===== Window Scope vs. Non-Window Scope ==== | ||
+ | Zotero code exists in either window scope and non-window scope. | ||
- | ===== The Zotero | + | Window scope applies to code that runs within either the main Zotero window or a secondary window (e.g., the Advanced Search window). It has access to the window' |
- | Zotero exposes an object-oriented JavaScript API that can be used to access and modify Zotero data. Within | + | Non-window scope applies to lower-level code that doesn' |
- | ==== XPCOM ==== | + | Overlays and windows in Zotero can import the core '' |
- | A common problem in developing Mozilla extensions is figuring out how to pass data between different windows, which have their own scopes and do not by default share the same variables and code. While there are various mechanisms to get around this, the [[http:// | + | To access Zotero functionality from your own extension, you will need access |
- | The base Zotero service is an XPCOM component written in JavaScript. While normally XPCOM components implement various predefined interfaces themselves, in Zotero the data layer and most of the core functionality are stored within a JavaScript object that is then stuffed into the special '' | + | <code html> |
+ | <script | ||
+ | </ | ||
- | Access to the Zotero service is not limited to Zotero itself, however. As a standard XPCOM component, the Zotero service---and, | + | Once you have '' |
- | + | ||
- | To access the data API in your own extension, you will need access to the core Zotero JavaScript object. If your extension operates within the main browser overlay, | + | |
- | + | ||
- | %%chrome:// | + | |
<code javascript> | <code javascript> | ||
- | var Zotero | + | var zp = Zotero.getActiveZoteroPane(); |
- | .getService(Components.interfaces.nsISupports) | + | var items = zp.getSelectedItems(); |
- | .wrappedJSObject; | + | </ |
- | </ | + | (The Zotero pane will always be available unless the main window is closed, as is possible on macOS.) |
===== Notification System ===== | ===== Notification System ===== | ||
Line 74: | Line 63: | ||
//The Zotero JavaScript API is under-documented, | //The Zotero JavaScript API is under-documented, | ||
- | |||
- | Once you have access to the core Zotero object, you can use the objects and methods provided by the Zotero JavaScript API. | ||
- | |||
- | Zotero uses a combination of instantiatable objects (e.g. '' | ||
==== Adding items and modifying data ==== | ==== Adding items and modifying data ==== | ||
- | A typical operation might include a call to '' | + | A typical operation might include a call to '' |
<code javascript> | <code javascript> | ||
- | var creator = new Zotero.Creator; | + | var item = new Zotero.Item(' |
- | creator.firstName = ' | + | |
- | creator.lastName = ' | + | |
- | creator.save(); | + | |
- | + | ||
- | var item = new Zotero.Item; | + | |
- | item.setType(Zotero.ItemTypes.getID(' | + | |
item.setField(' | item.setField(' | ||
- | item.setCreator(0, creator, 'author'); | + | item.setCreators( |
- | var itemID = item.save(); | + | [ |
+ | { | ||
+ | firstName: " | ||
+ | lastName: " | ||
+ | creatorType: | ||
+ | } | ||
+ | ] | ||
+ | ); | ||
+ | var itemID = await item.save(); | ||
+ | return itemID; | ||
</ | </ | ||
Line 105: | Line 93: | ||
alert(item.getCreator(0)); | alert(item.getCreator(0)); | ||
// | // | ||
+ | // Alternative format | ||
+ | alert(item.getCreatorJSON(0)); | ||
+ | // | ||
+ | |||
item.setField(' | item.setField(' | ||
item.setField(' | item.setField(' | ||
- | item.save(); // update database with new data | + | await item.saveTx(); // update database with new data |
</ | </ | ||
- | ==== Create new Zotero object ==== | + | ==== Get the Zotero Pane to interact with the Zotero |
- | + | ||
- | This is the first thing that you need to do when interacting with Zotero' | + | |
- | internals. | + | |
- | + | ||
- | <code javascript> | + | |
- | var Zotero = Components.classes[" | + | |
- | </ | + | |
- | + | ||
- | ==== Get the Zotero Pane to interact with the Zotero | + | |
<code javascript> | <code javascript> | ||
- | var ZoteroPane = Components.classes[" | + | var ZoteroPane = Zotero.getActiveZoteroPane(); |
</ | </ | ||
- | Then grab the currently selected items from the zotero | + | Then grab the currently selected items from the Zotero |
<code javascript> | <code javascript> | ||
- | //get first selected item | + | // Get first selected item |
- | var selected_items | + | var selectedItems |
- | var item = selected_items[0]; | + | var item = selectedItems[0]; |
- | // proced | + | // Proceed |
- | if ( ! item.isCollection() | + | if (item && !item.isNote()) { |
if (item.isAttachment()) { | if (item.isAttachment()) { | ||
// find out about attachment | // find out about attachment | ||
} | } | ||
if (item.isRegularItem()) { | if (item.isRegularItem()) { | ||
- | // we could grab attachments: | + | // We could grab attachments: |
- | // var att_ids | + | // let attachmentIDs |
- | // if (att_ids.length> | + | // let attachment |
- | // item_att=Zotero.Items.get(att_ids[0]); | + | |
} | } | ||
alert(item.id); | alert(item.id); | ||
Line 148: | Line 130: | ||
</ | </ | ||
- | ==== Setup a Zotero search | + | ==== Collection Operations |
- | If you are focused on data access, then the first thing you will want to do | + | === Get the items in the selected collection === |
- | will be to retrieve | + | |
- | good start. | + | |
- | <code javascript> | + | <code javascript> |
+ | var collection | ||
+ | var items = collection.getChildItems(); | ||
+ | // or you can obtain an array of itemIDs instead: | ||
+ | var itemIDs = collection.getChildItems(true); | ||
+ | </ | ||
- | ==== Search for items containing | + | === Create |
- | Starting with the code from "Setup a Zotero | + | <code javascript> |
- | code to retrieve items with a particular tag: | + | var currentCollection = ZoteroPane.getSelectedCollection(); |
+ | var collection = new Zotero.Collection(); | ||
+ | collection.name = name; | ||
+ | collection.parentID = currentCollection.id; | ||
+ | var collectionID = await collection.saveTx(); | ||
+ | return collectionID; | ||
+ | </code> | ||
- | <code javascript> | + | ==== Zotero Search Basics ==== |
- | ==== Zotero Collection Operations ==== | + | If you are focused on data access, |
- | + | will be to retrieve items from your Zotero library. Creating an in-memory search is a | |
- | === Get the collection tree and display as a series of nested ordered lists === | + | good start. |
- | + | ||
- | This code was developed | + | |
<code javascript> | <code javascript> | ||
- | var Zotero | + | var s = new Zotero.Search(); |
- | + | s.libraryID | |
- | var render_collection = function(coll) { | + | |
- | if (!coll) { | + | |
- | coll = null; | + | |
- | } | + | |
- | var collections | + | |
- | document.writeln("< | + | |
- | for (c in collections) { | + | |
- | document.writeln('< | + | |
- | if (collections[c].hasChildCollections) { | + | |
- | var childCol = render_collection(collections[c].id); | + | |
- | } | + | |
- | } | + | |
- | document.writeln("</ | + | |
- | } | + | |
- | + | ||
- | render_collection(); | + | |
</ | </ | ||
- | === Get the items for a particular collection | + | === Search |
- | <code javascript> | + | Starting with the above code, we then use the following |
- | var Zotero = Components.classes[" | + | |
- | var collectionid = pow_server.GET.id; | + | |
- | var collection = z.Collections.get(collectionid); | + | |
- | var items = collection.getChildItems(); | + | |
- | // or you can obtain an array of itemIDs instead: | + | |
- | var itemids = collection.getChildItems(true); | + | |
- | </code> | + | |
- | + | ||
- | === Create a New Collection | + | |
<code javascript> | <code javascript> | ||
- | async function createCollection(name) { | + | s.addCondition(' |
- | let collection = new Zotero.Collection(); | + | var itemIDs |
- | | + | |
- | | + | |
- | return collectionID; | + | |
- | } | + | |
</ | </ | ||
- | ==== Zotero Search Basics ==== | + | === Advanced searches |
- | + | ||
- | === Set up the search | + | |
<code javascript> | <code javascript> | ||
var s = new Zotero.Search(); | var s = new Zotero.Search(); | ||
+ | s.libraryID = Zotero.Libraries.userLibraryID; | ||
s.addCondition(' | s.addCondition(' | ||
- | // advanced search | + | // advanced search |
</ | </ | ||
- | To add the other conditions available in the advanced search | + | To add the other conditions available in the advanced search |
<code javascript> | <code javascript> | ||
Line 240: | Line 199: | ||
=== Search by collection === | === Search by collection === | ||
- | To search for a collection or a saved search you need to know the ID: | + | To search for a collection or a saved search you need to know the ID or key: |
<code javascript> | <code javascript> | ||
- | s.addCondition(' | + | s.addCondition(' |
s.addCondition(' | s.addCondition(' | ||
+ | </ | ||
+ | |||
+ | <code javascript> | ||
+ | s.addCondition(' | ||
+ | s.addCondition(' | ||
</ | </ | ||
Line 252: | Line 216: | ||
<code javascript> | <code javascript> | ||
- | | + | var tagName |
- | | + | s.addCondition(' |
</ | </ | ||
Line 265: | Line 229: | ||
results: | results: | ||
- | <code javascript> | + | <code javascript> |
- | This returns the item ids in the search as an array [I could be wrong ... ]. | + | This returns the item ids in the search as an array. The next thing to do is to get the Zotero items for the array of IDs: |
- | The next thing to do is to get the Zotero items for the array of IDs: | + | |
- | <code javascript> | + | <code javascript> |
===== Managing citations and bibliographies ===== | ===== Managing citations and bibliographies ===== | ||
Line 283: | Line 246: | ||
First we start with a list of as in the previous entry. | First we start with a list of as in the previous entry. | ||
- | <code javascript> | + | <code javascript> |
- | var biblio = qc.getContentFromItems(new Array(item), | + | var biblio = qc.getContentFromItems([item], Zotero.Prefs.get(" |
- | z.Prefs.get(" | + | var biblio_html_format = cite.html; |
- | var biblio_html_format = cite.html; | + | var biblio_txt |
- | var biblio_txt | + | |
</ | </ | ||
Line 293: | Line 255: | ||
<code javascript> | <code javascript> | ||
- | | + | await Zotero.Schema.schemeUpdatePromise; |
- | var style_info | + | var styles = Zotero.Styles.getVisible(); |
- | for each ( var s in styles) { | + | var styleInfo |
- | style_info.push( { "id" | + | for (let style of styles) { |
- | | + | |
- | | + | } |
+ | return styleInfo; | ||
</ | </ | ||
Line 311: | Line 274: | ||
To get an item's abstract, we get the ' | To get an item's abstract, we get the ' | ||
- | <code javascript> | + | <code javascript> |
==== Get child notes for an item ==== | ==== Get child notes for an item ==== | ||
Line 317: | Line 280: | ||
To get the child notes for an item, we use the following code: | To get the child notes for an item, we use the following code: | ||
- | <code javascript> | + | <code javascript> |
- | This returns an array of notes. | + | This returns an array of ids of note items. To get each note in turn we just iterate through the array: |
- | in turn we just iterate through the array: | + | |
<code javascript> | <code javascript> | ||
- | | + | for (let id of noteIDs) { |
- | | + | |
- | var note_html | + | let noteHTML |
- | } | + | } |
</ | </ | ||
==== Get an item's related items ==== | ==== Get an item's related items ==== | ||
- | This technique works for anything that can have related items attached within | + | <code javascript> |
- | the Zotero database. | + | |
- | <code javascript> | + | ==== Set two items as related to each other ==== |
- | This returns a list of items just like in the search examples. | + | Given two items '' |
+ | to each other by using the '' | ||
- | ==== Get an Item's Attachments === | + | <code javascript> |
+ | await itemA.saveTx(); | ||
+ | itemB.addRelatedItem(itemA); | ||
+ | await itemB.saveTx();</ | ||
- | Here's some example code to get the full text of HTML and PDF items in storage and puts the data in an array: | + | |
+ | ==== Get an item's attachments === | ||
+ | |||
+ | Here's some example code to get the full text of HTML and PDF items in storage and put the data in an array: | ||
<code javascript> | <code javascript> | ||
- | var item = 'some item' | + | var item = ZoteroPane.getSelectedItems()[0]; |
- | var fulltext = new Array; | + | var fulltext = []; |
if (item.isRegularItem()) { // not an attachment already | if (item.isRegularItem()) { // not an attachment already | ||
- | | + | |
- | for (a in attachments) { | + | for (let id of attachmentIDs) { |
- | | + | |
- | if (a_item.attachmentMIMEType | + | if (attachment.attachmentContentType |
- | || a_item.attachmentMIMEType | + | || attachment.attachmentContentType |
- | fulltext.push(a_item.attachmentText); | + | fulltext.push(await attachment.attachmentText); |
} | } | ||
} | } | ||
} | } | ||
+ | return fulltext; | ||
</ | </ | ||
Line 401: | Line 370: | ||
The list of field names to use can be retrieved via the server API: https:// | The list of field names to use can be retrieved via the server API: https:// | ||
- | |||
- | ==== Example: Delete All Automatic Tags ==== | ||
- | |||
- | <code javascript> | ||
- | Zotero.Tags.erase(Object.keys(Zotero.Tags.getAll([tagType])))</ | ||
==== Example: Delete Tags By Name ==== | ==== Example: Delete Tags By Name ==== |