如何自动检索文件并生成可见链接列表

遇到的问题

我在使用Obsidian写日记,以日为单位创建文件,但不方便回顾。

预期的效果

我希望的效果是:以「yymmdd」为标题创建日记文件,同时也以月份或年份为标题创建文件,在这个文件里能自动生成这个时间范围内的文件的可见链接列表。

例如,在「23年11月」这个标题的文件下,自动生成

  • ![[231101]]
  • ![[231102]]
  • ![[231103]]

这样的可见链接列表。当然,如果没有列表,直接分行引用各个文件也可以。这样在回顾日记时就可以按月为单位,而不用一篇一篇点击每日日记。

或者也可以模仿「五年日记」,建立按日为单位的文件,例如在「1月1日」这个文件中,自动生成

  • ![[210101]]
  • ![[220101]]
  • ![[230101]]

这样可以看看自己每年这个日子在做些什么。

已尝试的解决方案

尝试了Dataview,但似乎只能生成带标题链接的列表,无法生成可见链接,即只能生成类似

  • [[231101]]
  • [[231102]]
  • [[231103]]

这样我还是要点进链接才能看到具体内容,和在文件夹中直接点击没有区别。

另外也尝试了Daily Notes Editor这个插件,但它只能在一个页面里按时间顺序浏览所以日记,也不太能满足我的预期。

Dataview 插件可以用 DataviewJS。

DataviewJS 代码:

// 获取路径下笔记并排除当前笔记
let files = dv.pages(`"zz/日记"`).filter(p=>p.file.name!=dv.current().file.name)
// 处理路径下笔记
files.map(async function(p) {
    // 获取路径下笔记内容
    let content = await app.vault.readRaw(p.file.path)
    // 显示笔记名:6级标题链接形式
    dv.header(6, p.file.link);
    // 显示笔记内容
    dv.paragraph(content)
})

效果展示:

简单使用,你把想要回顾的文件放在一个路径下,把 zz/日记 改成对应路径即可(外面的 ` 和 " 都不可以动)。

想加排序和筛选,可以根据你具体文件命名格式和你具体想怎么筛选,自己找找教程,改改代码。

2 个赞

谢谢您!我再搜搜具体的教程

如果你的笔记名和你示例一样,你可以把第一行改成下面这样:

// 获取路径下笔记,以笔记名升序排序、选择笔记名以“日记”开头的笔记
let files = dv.pages(`"zz/日记"`).sort(p=>p.file.name, 'asc').filter(p=>p.file.name.startsWith("日记"))

把想要回顾的文件放在一个路径下,把 zz/日记 改成对应路径(外面的 ` 和 " 都不可以动)。

若想按降序排序,把 asc 改为 desc

筛选「23年11月」,把 .startsWith("") ("") 中的 日记 改为 2311

1 个赞

非得用插件实现吗?
你都生成生成带标题链接的列表了,直接文档中把[[替换为![[不行吗?

谢谢您的建议,我现在给单篇日记命名的方法是「YY-MMDD」,比如「23-1117」。我这两天看了一些教程,在您最初给的代码基础上改了一下, 比如「2023年」视图的筛选代码是

// 获取路径下的笔记,筛选标题包含「23-」的笔记,按标题升序排列
let files = dv.pages('\"1 日记\"')
	.filter(p => p.file.name.includes("23-"))
	.sort(p => p.file.name, 'asc');

另外我检索「所有11月17日的日记」的方法是,建立名为「1117」的文件,然后利用代码

let files = dv.pages(‘"1 日记"’)
.filter(p => p.file.name.includes(dv.current().file.name))
.sort(p => p.file.name, ‘asc’);

这样不用改代码,只用建立对应日期的文件,粘贴进去就能自动生成。再次谢谢您的帮助

您好,我生成带标题链接的列表也是靠插件,另外我觉得利用全局替换还是有些繁琐。现在已经基本解决了,谢谢您的回复

既然你用文件名作变量建表,也不用每次都粘贴了,直接复用就行。

复用的好处是假如以后你需要修改代码,不用每个文件都改一遍。

你筛选部分的代码需要改为:

// 获取活动文件名(不含扩展名)
let riqi = app.workspace.getActiveFile().basename
// 获取路径下笔记,选择标题包含活动文件名的笔记,按标题升序排列
let files = dv.pages(`"1 日记"`)
    .filter(p => p.file.name.includes(riqi))
    .sort(p => p.file.name, 'asc')

假如你存放 dataviewJS 的笔记为“日记索引.md”,你只需在想看这个表的笔记(如“1117.md”)里直接嵌入 ![[日记索引]]

效果展示:

20231117_205326

因为是通过嵌入的方式实现复用,
所以嵌入的样式和你在 Ob 里嵌入其他笔记是一样的,
因此特别要注意是否应用了类似屏蔽嵌入链接标题的 CSS。
我就是自己写了个 CSS 屏蔽了嵌入链接笔记标题及 1-6 级标题,
导致显示不出 6 级标题链接形式的笔记名,
还以为 dataviewJS 代码哪里写错了,找了半天,十分尴尬。

下面两块加起来即效果展示同款嵌入块 CSS:

.internal-embed:not(.image-embed),
.internal-embed:not(.image-embed) p {
  border: none; /*嵌入线*/
  padding-left: 0; /*文本与嵌入线间距*/
}

找到适合自己的方法就好,我也借宝地简单分享点我的经验吧。

不用插件的话,用全局搜索功能加正则表达式,
如整理23年日记,输入:file:/23-\d{2}\d{2}/
然后复制结果到文件里粘贴,并搜索替换[[

生成过程也不麻烦,
缺点是生成的文件列表,不能随日记增减而自动更新。

用插件的话,我以前用过 Text expend,
将他的默认模板改成- !$link后,
例如 列出23年11月日记,则直接在文档中输入代码:

    ```expander
    file:/23-11\d{2}/ 
    ```

就可以了。和全局搜索的命令一样。
这个的优点是可以实现自动更新列表,和更丰富的模板。

五年日记的正则表达式简单写法:
18到22年6月1日的五年日记:file:/1[89]-\06\01|2[012]-\06\01/

以上两种方式生成的文档,即使不安装插件,任然正常显示。