Add reference to collection when tag is present #377
-
A little while ago I came across this script #245 by @garth74, which, if an item is present in a collection, will add a tag of the same name to the item. // ========================================================================== //
// EDITABLE SETTINGS
// ========================================================================== //
/**
* @type {string} Prefix tags set during this script (e.g., "coll-tagName").
* This makes it easier to search and remove tags later.
*/
const tagPrefix = "#";
/**
* @type {boolean} If true, trim any leading underscore characters from the
* collection name.
*/
const trimLeadingUnderscores = true;
/**
* @type {boolean} If true, trim any leading numbers (i.e., 0-9) from the
* collection name.
*/
const trimLeadingNumbers = false;
/**
* @type {string[]} Names of collections to exclude from tagging.
*/
const exclude = [];
// ========================================================================== //
// Main
// ========================================================================== //
/**
* Convert the tag name to a collection name.
*
* @param {string[]} tagNames
* @returns {string[]}
*/
function TagNames2CollNames(tagNames) {
if (trimLeadingUnderscores)
tagNames = tagNames.map((t) => t.replace(/^_+/, "").trim());
if (trimLeadingNumbers)
tagNames = tagNames.map((t) => t.replace(/[0-9]+/, "").trim());
return tagNames.map((t) => t.replace(tagPrefix, ""));
}
/**
* Get all collections in the library.
*
* @param {number} libraryID
* @returns {any[]}
*/
function getAllCollections(libraryID) {
return Zotero.Collections.getByLibrary(libraryID);
}
/**
* Add item to collections based on its tags.
*
* @param {any} item
* @returns {string[]} Names of collections the item was added to.
*/
function addItemToCollections(item) {
let itemTags = item.getTags().map((t) => t.tag);
let collNames = TagNames2CollNames(itemTags);
let collections = getAllCollections(item.libraryID);
let addedCollections = [];
for (let collName of collNames) {
if (exclude.includes(collName)) continue;
let collection = collections.find((c) => c.name === collName);
if (collection && !collection.hasItem(item.id)) {
collection.addItem(item.id);
addedCollections.push(collName);
}
}
return addedCollections;
}
// ========================================================================== //
// TRIGGERED IN ITEM MENU
if (item) {
let addedCollections = addItemToCollections(item);
if (addedCollections.length > 0) {
return `[Collection Tags] Added item to collections: ${addedCollections.join(", ")}`;
} else {
return "[Collection Tags] No matching collections found or item already in collections";
}
} else {
return "[Collection Tags] No item is selected";
} While it correctly identifies collections which it should be added to, and can see if it is already there with the "collection.hasItem(item.id)" function, for some reason the "collection.addItem(item.id);" function is not adding the reference to the correct collections, even though the source code has that function https://github.com/zotero/zotero/blob/main/chrome/content/zotero/xpcom/data/collection.js. Does anyone know what might cause this one line to, not give an error, but finish without having done what it is supposed to do? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Try adding |
Beta Was this translation helpful? Give feedback.
-
I appreciate what you've done! One problem though is that it seems to successfully match and move only if the folder that matches the tag is the parent folder of the first level. When the target folder is a sub-folder of any level, it returns that 'No matching collections found or item already in collections'. I've checked and made sure that the section of code for folder matching is the same as yours. Is it because the method |
Beta Was this translation helpful? Give feedback.
Ah my apologies I misread item.addItemToCollection()! Yes that does work!
Full working code is therefore: