Obsidian 插件:Abstract Folder 利用笔记属性渲染虚拟文件夹列表

[!example] 插件名片

  • 插件名称:Abstract Folder
  • 插件作者:RahmaniErfan
  • 插件版本:1.14.0
  • 插件概述:Abstract Folder在 Obsidian 中创建了一个虚拟文件浏览器,它的结构由用户在 Frontmatter 中定义。任何文件都可以是其它文件的“亲文件夹”;任何文件都无须一式多份,即可同时属于多个“文件夹”。如果用户想要修改上下级关系,只需改动文本即可,真实的文件系统结构不会受到任何改动。
  • 插件项目地址:点我跳转
  • 国内下载地址:下载安装

术语解说

以下作者在个人播客中写的一篇文章,说明了他为什么要写这个插件,在开始阅读插件文档之前,请先阅读这篇文章以期获得更深入的了解。

为什么使用文件夹

对于文件夹是什么,我就不多废话了。好吧,可能还是要说一下。文件夹早在操作系统和计算机出现之前就已经存在(是不是很意外)。它的理念是:一个文件夹代表一个通用类别,用来存放属于该类别的项目。这个文件夹会被放进一个抽屉,而这个抽屉又按更广泛、更通用的类别进行分类。文件夹本身也会有子类别,通过那些小标签进行组织。这个概念被引入操作系统中,而且它确实很合理。它们的工作方式是一样的。然而,当涉及到 PKM(个人知识管理)工具时,就出现了一个巨大的问题——过度分类的陷阱:“我最顶层的文件夹应该是什么?”“这个文件该放在这个文件夹,还是那个?好像两个都属于……”

为什么它们行不通

人类的思想是复杂的,复杂在它们之间的连接是无限的。而文件夹是刚性的;它们无法支撑这一复杂的连接系统。一个文件必须归属于单一一个文件夹,而一个想法却可以同时属于多个类别。

假设你刚开始记笔记。最初你的文件以扁平结构组织,没有创建任何文件夹。然后你决定要整理一下。你首先要做的是想出这些文件所属的最一般领域或范围。你决定分为 Work(工作)、Personal(个人)和 University(大学)。这些是居于所有其他类别之上的通用分类。你开始把文件分别放进对应的文件夹,直到某样东西让你停了下来。“嗯,这是一个日志文件。我在所有主分类下都有日志。那是不是意味着我要在每个主文件夹下面都创建一个‘日志’文件夹?”于是你这么做了。然后你意识到你希望有一个统一视图,可以快速查看所有日志。但你无法轻松做到这一点。于是你开始使用属性。你的工作日志文件会有一个值为 Work 的属性 ”domain“,还有一个值为 Logs 的 ”subdomain“。然后再用标签来细化。这听起来比创建无限的子子子子分类要好。两个属性加标签,似乎不错。

这听起来是不是非常非常耗时又令人沮丧?
是的,确实如此。至少对我来说是这样。所以我在想,应该有更好的方式。既然文件夹结构本身已经描述了文件——个人→个人计划→为什么文件夹烂透了——这个结构已经说明了一切。那为什么我们只是为了让这个僵硬的系统稍微灵活一点,就要被迫添加属性?

如何摆脱它

操作系统中文件夹的运作方式很简单(好吧,其实并非如此,但我会简化说明):你有一个文件夹,这个文件夹可以链接到其他文件夹。就这样——一个单一的值就决定了它们之间的关系。根文件夹则没有链接。

我把这个想法应用到了我制作的 Obsidian 插件中(顺便说一句,我还没提到它的名字,叫 Abstract Folder)。我意识到,文件夹结构本身已经描述了文件的分类。我所需要的只是一个单一的值,用来建立文件之间的连接。我甚至根本不需要文件夹,哈哈!而且,我还可以添加任意多个亲级!(后来我意识到这些文件还有其他用途,而且整个操作系统都是围绕文件夹构建的,所以彻底去掉文件夹会带来问题。)

我决定使用 Markdown 笔记的 Frontmatter 区来创建这种连接。简单的解决方案!现在,如果我有一个叫“为什么文件夹烂透了”的文件,我可以把它链接到一个名为“个人”的亲“文件夹”,它就等于被分类了,某种意义上。我将完全依赖这些连接,不需要任何“物理”文件夹。但这带来了一个问题。某些文件没有 Frontmatter。实际上,大多数文件都没有。如果你不知道什么是 Frontmatter,在 Obsidian 中,它基本上就是笔记顶部的 以 YAML 语言写成的笔记属性,用来列举元数据。

为了解决这个问题,有几种办法。但我意识到最简单也是最好的方案是使用单向关系。一个亲文件可以有亲级,但也可以同时有子级!因此,举例来说,在亲文件“个人计划”中,我会添加一个名为”children“的属性用来列出它的子文件。整个“文件夹结构”将通过同时查看 parents 和 children 来构建。

很多问题解决了,但还有一些。我之前提到完全没有文件夹会导致的问题。整个操作系统都依赖这个系统。如果你想把文件转移到其他地方,或者从 Obsidian 迁移到别的应用,一切都会变成扁平结构。所以我修复了这个问题。我创建了一个转换工具,可以根据文件之间的链接关系导出实际的文件夹结构。与此同时,我也创建了反向转换工具——将传统文件夹结构转换为这个插件使用的“抽象文件夹”格式。简单来说,这个转换工具会检查文件夹及其内容,并自动添加相应的属性。如果文件不是 Markdown 文件,它们会在亲文件中被声明为子文件。

我还添加了一些可用性功能:

  • 彩色缩进,用于区分树状视图的层级深度(可自定义)
  • 垂直 Miller 列视图,类似 macOS 中 Finder 的列视图,但方向为垂直排列
  • 工作区分组(Workspace groups):可以创建不同分组来切换过滤视图。例如,你的工作分组只显示 work.md 和 todo.md 的子文件
  • 图标

以及大量兼容性功能:

  • 显示非 Markdown 文件的文件格式
  • 右键菜单显示菜单项(包括其他插件的指令)
  • 通过右键创建笔记,可以在空白处创建,也可以在文件上下文中创建(例如在某个文件“下方”创建)
  • 别名(Aliases)
  • 排序
  • 以及一些我记不太清的小功能(概念上小,但开发起来并不小……)

当然,这个插件也不是完美无缺的。还是有一个问题。在传统文件夹系统中,只要位于不同文件夹,你可以拥有同名文件。但在扁平结构中不行。我考虑过一些解决方案,比如使用 ID 替代文件名,但那会带来其他问题。所以我选择添加别名功能。你可以使用一个具有描述性的真实文件名,然后添加 alias 属性作为显示名称;或者使用命令在重名时自动生成唯一文件名。

现在你拥有以下“特权”:

  • 可以把“文件夹”当作真正的文件使用!就像 Notion 那样。你可以在这个通用类别文件里直接记录相关内容。
  • 创建“幽灵节点”(ghost nodes)!你可以有一个名为 logs 的亲文件,而你的工作、个人和大学日志都可以连接到它,从而统一归类。
  • 图标!(虽然有其他插件也能实现,但我还是加了)
  • 不用担心“无法回退”,因为你可以随时把扁平结构转换回真实文件夹结构。
  • 隐藏笔记。是的,我差点忘了提。你可以隐藏整个抽象文件夹!

你也可以给我打赏,链接在 GitHub 仓库里 ;)。我也许应该把这句话放在最前面,因为不是每个人都会读到这里。不过如果你读到了,谢谢你的阅读!

基本用法

简单来说,Abstract Folder的原理就是根据笔记属性中规定的亲子关系,渲染出一个虚拟文件夹列表,与笔记文件在系统资源管理器中的实际位置无关,如此一来,无须再操心文件的物理位置,哪怕所有文件都以扁平结构位于库下,只要笔记属性中存在亲子关系,插件就能在虚拟文件夹列表中虚拟地渲染出文件夹结构

  • 在命令面板中执行Abstract Folder: Open View命令,然后手动在笔记属性区为当前文件指定其亲文件,
    • 具有单个亲文件的子文件的笔记属性例`parent: “[[亲文件名1]]”
    • 具有多个亲文件的子文件的笔记属性例:parent: ["[[亲文件名1]]", "[[亲文件名2]]"]
  • 如果用户希望自上而下地指定亲子关系,对于不支持属性区的格式比如白板、Excalidraw、图片或 pdf 等文件,可以在亲文件的笔记属性区将它们指定为子文件,例:`children: [“[[子文件名1]]”, “[[子文件名2]]”]
  • 同一个文件可以有多个亲文件或多个子文件,建议将属性格式设置为列表
  • 如果用户想要为某子文件更换亲文件,直接在虚拟文件夹列表中拖拽即可,直接拖拽是剪切,按住Ctrl键同时拖拽是复制,笔记属性区会自动更改

将已有文件夹架构转化为虚拟文件夹

如果想将已有文件夹架构转化为虚拟文件夹(原文件夹结构并不会被破坏),点击Abstract Folder虚拟文件夹列表上方工具栏左起第三个按钮,或执行命令面板中的Abstract Folder: Convert folder structure to plugin format命令,在选择需要转换的文件夹后,会弹出如图对话框

  • Create parent notes:如启用,若将要转换的文件夹没有一个同名文件,则为它创建一个
  • Existing relationships:如将要转换的文件夹下的文件的parent属性中已指定亲文件,则
    • Append new parents:在parent属性的末尾加上新的亲文件
    • Replacing existing parents:将原有亲文件转换为新制定的亲文件
  • Folder note strategy:决定要在哪里搜索将要转换的文件夹的同名文件
    • Outside (Sibling note, e.g. "Folder.md" next to " Folder/"):在该文件夹外,与其平级
    • Inside (Index note, e.g. "Folder/Folder.md"):在该文件夹内
      点击确认后,插件会自动为文件夹中的子文件创建parent属性(属性名文本可在设置中修改)并指定亲文件

Abstract Folder虚拟文件夹列表渲染效果如图:

也可以在命令面板中执行Abstract Folder: Create folder stucture from plugin format命令,将原来并非处于文件夹结构,但已经在笔记属性区指定亲/子文件的文件在系统资源管理器中创建传统的文件夹结构

自定义分组视图

如果想列出某个特定笔记文件的所有子文件,可点击Abstract Folder虚拟文件夹列表上方工具栏左起第八个按钮,在下拉菜单中选择Manage groups再选择Add new group,或执行命令面板中的Abstract Folder: Manage groups会弹出如下对话框

  • Group name:在空白栏中填入的文本将被视为分组名
  • Add parent note: 在空白栏中填入需要作为亲文件的笔记文件点击加号选择库内笔记文件

如果想直接以当前笔记文件为亲文件创建分组,在命令面板中执行Abstract Folder: Creat group with active file命令即可

独特排序

点击虚拟文件夹列表最上方工具栏左起第六个按钮,可以对文件进行排序,除了常见的首字母、创建时间和修改时间之外,Abstract Folder还提供了以下三种独特的排序方式:

  • Sort by thermal:插件会根据每 24 小时内的最新程度和互动辨别库的哪一部分当前正在使用,一个笔记文件被打开得越多,其亲子关系变化得越多,它的分数就越高
  • Sort by stale rot:插件会根据笔记文件的最后一次编辑日期计算其不活跃时间,一个笔记文件的子文件越多,而且其不活跃时间越长,它的分数就越高,有助于用户重温重要但被忽视已久的笔记
  • Sort by gravity:插件会计算含子文件最多的亲文件,并据此进行排序

设置说明

  • Excluded Paths:在空白栏中填入的文件夹路径将被插件忽略
  • Properties
    • Parent Property Names:在空白栏中填入的属性名称将被用来指定该笔记文件的亲文件,可设置多个,用英文逗号隔开,区分大小写
    • Children Property Names:在空白栏中填入的属性名称将被用来指定该笔记文件的子文件,可设置多个,用英文逗号隔开,区分大小写
    • Created date field names:在空白栏中填入的属性名称将被用来存放该笔记文件的创建时间
    • Modified date field names:在空白栏中填入的属性名称将被用来存放该笔记文件的最后一次修改时间
  • Display name
    • Show Aliases:如启用,则aliases属性的第一个值将被用作文件在虚拟文件夹列表中的显示名
    • Display name priority:在空白栏中有三个属性名称,分别为basenamealiasestitle,它们分别代表文件在系统资源管理器中的文件名、笔记属性中用aliases指定的别名、用title指定的标题,用户可自定义其先后顺序以决定其在虚拟文件夹列表中的优先级,用英文逗号隔开
  • Behavior
    • Expand parent folder for active file:如启用,则插件将自动在虚拟文件夹列表中展开当前文件的所有亲文件,并高亮当前文件
    • Scroll to active file:如启用,则虚拟文件夹列表将自动滚动至该文件位置以展示其亲子关系
    • Expand children when opening a file:如启用,则插件将自动在虚拟文件夹列表中展开当前文件的直接子文件
    • Expand target folder on drap & drop:如启用,在虚拟文件夹列表中拖拽文件时,目的亲文件将自动展开
    • Remember expanded folders:如启用,则哪怕用户转换视图或重启软件,虚拟文件夹列表也将保持上一次的展开状态
  • Startup & Layout
    • Default new note path:在空白栏中填入的文件夹路径将被视作新文件的默认创建路径,如留空,则新文件将被默认创建在库根目录下
    • Open on Startup:如启用,则虚拟文件夹列表将随 Obsidian 自动启动
    • Open Position:选择虚拟文件夹列表是在左侧边栏还是右侧边栏
    • Show Ribbon Icon:如启用,则将在功能区显示插件的命令按钮
  • Visuals
    • Enable Rainbow Indents:如启用,则虚拟文件夹列表将用彩色缩进线在视觉上区分层级
    • Rainbow Palette:为彩色缩进线选择样式
    • Rainbow indent-varied item colors:启用后没看出来有什么变化
  • Toolbar & Search
    • 前十个选项依次为:自定义是否展示虚拟文件夹列表上方工具栏的搜索、视图切换、聚焦当前文件、转换虚拟文件夹/真实文件夹、全部收起、全部展开、排序、筛选、分组和新建笔记按钮
    • Max menu name length:在 10-100 范围内选择右击文件名唤出的菜单所能显示的最大文件名字符数
  • Naming conflicts
    • Conflict resolution strategy: 在扁平结构内,如何处理重名文件,可以选择分别命名、亲文件或最上级亲文件
    • Conflict separator:选择是用 dash 还是 bracket 来隔开亲文件名和文件名,例:亲文件名 - 文件名亲文件名 [文件名]
    • Conflict naming order:选择是亲文件名在前还是文件名在前
  • Debug:向插件作者反映 bug 用的,不高兴翻译了,自己看吧,看不懂说明你用不上
3 个赞

感谢分享
感觉和卡片笔记法的关键词卡片概念有点像