How to define custom functions & assign them to item types
Last updated
Step 1 : Define a global function
Custom functions must be defined with the syntax window.myFuncName = function(item) { ... } rather than function myFuncName(item){ ... } , otherwise an error will be thrown. This syntax is needed to make the function globally available, so that it can be found by the extension.
Step 2 : Construct your metadata template within the function
All formatting functions must do the following :
The function must take a single argument - the item's data object, as returned by the Zotero Web API. See here for an official gist from the Zotero API docs, showing an example object returned for a single item.
The function must return a single array - specifying the contents of the blocks that should be added to the item's page in Roam.
Each element of the array will be processed as a top-level Roam block to be added to the item's Roam page. If the element is a String of text, the block will be childless. If the element is an Object, it can have children blocks (see Nesting metadata).
String elements will be added as top-level, childless blocks.
Object elements will be processed recursively and support nested blocks.
The ordering of the blocks in Roam will reflect the ordering of the array.
To help you with writing your own functions, I've made an Observable interactive notebook, where you can try your hand at writing functions & using them to process your own Zotero data :
Default formatting function
// By default, the extension uses the following function :zoteroRoam.formatting.getItemMetadata=function(item){// Initialization of the array of blocks :let metadata = [];// Title of the itemif (item.data.title) {metadata.push(`Title:: ${item.data.title}`) };// Creators of the itemif (item.data.creators.length>0) {metadata.push(`Author(s):: ${zoteroRoam.formatting.getCreators(item)}`) };// Abstract for the itemif (item.data.abstractNote) { metadata.push(`Abstract:: ${item.data.abstractNote}`) };// Type of the itemif (item.data.itemType) {metadata.push(`Type:: [[${zoteroRoam.formatting.getItemType(item)}]]`) };// Publication/Book titlemetadata.push(`Publication:: ${item.data.publicationTitle ||item.data.bookTitle ||""}`)// URLif (item.data.url) {metadata.push(`URL : ${item.data.url}`) };// Date the item was added to Zoteroif (item.data.dateAdded) {metadata.push(`Date Added:: ${zoteroRoam.utils.makeDNP(item.data.dateAdded, {brackets:true})}`) };// Links to the item in Zotero (local + web links)metadata.push(`Zotero links:: ${zoteroRoam.formatting.getLocalLink(item)}, ${zoteroRoam.formatting.getWebLink(item)}`); // Local + Web links to the item// Tags attached to the itemif (item.data.tags.length>0) {metadata.push(`Tags:: ${zoteroRoam.formatting.getTags(item)}`) };// Requesting the item's PDF files + noteslet children =zoteroRoam.formatting.getItemChildren(item, {pdf_as:"links", notes_as:"formatted", split_char:"\n"});// Links to the PDF filesif(children.pdfItems){metadata.push(`PDF links : ${children.pdfItems.join(", ")}`); }// Contents of notesif(children.notes){let notesBlock = {string:`[[Notes]]`, children: []};notesBlock.children.push(...children.notes.flat(1));metadata.push(notesBlock); }return metadata; }
Step 3 : Assign the function to item types
Custom functions can be assigned to item types using funcmap. You can assign a function to specific item types, or set it as the default formatting function.
Assigning the customPaperFormat function to be used for conference papers and journal articles, and letting the extension handle other item types with its own defaults.