๋ทฐ(Views)๋Š” Obsidian์ด ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ํƒ์ƒ‰๊ธฐ, ๊ทธ๋ž˜ํ”„ ๋ทฐ, ๋งˆํฌ๋‹ค์šด ๋ทฐ๋Š” ๋ชจ๋‘ ๋ทฐ์˜ ์˜ˆ์‹œ์ด์ง€๋งŒ, ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋งž๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๋ทฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๋ทฐ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ItemView ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค:

import { ItemView, WorkspaceLeaf } from 'obsidian';
 
export const VIEW_TYPE_EXAMPLE = 'example-view';
 
export class ExampleView extends ItemView {
  constructor(leaf: WorkspaceLeaf) {
    super(leaf);
  }
 
  getViewType() {
    return VIEW_TYPE_EXAMPLE;
  }
 
  getDisplayText() {
    return 'Example view';
  }
 
  async onOpen() {
    const container = this.contentEl;
    container.empty();
    container.createEl('h4', { text: 'Example view' });
  }
 
  async onClose() {
    // ์ •๋ฆฌํ•  ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค.
  }
}

Note

createEl() ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ HTML elements๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฐ ๋ทฐ๋Š” ํ…์ŠคํŠธ ๋ฌธ์ž์—ด๋กœ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ์ž‘์—…์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ทฐ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ€์ด๋“œ์˜ ๋’ท๋ถ€๋ถ„์—์„œ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ฒ˜๋Ÿผ, ์ด๋ฅผ ์ƒ์ˆ˜ VIEW_TYPE_EXAMPLE๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • getViewType()์€ ๋ทฐ์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • getDisplayText()๋Š” ๋ทฐ์˜ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • onOpen()์€ ์ƒˆ ๋ฆฌํ”„(leaf) ๋‚ด์—์„œ ๋ทฐ๊ฐ€ ์—ด๋ฆด ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ ๋ทฐ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • onClose()๋Š” ๋ทฐ๊ฐ€ ๋‹ซํ˜€์•ผ ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ ๋ทฐ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๋ทฐ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํ™œ์„ฑํ™”๋  ๋•Œ ๋“ฑ๋ก๋˜๊ณ  ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋น„ํ™œ์„ฑํ™”๋  ๋•Œ ์ •๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

import { Plugin, WorkspaceLeaf } from 'obsidian';
import { ExampleView, VIEW_TYPE_EXAMPLE } from './view';
 
export default class ExamplePlugin extends Plugin {
  async onload() {
    this.registerView(
      VIEW_TYPE_EXAMPLE,
      (leaf) => new ExampleView(leaf)
    );
 
    this.addRibbonIcon('dice', 'Activate view', () => {
      this.activateView();
    });
  }
 
  async onunload() {
  }
 
  async activateView() {
    const { workspace } = this.app;
 
    let leaf: WorkspaceLeaf | null = null;
    const leaves = workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE);
 
    if (leaves.length > 0) {
      // ์šฐ๋ฆฌ ๋ทฐ๊ฐ€ ์žˆ๋Š” ๋ฆฌํ”„๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋ฏ€๋กœ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      leaf = leaves[0];
    } else {
      // ์ž‘์—… ๊ณต๊ฐ„์—์„œ ์šฐ๋ฆฌ ๋ทฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ
      // ์˜ค๋ฅธ์ชฝ ์‚ฌ์ด๋“œ๋ฐ”์— ์ƒˆ ๋ฆฌํ”„๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
      leaf = workspace.getRightLeaf(false);
      await leaf.setViewState({ type: VIEW_TYPE_EXAMPLE, active: true });
    }
 
    // ์ถ•์†Œ๋œ ์‚ฌ์ด๋“œ๋ฐ”์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฆฌํ”„๋ฅผ "๋“œ๋Ÿฌ๋ƒ…๋‹ˆ๋‹ค".
    workspace.revealLeaf(leaf);
  }
}

registerView()์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋“ฑ๋กํ•˜๋ ค๋Š” ๋ทฐ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

Warning

ํ”Œ๋Ÿฌ๊ทธ์ธ์—์„œ ๋ทฐ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ ˆ๋Œ€ ๊ด€๋ฆฌํ•˜์ง€ ๋งˆ์„ธ์š”. Obsidian์€ ๋ทฐ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ทฐ์—์„œ ๋ถ€์ž‘์šฉ์„ ํ”ผํ•˜๊ณ , ๋ทฐ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค getLeavesOfType()์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

this.app.workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE).forEach((leaf) => {
  if (leaf.view instanceof ExampleView) {
    // ๋ทฐ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
  }
});