Obsidian Templater 插件的实用代码片段,用于模板中的交互式数据输入。
工具类型与分类选择器
在创建工具卡片时,通过多级弹窗让用户依次选择工具类型和对应分类,支持多选。选中的结果格式化为 wikilink 数组,供模板 frontmatter 使用。
使用场景
- 适用于
tp-卡片-工具这类需要填写tool_types/tool_categories的模板。 - 依赖 Dataview 与 Templater:
dv.pages("#tool/type")读取工具类型,tp.system.suggester负责交互式选择。 - 片段会在每次选择后从候选列表中移除已选项,避免重复选择;按 ESC 结束当前层级选择。
输出结果
最终得到两个数组:selectedTypes 与 selectedCategories。数组元素会被格式化为 "[[名称]]",可以直接拼入 YAML frontmatter 的列表字段。
// tool types and categories
let types = await dv.pages("#tool/type")
.sort(p => p.tool_type_id)
.map(p => p.file.name)
.array();
let categories = await dv.pages("#tool/category")
.sort(p => [p.tool_type_id, p.tool_category_id])
.groupBy(p => p.tool_type_id)
.map(p => p.rows.map(r => r.file.name).array())
.array();
const typeCategories = Object.fromEntries(types.map((t, i) => [t, categories[i]]));
let selectMoreTypes = true;
let selectedTypes = [];
let selectedCategories = [];
while (selectMoreTypes) {
let selectedType = await tp.system.suggester(types, types, false,
"[Select tool type (ESC when finished)] - " + selectedTypes.join(", ")
);
if (!selectedType) {
break;
}
selectedTypes.push(selectedType);
types = types.filter(t => t !== selectedType);
let currentCategories = typeCategories[selectedType];
while (true) {
let selectedCategory = await tp.system.suggester(currentCategories, currentCategories, false,
"[Select tool category (ESC when finished)] - " + selectedCategories.join(", ")
);
if (!selectedCategory) {
break;
}
selectedCategories.push(selectedCategory);
currentCategories = currentCategories.filter(c => c !== selectedCategory);
}
}
selectedTypes = selectedTypes.map(t => `"[[${t}]]"`);
selectedCategories = selectedCategories.map(c => `"[[${c}]]"`);