【已解决】我想创建一个过滤属性表,点击按钮便可以筛选出不同来源的文章

遇到的问题

我喜欢浏览哔哩哔哩和知乎并摘抄我喜欢的评论,会在 YAML 中设置 source作为区分。我希望使用 Dataview 语法创建一个过滤筛选表,这个筛选表上有两个按钮,分别是哔哩哔哩和知乎。我不懂 DataviewJS语法,即便刷到了相关的帖子也不能根据自己的需求改,所以特来论坛求助。

预期的效果

点击哔哩哔哩的按钮时,会自动筛选出 source 为哔哩哔哩的文章,其他按钮类似。

已尝试的解决方案

我在 OBSIDIAN 的英文论坛中刷到了类似功能的帖子,并进行了修改,可以根据tags和source按钮实现过滤功能:

// Don't change this code

const {createButton} = app.plugins.plugins["buttons"]
const tp = app.plugins.plugins["templater-obsidian"].templater.current_functions_object

let current = dv.current()
let currentFile = app.vault.getAbstractFileByPath(current.file.path)

const changeFilter = async(prop) => {
  let propName = "filter-" + prop
  let values = pages.map(p => p[prop])
  values = [...new Set(values)]
  values.unshift("all")
  let val = await tp.system.suggester(values, values)
    app.fileManager.processFrontMatter(currentFile, (frontmatter) => { 
		frontmatter[propName] = val
	})
  }

const filterButton = async(name, prop) => {
  createButton({
	app, 
	el: this.container, 
	args: {
		name: name}, 
	clickOverride: {
		click: await changeFilter, 
		params: [prop]
	}
  })
}

const filterFunction = async(prop) => {
  let propName = "filter-" + prop
  let filter = current[propName]
  if (filter != "all" && filter != null) {
	filteredPages = filteredPages.filter(p => p[prop] == filter)
  }
}




// Only edit the code below

let pages = dv.pages('"001 素材收藏"')
let filteredPages = [...pages]


// Apply filters
await filterFunction("tags")
await filterFunction("source")

// Add filter buttons
await filterButton("Filter Tags", "source")
await filterButton("Filter Source", "source")


let headers = ["Name", "tags", "Number"]
let rows = filteredPages.map(p => [p.file.link, p.tags, p.source])

dv.table(headers, rows)
1 个赞

最后在 CHATGPT 的帮助下成功了,代码如下:

// Don't change this code

const {createButton} = app.plugins.plugins["buttons"]
const tp = app.plugins.plugins["templater-obsidian"].templater.current_functions_object

let current = dv.current()
let currentFile = app.vault.getAbstractFileByPath(current.file.path)

const changeFilter = async (buttonName) => {
  let propName = "filter-source"
  let val = buttonName === "All" ? null : buttonName
  app.fileManager.processFrontMatter(currentFile, (frontmatter) => {
    frontmatter[propName] = val
  })
}

const filterButton = async (name) => {
  createButton({
    app,
    el: this.container,
    args: {
      name: name
    },
    clickOverride: {
      click: async () => await changeFilter(name),
      params: []
    }
  })
}

const filterFunction = async () => {
  let filter = current["filter-source"]
  if (filter != null) {
    filteredPages = filteredPages.filter(p => p.source === filter)
  }
}

// Only edit the code below

let pages = dv.pages('"001 素材收藏"')
let filteredPages = [...pages]

// Apply filters
await filterFunction()

// Add filter buttons
await filterButton("All")
await filterButton("哔哩哔哩")
await filterButton("知乎")
await filterButton("小红书")

let headers = ["Name", "Source"]
let rows = filteredPages.map(p => [p.file.link, p.source])

dv.table(headers, rows)

1 个赞

唯一麻烦的一点是每次点按钮都要等一会

1 个赞

原来的英文帖子在这里:Live filtering of dataviewjs table - Share & showcase - Obsidian Forum

1 个赞

仅对于这点需求,可以如下处理:

  1. 在 搜索 中,输入 ["source":知乎]
  2. 点击 n项结果 右边的三个点符号,将结果保存到书签
  3. 重复1-2步,创建 哔哩哔哩 的书签

筛选时直接书签里点击就好,还是会在搜索中显示结果