Контекст выделения
Когда пользователь выбирает элементы в Zotero, плагин строит структурированный контекст выделения (SelectionContext), который описывает, что выбрал пользователь и к какому типу относится каждый выбранный элемент. Этот контекст служит входной основой для хука buildRequest.
Типы выделения
На основе комбинации выбранных типов элементов selectionContext.selectionType возвращает одно из следующих значений:
| Тип | Описание |
|---|---|
"parent" | Все выбранные элементы являются родительскими элементами (элементами верхнего уровня) |
"child" | Все выбранные элементы являются дочерними элементами (элементами не верхнего уровня) |
"attachment" | Все выбранные элементы являются вложениями |
"note" | Все выбранные элементы являются заметками |
"mixed" | Выбранные элементы представляют собой смесь нескольких типов |
"none" | Никакие элементы не выбраны |
Структура контекста
selectionContext = {
selectionType: "parent", // Тип выделения
items: {
parents: [ /* Список родительских элементов */ ],
children: [ /* Список дочерних элементов */ ],
attachments: [ /* Список вложений */ ],
notes: [ /* Список заметок */ ],
},
summary: {
parentCount: 2,
childCount: 0,
attachmentCount: 0,
noteCount: 0,
},
warnings: [], // Предупреждения
sampledAt: "2026-01-15T...", // Время создания контекста
}
Каждый тип элемента содержит богатую контекстную информацию.
Родительский элемент (ParentContext)
Родительский элемент — это элемент верхнего уровня в библиотеке Zotero (например, статья журнала, книга, веб-страница и т.д.). Каждый контекст родительского элемента содержит:
{
item: Zotero.Item, // Объект элемента
id: number, // ID элемента
title: string, // Заголовок
attachments: [ // Дочерние вложения под этим элементом
{ type, filePath, mimeType, dateAdded, ... }
],
notes: [ // Дочерние заметки под этим элементом
{ id, content, ... }
],
tags: string[], // Список тегов
collections: string[], // Содержащие коллекции
children: [ // Другие дочерние элементы
{ id, type, ... }
],
}
Вложение (AttachmentContext)
Вложение — это файловое вложение элемента (PDF, Markdown и т.д.). Каждый контекст вложения содержит:
{
item: Zotero.Item, // Объект элемента вложения
id: number, // ID элемента
filePath: string, // Локальный путь к файлу
fileName: string, // Имя файла
mimeType: string, // MIME-тип (например, "application/pdf")
dateAdded: Date, // Дата добавления
parentItem: { // Владелец родительского элемента
id: number,
key: string,
libraryID: number,
},
tags: string[],
collections: string[],
}
Заметка (NoteContext)
{
item: Zotero.Item,
id: number,
content: string, // Содержимое заметки (HTML)
parentItem: { id, key, libraryID },
tags: string[],
}
Использование контекста выделения в хуках
Получение выбранных вложений
export function buildRequest({ selectionContext, runtime }) {
const attachments = selectionContext.items.attachments;
return {
kind: "skillrunner.job.v1",
create: { skill_id: "my-skill" },
input: {
files: attachments.map((attachment) => ({
path: runtime.helpers.getAttachmentFilePath(attachment),
name: runtime.helpers.getAttachmentFileName(attachment),
})),
},
};
}
Получение выбранных родительских элементов и их дочернего содержимого
export function buildRequest({ selectionContext, runtime }) {
const parents = selectionContext.items.parents;
for (const parent of parents) {
const title = parent.item.getField("title");
const attachments = parent.attachments; // Вложения под этим родительским элементом
const notes = parent.notes; // Заметки под этим родительским элементом
}
// ...
}
Проверка типа выделения для определения поведения
export function preflight({ selectionContext }) {
const { selectionType } = selectionContext;
if (selectionType === "none") {
// Никакие элементы не выбраны, пропустить
return { kind: "skip", reason: "no selected items" };
}
if (selectionType === "attachment") {
// Пользователь выбрал только вложения, использовать логику обработки вложений
} else if (selectionType === "parent") {
// Пользователь выбрал только родительские элементы, расширить первое подходящее вложение
}
return { kind: "continue", context: { selectionType } };
}
Фильтрация вложений
Используйте декларативный validateSelection для распространённой фильтрации вложений:
{
"validateSelection": {
"select": { "policy": "pdf-attachment" },
"require": {
"counts": { "attachments": 1 },
"allowMixed": false
}
}
}
Для решений только во время выполнения, зависящих от разрешённой единицы, используйте preflight для пропуска или продолжения:
export function preflight({ selectionContext, runtime }) {
const { helpers } = runtime;
const hasPdf = selectionContext.items.attachments.some(
a => helpers.isPdfAttachment(a)
);
if (!hasPdf) {
return { kind: "skip", reason: "no PDF attachments" };
}
return { kind: "continue" };
}
Workflow, когда никакие элементы не выбраны
Когда inputs.unit: "workflow" и trigger.requiresSelection: false, workflow может быть запущен без выбора каких-либо элементов. В этом случае selectionContext.selectionType равен "none", и все массивы в items пусты. Этот режим подходит для создания глобальных операций (например, "Создать синтез по теме").
Декларативная проверка выделения
Если вашему workflow нужно только пропускать элементы, которые уже имеют результаты, или фильтровать определённые типы входных данных, используйте декларативное поле validateSelection без написания JavaScript-хука.
{
"validateSelection": {
"select": { "policy": "literature-source" },
"exclude": [
{ "kind": "generated-notes-all", "noteKinds": ["digest"] }
]
}
}
Полную документацию см. в разделе Создание манифеста.
Руководство по выделению: Используйте декларативный
validateSelectionвсякий раз, когда это возможно — он не требует ни JavaScript, ни обслуживания. Сложная логика выделения может быть реализована в хукеbuildRequest.
Следующие шаги
- Справочник API хоста — Полный API для управления данными Zotero в хуках
- Создание манифеста — Определите типы единиц ввода workflow