插件间通信
插件间通信
可供参考的插件/文档
这里对之前调研的方式做一些归纳,以及补充
提前总结:
(结合我接下来要做的一个东西的选型,他们各自都有一些缺点)
- 事件注册方式、渲染驱动方式:拿不到返回值
- 全局状态方式:不够灵活,能分享的内容有限
- http方式、app.plugins.plugins方式:需要对方插件的配合
Http方式
这里有两个可供参考的插件:
- Local Rest API
- APIRequest
这两个插件我会在后面进行剖析、原理分析
事件注册方式
注册命令
渲染驱动
MarkdownRender()
方法
可以参考 https://any-block.github.io/obsidian-any-block/docs/zh/05.%20%E7%B2%BE%E5%BD%A9%E7%94%A8%E4%BE%8B.html 里的一些例子
全局状态方式
暂时不研究,因为不打算使用这种方式。
全局状态一般只适合分享一些比较小且固定、预定好的几个状态变量,不满足我的当前需求。
app.plugins.plugins 获取其他插件实例
各插件提供的API
参考:obsidian 群的 Moy 群友
- Templater:
app.plugins.plugins["templater-obsidian"].templater.current_functions_object
- TP 中调用 Obsidian 的 API:
tp.obsidian
- Dataview:
app.plugins.plugins.dataview.api
- QuickAdd:
this.quickAddApi
- Metaedit:
app.plugins.plugins["metaedit"].api
(来自 QuickAdd 的文档)
注册api
那么这些插件是如何注册api的呢?
见后面dataview的分析
参考插件深入剖析
dataview - 原理分析
参考: https://github.com/blacksmithgu/obsidian-dataview/blob/6d9030ef1df9c3f310f42e3502149dc71792dc4d/src/main.ts#L59
export default class DataviewPlugin extends Plugin {
public api: DataviewApi;
async onload() {
// From this point onwards the dataview API is fully functional (even if the index needs to do some background indexing).
this.api = new DataviewApi(this.app, this.index, this.settings, this.manifest.version);
// Register API to global window object.
(window["DataviewAPI"] = this.api) && this.register(() => delete window["DataviewAPI"]);
}
}
Local Rest API - 插件
- 接收外部的http请求,以执行一些操作。可用于自动化
- github: https://github.com/coddingtonbear/obsidian-local-rest-api star 712
- 其文档: https://coddingtonbear.github.io/obsidian-local-rest-api/
Local Rest API - 原理分析
APIRequest - 插件
- 发送http请求到外部,并获取响应值
- 官网
- github: https://github.com/Rooyca/obsidian-api-request star 126
- 文档: https://rooyca.github.io/obsidian-api-request/
- 我的fork (中文注释)
- github: https://github.dev/LincDemo/obsidian-api-request
- 文档: https://lincdocs.github.io/obsidian-api-request/
APIRequest - 原理分析
(部分在 注释fork 中)
.github | |
docs | |
src | |
functions | |
HtmlSanitizer.js | |
frontmatterUtils.ts | 解析前辅文 |
general.ts | 通用函数 |
mdparse.js | 简易的md解析 |
regx.ts | |
settings | |
settingsData.ts | 设置项定义 |
settingsTab.ts | 设置菜单,class APRSettings extends PluginSettingTab |
main.ts | 核心 |
(some files) | |
README.md | |
README.es.md | |
README.zh.md |
依赖 (package.json),并没有使用什么特别的库
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
}
主要流程:
- 都在
main.ts
中,注册代码块类型,回调使用异步回调,回调时:- 解析代码块
- http请求并获得响应 (
responseData = await requestUrl(...)
,这个是ob自己提供的方法,所以不需要其他依赖。如果你的插件要跨平台,需要写一个可以适配的方法) - 渲染响应和保留结果 (if isRender, if isSaveTo)
GPT调研 - 旧
kimi gpt:
注
Obsidian 插件之间可以互相通信,但需要通过一定的方法和 API 来实现。以下是一些相关的方法和 API:
直接插件间通信
- 插件 API:Obsidian 提供了一个插件 API,允许插件之间进行通信和交互。插件可以通过 API 访问其他插件的功能和数据。例如,插件可以注册命令、监听事件、访问其他插件的状态等- 。
- 插件状态共享:插件可以将数据存储在 Obsidian 的全局状态中,其他插件可以访问和修改这些状态。这样,不同插件之间可以共享数据,实现通信。
通过外部API通信
- Local REST API 插件:这个插件为 Obsidian 提供了一个本地的 REST API 服务,允许外部工具和插件通过 HTTP 请求与 Obsidian 进行交互。例如,一个插件可以通过发送 HTTP 请求调用另一个插件提供的 API,实现功能的调用和数据的交换- 。
- APIRequest 插件:这个插件允许 Obsidian 向外部 API 发送请求,并以 JSON 块或 Obsidian 变量的格式接收响应。插件之间可以通过调用外部 API 来实现间接的通信和数据交换。
通过事件监听通信
- 事件系统:Obsidian 的插件 API 提供了一个事件系统,插件可以监听和触发各种事件。例如,一个插件可以触发一个自定义事件,另一个插件监听该事件并执行相应的操作。通过这种方式,插件之间可以实现基于事件的通信。
通过插件扩展通信
- 编辑器扩展:对于编辑器相关的插件,可以通过扩展 Obsidian 的编辑器来实现通信。例如,一个插件可以创建一个编辑器扩展,并通过该扩展与其他插件进行交互。
总之,Obsidian 插件之间可以通过插件 API、外部 API、事件系统和插件扩展等多种方式实现互相通信。开发者可以根据具体的需求和场景选择合适的方法来实现插件之间的通信和协作
后来又问了一遍
注
在Obsidian中,插件之间可以通过以下几种方式实现通信:
1. 使用事件系统
Obsidian的API提供了一个事件系统,插件可以注册监听特定的事件,也可以触发事件。当一个插件触发事件时,其他插件可以监听到这个事件并作出相应的响应
- 注册事件监听器:插件可以注册一个事件监听器,当特定事件发生时,执行相应的回调函数。
- 触发事件:插件可以在适当的时候触发一个事件,通知其他插件某个动作已经发生或即将发生。
2. 使用插件API
Obsidian的API为插件提供了许多可以调用的方法和属性,插件可以通过这些API与其他插件进行通信。
- 获取插件实例:插件可以通过API获取其他插件的实例,然后调用这些插件提供的方法或访问其属性。
- 调用插件方法:如果一个插件公开了一些方法,其他插件可以直接调用这些方法来实现通信。
3. 使用全局状态
Obsidian提供了一些全局状态,插件可以读取或修改这些状态,从而实现插件之间的通信。
- 读取全局状态:插件可以读取全局状态中的数据,了解其他插件的状态或行为。
- 修改全局状态:插件可以修改全局状态,其他插件可以通过监听状态的变化来做出响应。
4. 使用插件之间的协议
一些插件可能会定义自己的通信协议,其他插件可以通过遵循这些协议来实现通信。
- 定义协议:一个插件可以定义一套通信协议,包括数据格式、通信方式等。
- 遵循协议:其他插件在与该插件通信时,需要遵循其定义的协议。
5. 使用HTTP API接口
对于一些需要与其他系统或插件进行复杂通信的场景,插件可以通过HTTP API接口实现。
- 提供API接口:插件可以提供HTTP API接口,其他插件或系统可以通过这些接口发送请求。
- 调用API接口:插件可以调用其他插件提供的HTTP API接口,获取数据或触发动作。
通过以上几种方式,Obsidian的插件之间可以实现灵活的通信,从而扩展和增强Obsidian的功能。开发者可以根据具体的需求和场景选择合适的通信方式。