logseq / logseq/plugins

[Feature Request] Extend Plugin API for full ontology import/export parity in DB graphs

オープン
#32 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
HTML
スター
26
フォーク
8
PR マージ指標
30日以内にマージされた PR はありません

説明

Problem Statement

The Plugin API for DB graphs does not support all fields that Logseq exports in its native EDN format. This prevents plugins from implementing complete ontology import/export functionality.

When users export ontology from a DB graph and attempt to re-import it via a plugin, some data is lost:

Data Type Fields in EDN Export Fields Settable via API Lost on Import
Properties 14 10 4 fields (29%)
Classes/Tags 7 6 1 field (14%)
What Works (Discovered Feb 2025)

Through extensive console testing, we discovered workarounds for several fields:

System Description Field

Using the full namespaced key with upsertBlockProperty sets the system description:

// ❌ WRONG - creates a user property named "description"
await logseq.Editor.upsertBlockProperty(uuid, 'description', 'My description')

// ✅ CORRECT - sets the system logseq.property/description field
await logseq.Editor.upsertBlockProperty(uuid, ':logseq.property/description', 'My description')

The value is stored as an entity reference (Logseq creates a new entity containing the text).

Tabler Icons on Properties and Tags

setBlockIcon() works for Tabler icons on properties and tags:

// ✅ Works - Tabler icon on property
const prop = await logseq.Editor.getProperty('my-property')
await logseq.Editor.setBlockIcon(prop.uuid, 'tabler-icon', 'star')

// ✅ Works - Tabler icon on tag
const tag = await logseq.Editor.getTag('MyTag')
await logseq.Editor.setBlockIcon(tag.uuid, 'tabler-icon', 'folder')
What Doesn't Work
Emoji Icons - Lookup Table Inaccessible

setBlockIcon() fails for all emoji formats:

await logseq.Editor.setBlockIcon(uuid, 'emoji', 'rocket')     // ❌ "Can't find emoji for rocket"
await logseq.Editor.setBlockIcon(uuid, 'emoji', '🚀')         // ❌ "Can't find emoji for 🚀"
await logseq.Editor.setBlockIcon(uuid, 'emoji', ':rocket:')   // ❌ "Can't find emoji for :rocket:"

Root cause: Logseq's emoji lookup table is internal and not accessible to plugins. The EDN export shows emojis stored with numeric IDs (e.g., {:type :emoji, :id "100"}) but there's no way for plugins to discover or use these IDs.

Class/Tag Title - Ownership Restriction

Attempting to set :logseq.class/title fails:

await logseq.Editor.upsertBlockProperty(tagUuid, ':logseq.class/title', 'My Display Title')
// ❌ Error: "Plugins can only upsert its own properties"

Unlike :logseq.property/description which works, the title field is blocked.

Remaining Fields Not Settable via Plugin API
Properties
Missing Field Impact
icon (emoji only) Cannot set emoji icons (Tabler icons work)
closedValues Cannot create enum/choice/select properties
datetime type Must downgrade to date (loses time component)
position Cannot control UI ordering
default Cannot set default values
Classes/Tags
Missing Field Impact
icon (emoji only) Cannot set emoji icons (Tabler icons work)
title Cannot set display name (blocked by ownership restriction)
position Cannot control UI ordering
Use Case

I'm building an ontology import plugin that allows users to:

  1. Export ontology definitions from one DB graph
  2. Share them via a marketplace/repository
  3. Import them into another DB graph

Currently, imported ontologies lose emoji icons, enum configurations (closedValues), and display titles. Tabler icons and descriptions now import successfully.

Proposed Solutions
1. Expose emoji lookup or accept emoji characters directly

Either:

  • Option A: Accept emoji characters directly in setBlockIcon: setBlockIcon(uuid, 'emoji', '🚀')
  • Option B: Accept standard emoji names: setBlockIcon(uuid, 'emoji', 'rocket')
  • Option C: Document the emoji ID format so plugins can use it
2. Add closedValues support to upsertProperty
upsertProperty(key: string, schema?: {
  // Existing fields...

  // Requested addition
  closedValues?: Array<{
    value: string;
    icon?: { type: "emoji" | "tabler-icon"; id: string };
    description?: string;
  }>;
}): Promise<IEntityID>
3. Allow setting class/tag title

Either remove the ownership restriction for :logseq.class/title or add it to the createTag options:

createTag(name: string, opts?: {
  uuid?: string;  // Existing
  title?: string; // Requested
}): Promise<PageEntity>
4. Add datetime property type

Currently datetime must be downgraded to date, losing the time component.

Priority Ranking
  1. 🔴 Critical: Fix emoji icon setting (expose lookup or accept characters) - Icons are the primary visual identity of ontology elements; losing them during import significantly degrades the user experience
  2. 🔴 Critical: Add closedValues support to upsertProperty - Required for enum/select properties
  3. 🟡 Medium: Allow setting class/tag title
  4. 🟡 Medium: Add datetime property type
  5. 🟢 Low: Add position to schema APIs
Environment
  • Logseq version: 2.0.0 (DB graph mode)
  • Platform: Windows
  • Plugin API version: @logseq/libs latest
What We Learned (Testing Details)

For reference, here's what we discovered through console testing:

Feature Method Status
System Description upsertBlockProperty(uuid, ':logseq.property/description', text) ✅ Works
Tabler Icons setBlockIcon(uuid, 'tabler-icon', 'iconName') ✅ Works
Emoji Icons setBlockIcon(uuid, 'emoji', ...) ❌ All formats fail
Class Title upsertBlockProperty(uuid, ':logseq.class/title', text) ❌ Ownership blocked
Icon via upsertBlockProperty upsertBlockProperty(uuid, ':logseq.property/icon', {...}) ❌ Renders "Invalid icon"

Key insight: setBlockIcon stores icons as {type: 'tablerIcon', id: 'name'} (camelCase), but setting this format directly via upsertBlockProperty still renders as "Invalid icon" - there's internal processing in setBlockIcon that can't be replicated.

Additional Context

Full field-by-field reconciliation available here: API Field Reconciliation Document

This enhancement would enable a richer ecosystem of ontology sharing and template plugins for DB graphs.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

issue で挙げられている @logseq/libs のエントリポイント、setBlockIcon、upsertProperty、upsertBlockProperty、createTag から始めます。docs/api-field-reconciliation.md を読み、文書化されている DB グラフのインポート/エクスポートの不足を再現します。要求されたオントロジーフィールド(emoji アイコン、closedValues、タイトル、datetime、position を含む)が plugin API 経由でラウンドトリップできれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
api
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。