์ด ํ์ด์ง๋ ํ๋ฌ๊ทธ์ธ ์์ฑ์๊ฐ ํ๋ฌ๊ทธ์ธ์ ์ ์ถํ ๋ ํํ ๋ฐ๋ ๋ฆฌ๋ทฐ ์๊ฒฌ์ ๋์ดํฉ๋๋ค.
์ด ํ์ด์ง์ ๊ฐ์ด๋๋ผ์ธ์ ๊ถ์ฅ ์ฌํญ์ด์ง๋ง, ์ฌ๊ฐ์ฑ์ ๋ฐ๋ผ ์๋ฐ ์ฌํญ์ ํด๊ฒฐํ๋๋ก ์๊ตฌํ ์ ์์ต๋๋ค.
ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ์๋ฅผ ์ํ ์ ์ฑ
Developer policies์ Submission requirements for plugins๋ฅผ ๋ฐ๋์ ์ฝ์ด๋ณด์ธ์.
์ผ๋ฐ
์ ์ญ ์ฑ ์ธ์คํด์ค ์ฌ์ฉ ํผํ๊ธฐ
์ ์ญ ์ฑ ๊ฐ์ฒด์ธ app (๋๋ window.app) ์ฌ์ฉ์ ํผํ์ธ์. ๋์ ํ๋ฌ๊ทธ์ธ ์ธ์คํด์ค์์ ์ ๊ณตํ๋ ์ฐธ์กฐ์ธ this.app์ ์ฌ์ฉํ์ธ์.
์ ์ญ ์ฑ ๊ฐ์ฒด๋ ๋๋ฒ๊น ๋ชฉ์ ์ผ๋ก ๋ง๋ค์ด์ก์ผ๋ฉฐ ํฅํ ์ ๊ฑฐ๋ ์ ์์ต๋๋ค.
๋ถํ์ํ ์ฝ์ ๋ก๊น ํผํ๊ธฐ
๋ถํ์ํ ๋ก๊น ์ ํผํด์ฃผ์ธ์. ๊ธฐ๋ณธ ์ค์ ์์๋ ๊ฐ๋ฐ์ ์ฝ์์ ์ค๋ฅ ๋ฉ์์ง๋ง ํ์๋์ด์ผ ํ๋ฉฐ, ๋๋ฒ๊ทธ ๋ฉ์์ง๋ ํ์๋์ง ์์์ผ ํฉ๋๋ค.
ํด๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ ๋ฒ ์ด์ค ์ ๋ฆฌ ๊ณ ๋ คํ๊ธฐ
ํ๋ฌ๊ทธ์ธ์ด ํ๋ ์ด์์ .ts ํ์ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ๋ฆฌ๋ทฐ์ ์ ์ง๋ณด์๋ฅผ ์ฉ์ดํ๊ฒ ํ๊ธฐ ์ํด ํด๋๋ก ์ ๋ฆฌํ๋ ๊ฒ์ ๊ณ ๋ คํด๋ณด์ธ์.
ํ๋ ์ด์คํ๋ ํด๋์ค ์ด๋ฆ ๋ฐ๊พธ๊ธฐ
์ํ ํ๋ฌ๊ทธ์ธ์๋ MyPlugin, MyPluginSettings, SampleSettingTab๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ธ ํด๋์ค์ ๋ํ ํ๋ ์ด์คํ๋ ์ด๋ฆ์ด ํฌํจ๋์ด ์์ต๋๋ค. ํ๋ฌ๊ทธ์ธ ์ด๋ฆ์ ๋ฐ์ํ๋๋ก ์ด ์ด๋ฆ๋ค์ ๋ณ๊ฒฝํ์ธ์.
๋ชจ๋ฐ์ผ
Transclude of Mobile-development#node-and-electron-apis
Transclude of Mobile-development#lookbehind-in-regular-expressions
UI ํ ์คํธ
์ด ์น์ ์ ์ค์ , ๋ช ๋ น์ด, ๋ฒํผ ๋ฑ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ํ ์คํธ ์์ ์ง์ ์ ๋ํ ๊ฐ์ด๋๋ผ์ธ์ ๋์ดํฉ๋๋ค.
์๋ Settings โ Appearance์ ์์๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค ํ ์คํธ์ ๋ํ ๊ฐ์ด๋๋ผ์ธ์ ๋ณด์ฌ์ค๋๋ค.

- ์ผ๋ฐ ์ค์ ์ ์๋จ์ ์์ผ๋ฉฐ ์ ๋ชฉ์ด ์์ต๋๋ค.
- ์น์ ์ ๋ชฉ์๋ โsettingsโ๋ผ๋ ๋จ์ด๊ฐ ํฌํจ๋์ง ์์ต๋๋ค.
- Use Sentence case in UI.
Obsidian์ฉ ํ ์คํธ ์์ฑ ๋ฐ ์์ ์ง์ ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์คํ์ผ ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์.
์ค์ ์๋์ ์น์ ์ด ๋ ๊ฐ ์ด์์ธ ๊ฒฝ์ฐ์๋ง ์ ๋ชฉ ์ฌ์ฉํ๊ธฐ
์ค์ ํญ์ โGeneralโ, โSettingsโ ๋๋ ํ๋ฌ๊ทธ์ธ ์ด๋ฆ๊ณผ ๊ฐ์ ์ต์์ ์ ๋ชฉ์ ์ถ๊ฐํ์ง ๋ง์ธ์.
์ค์ ์๋์ ์น์ ์ด ๋ ๊ฐ ์ด์ ์๊ณ ๊ทธ์ค ํ๋์ ์ผ๋ฐ ์ค์ ์ด ํฌํจ๋ ๊ฒฝ์ฐ, ์ ๋ชฉ์ ์ถ๊ฐํ์ง ์๊ณ ์๋จ์ ์ ์งํ์ธ์.
์๋ฅผ ๋ค์ด, Settings โ Appearance ์๋์ ์ค์ ์ ๋ณด์ธ์.
์ค์ ์ ๋ชฉ์ โsettingsโ ํผํ๊ธฐ
์ค์ ํญ์์ ์ค์ ์ ์ ๋ฆฌํ๊ธฐ ์ํด ์ ๋ชฉ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด ์ ๋ชฉ์ โsettingsโ๋ผ๋ ๋จ์ด๋ฅผ ํฌํจํ์ง ๋ง์ธ์. ์ค์ ํญ ์๋์ ๋ชจ๋ ๊ฒ์ด ์ค์ ์ด๋ฏ๋ก ๋ชจ๋ ์ ๋ชฉ์ ๋ฐ๋ณตํ๋ ๊ฒ์ ์ค๋ณต์ ๋๋ค.
- โAdvanced settingsโ ๋์ โAdvancedโ๋ฅผ ์ ํธํฉ๋๋ค.
- โSettings for templatesโ ๋์ โTemplatesโ๋ฅผ ์ ํธํฉ๋๋ค.
UI์์ ๋ฌธ์ฅ ์ผ์ด์ค ์ฌ์ฉํ๊ธฐ
UI ์์์ ๋ชจ๋ ํ ์คํธ๋ Title Case ๋์ Sentence case๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋ฌธ์ฅ ์ผ์ด์ค์์๋ ๋ฌธ์ฅ์ ์ฒซ ๋จ์ด์ ๊ณ ์ ๋ช ์ฌ๋ง ๋๋ฌธ์๋ก ํ๊ธฐํฉ๋๋ค.
- โTemplate Folder Locationโ ๋์ โTemplate folder locationโ์ ์ ํธํฉ๋๋ค.
- โCreate New Noteโ ๋์ โCreate new noteโ๋ฅผ ์ ํธํฉ๋๋ค.
<h1>, <h2> ๋์ setHeading ์ฌ์ฉํ๊ธฐ
HTML์ ์ ๋ชฉ ์์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ ๊ฐ์ ์คํ์ผ์ด ์ผ๊ด๋์ง ์์ ์ ์์ต๋๋ค. ๋์ ๋ค์์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํด์ผ ํฉ๋๋ค:
new Setting(containerEl).setName('your heading title').setHeading();๋ณด์
innerHTML, outerHTML, insertAdjacentHTML ํผํ๊ธฐ
์ฌ์ฉ์ ์ ์ ์
๋ ฅ์ ์ฌ์ฉํ์ฌ innerHTML, outerHTML, insertAdjacentHTML๋ก DOM ์์๋ฅผ ๋ง๋๋ ๊ฒ์ ๋ณด์ ์ํ์ ์ด๋ํ ์ ์์ต๋๋ค.
๋ค์ ์์ ๋ ์ฌ์ฉ์ ์
๋ ฅ ${name}์ ํฌํจํ๋ ๋ฌธ์์ด์ ์ฌ์ฉํ์ฌ DOM ์์๋ฅผ ๋ง๋ญ๋๋ค. name์ <script>alert()</script>์ ๊ฐ์ ๋ค๋ฅธ DOM ์์๋ฅผ ํฌํจํ ์ ์์ผ๋ฉฐ, ์ ์ฌ์ ์ธ ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉ์์ ์ปดํจํฐ์์ ์์์ ์ฝ๋๋ฅผ ์คํํ๋๋ก ํ์ฉํ ์ ์์ต๋๋ค.
function showName(name: string) {
let containerElement = document.querySelector('.my-container');
// ์ด๋ ๊ฒ ํ์ง ๋ง์ธ์
containerElement.innerHTML = `<div class="my-class"><b>Your name is: </b>${name}</div>`;
}๋์ , createEl(), createDiv(), createSpan()๊ณผ ๊ฐ์ DOM API ๋๋ Obsidian ํฌํผ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก DOM ์์๋ฅผ ๋ง๋์ธ์. ์์ธํ ๋ด์ฉ์ HTML elements๋ฅผ ์ฐธ์กฐํ์ธ์.
HTML ์์์ ๋ด์ฉ์ ์ ๋ฆฌํ๋ ค๋ฉด el.empty();๋ฅผ ์ฌ์ฉํ์ธ์.
๋ฆฌ์์ค ๊ด๋ฆฌ
ํ๋ฌ๊ทธ์ธ์ด ์ธ๋ก๋๋ ๋ ๋ฆฌ์์ค ์ ๋ฆฌํ๊ธฐ
์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๊ฐ์ด ํ๋ฌ๊ทธ์ธ์ ์ํด ์์ฑ๋ ๋ชจ๋ ๋ฆฌ์์ค๋ ํ๋ฌ๊ทธ์ธ์ด ์ธ๋ก๋๋ ๋ ํ๊ดด๋๊ฑฐ๋ ํด์ ๋์ด์ผ ํฉ๋๋ค.
๊ฐ๋ฅํ๋ฉด registerEvent() ๋๋ addCommand()์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ฌ๊ทธ์ธ์ด ์ธ๋ก๋๋ ๋ ๋ฆฌ์์ค๋ฅผ ์๋์ผ๋ก ์ ๋ฆฌํ์ธ์.
export default class MyPlugin extends Plugin {
onload() {
this.registerEvent(this.app.vault.on('create', this.onCreate));
}
onCreate: (file: TAbstractFile) => {
// ...
}
}Note
ํ๋ฌ๊ทธ์ธ์ด ์ธ๋ก๋๋ ๋ ์ ๊ฑฐ๊ฐ ๋ณด์ฅ๋๋ ๋ฆฌ์์ค๋ ์ ๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, DOM ์์์
mouseenter๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํ๋ฉด ํด๋น ์์๊ฐ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋ฉ๋๋ค.
onunload์์ ๋ฆฌํ(leaf) ๋ถ๋ฆฌํ์ง ์๊ธฐ
์ฌ์ฉ์๊ฐ ํ๋ฌ๊ทธ์ธ์ ์ ๋ฐ์ดํธํ ๋, ์ด๋ ค ์๋ ๋ชจ๋ ๋ฆฌํ๋ ์ฌ์ฉ์๊ฐ ์ด๋๋ก ์ฎ๊ฒผ๋์ง์ ๊ด๊ณ์์ด ์๋ ์์น์์ ๋ค์ ์ด๊ธฐํ๋ฉ๋๋ค.
๋ช ๋ น์ด
๋ช ๋ น์ด์ ๊ธฐ๋ณธ ๋จ์ถํค ์ค์ ํผํ๊ธฐ
๊ธฐ๋ณธ ๋จ์ถํค๋ฅผ ์ค์ ํ๋ฉด ํ๋ฌ๊ทธ์ธ ๊ฐ์ ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ผ๋ฉฐ ์ฌ์ฉ์๊ฐ ์ด๋ฏธ ๊ตฌ์ฑํ ๋จ์ถํค๋ฅผ ๋ฎ์ด์ธ ์ ์์ต๋๋ค.
๋ํ ๋ชจ๋ ์ด์ ์ฒด์ ์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ณธ ๋จ์ถํค๋ฅผ ์ ํํ๊ธฐ ์ด๋ ต์ต๋๋ค.
๋ช ๋ น์ด์ ์ ์ ํ ์ฝ๋ฐฑ ์ ํ ์ฌ์ฉํ๊ธฐ
ํ๋ฌ๊ทธ์ธ์ ๋ช ๋ น์ด๋ฅผ ์ถ๊ฐํ ๋ ์ ์ ํ ์ฝ๋ฐฑ ์ ํ์ ์ฌ์ฉํ์ธ์.
- ๋ช
๋ น์ด๊ฐ ๋ฌด์กฐ๊ฑด ์คํ๋๋ ๊ฒฝ์ฐ
callback์ ์ฌ์ฉํฉ๋๋ค. - ๋ช
๋ น์ด๊ฐ ํน์ ์กฐ๊ฑด์์๋ง ์คํ๋๋ ๊ฒฝ์ฐ
checkCallback์ ์ฌ์ฉํฉ๋๋ค.
๋ช
๋ น์ด์ ์ด๋ ค ์๊ณ ํ์ฑํ๋ ๋งํฌ๋ค์ด ์๋ํฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ, editorCallback ๋๋ ํด๋น editorCheckCallback์ ์ฌ์ฉํ์ธ์.
์์ ๊ณต๊ฐ
workspace.activeLeaf์ ์ง์ ์ ๊ทผ ํผํ๊ธฐ
ํ์ฑ ๋ทฐ์ ์ ๊ทผํ๋ ค๋ฉด ๋์ getActiveViewOfType()๋ฅผ ์ฌ์ฉํ์ธ์:
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
// getActiveViewOfType์ ํ์ฑ ๋ทฐ๊ฐ null์ด๊ฑฐ๋ MarkdownView๊ฐ ์๋ ๊ฒฝ์ฐ null์ ๋ฐํํฉ๋๋ค.
if (view) {
// ...
}ํ์ฑ ๋
ธํธ์ ์๋ํฐ์ ์ ๊ทผํ๋ ค๋ฉด ๋์ activeEditor๋ฅผ ์ฌ์ฉํ์ธ์:
const editor = this.app.workspace.activeEditor?.editor;
if (editor) {
// ...
}์ฌ์ฉ์ ์ ์ ๋ทฐ์ ๋ํ ์ฐธ์กฐ ๊ด๋ฆฌ ํผํ๊ธฐ
์ฌ์ฉ์ ์ ์ ๋ทฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ด๋ฆฌํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์๋ํ์ง ์์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ํ์ง ๋ง์ธ์:
this.registerView(MY_VIEW_TYPE, () => this.view = new MyCustomView());๋์ ์ด๋ ๊ฒ ํ์ธ์:
this.registerView(MY_VIEW_TYPE, () => new MyCustomView());ํ๋ฌ๊ทธ์ธ์์ ๋ทฐ์ ์ ๊ทผํ๋ ค๋ฉด Workspace.getActiveLeavesOfType()๋ฅผ ์ฌ์ฉํ์ธ์:
for (let leaf of app.workspace.getActiveLeavesOfType(MY_VIEW_TYPE)) {
let view = leaf.view;
if (view instanceof MyCustomView) {
// ...
}
}์ ์ฅ์(Vault)
ํ์ฑ ํ์ผ์ ๋ํด Vault.modify ๋์ Editor API ์ ํธํ๊ธฐ
ํ์ฑ ๋ ธํธ๋ฅผ ํธ์งํ๋ ค๋ฉด Vault.modify() ๋์ Editor ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ธ์.
Editor๋ ์ปค์ ์์น, ์ ํ ์์ญ, ์ ํ ๋ด์ฉ๊ณผ ๊ฐ์ ํ์ฑ ๋ ธํธ์ ๋ํ ์ ๋ณด๋ฅผ ์ ์งํฉ๋๋ค. Vault.modify()๋ฅผ ์ฌ์ฉํ์ฌ ๋ ธํธ๋ฅผ ํธ์งํ๋ฉด ๋ชจ๋ ์ ๋ณด๊ฐ ์์ค๋์ด ์ฌ์ฉ์ ๊ฒฝํ์ด ์ ํ๋ฉ๋๋ค.
Editor๋ ๋ ธํธ์ ์ผ๋ถ๋ฅผ ์๊ฒ ๋ณ๊ฒฝํ ๋ ๋ ํจ์จ์ ์ ๋๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋์์ ํ์ผ์ ์์ ํ๋ ค๋ฉด Vault.modify ๋์ Vault.process ์ ํธํ๊ธฐ
ํ์ฌ ์ด๋ ค ์์ง ์์ ๋ ธํธ๋ฅผ ํธ์งํ๋ ค๋ฉด Vault.modify ๋์ Vault.process ํจ์๋ฅผ ์ฌ์ฉํ์ธ์.
process ํจ์๋ ํ์ผ์ ์์์ ์ผ๋ก ์์ ํ๋ฏ๋ก, ํ๋ฌ๊ทธ์ธ์ด ๋์ผํ ํ์ผ์ ์์ ํ๋ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ๊ณผ ์ถฉ๋ํ์ง ์์ต๋๋ค.
๋
ธํธ์ ํ๋ก ํธ๋งคํฐ๋ฅผ ์์ ํ๋ ค๋ฉด FileManager.processFrontMatter ์ ํธํ๊ธฐ
๋ ธํธ์ ํ๋ก ํธ๋งคํฐ๋ฅผ ์ถ์ถํ๊ณ YAML์ ์๋์ผ๋ก ํ์ฑํ๊ณ ์์ ํ๋ ๋์ FileManager.processFrontMatter ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
processFrontMatter๋ ์์์ ์ผ๋ก ์คํ๋๋ฏ๋ก ํ์ผ์ ์์ ํด๋ ๋์ผํ ํ์ผ์ ํธ์งํ๋ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ๊ณผ ์ถฉ๋ํ์ง ์์ต๋๋ค.
๋ํ ์์ฑ๋ YAML์ ์ผ๊ด๋ ๋ ์ด์์์ ๋ณด์ฅํฉ๋๋ค.
Adapter API ๋์ Vault API ์ ํธํ๊ธฐ
Obsidian์ ํ์ผ ์์
์ ์ํ ๋ ๊ฐ์ง API๋ฅผ ๋
ธ์ถํฉ๋๋ค: Vault API (app.vault)์ Adapter API (app.vault.adapter).
Adapter API์ ํ์ผ ์์ ์ด ๋ง์ ๊ฐ๋ฐ์์๊ฒ ๋ ์ต์ํ์ง๋ง, Vault API๋ ์ด๋ํฐ์ ๋นํด ๋ ๊ฐ์ง ์ฃผ์ ์ด์ ์ด ์์ต๋๋ค.
- ์ฑ๋ฅ: Vault API์๋ ํ์ผ์ด ์ด๋ฏธ Obsidian์ ์๋ ค์ง ๊ฒฝ์ฐ ํ์ผ ์ฝ๊ธฐ ์๋๋ฅผ ๋์ผ ์ ์๋ ์บ์ฑ ๊ณ์ธต์ด ์์ต๋๋ค.
- ์์ ์ฑ: Vault API๋ ๋์์ ์ฐ๊ธฐ ์ค์ธ ํ์ผ์ ์ฝ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ฒฝ์ ์กฐ๊ฑด์ ํผํ๊ธฐ ์ํด ํ์ผ ์์ ์ ์ง๋ ฌ๋ก ์ํํฉ๋๋ค.
๊ฒฝ๋ก๋ก ํ์ผ์ ์ฐพ๊ธฐ ์ํด ๋ชจ๋ ํ์ผ ๋ฐ๋ณต ํผํ๊ธฐ
์ด๊ฒ์ ํนํ ํฐ ์ ์ฅ์์์ ๋นํจ์จ์ ์ ๋๋ค. ๋์ Vault.getFileByPath, Vault.getFolderByPath ๋๋ Vault.getAbstractFileByPath๋ฅผ ์ฌ์ฉํ์ธ์.
์ด๋ ๊ฒ ํ์ง ๋ง์ธ์:
this.app.vault.getFiles().find(file => file.path === filePath);๋์ ์ด๋ ๊ฒ ํ์ธ์:
const filePath = 'folder/file.md';
// ํ์ผ์ ๊ฐ์ ธ์ค๋ ค๋ฉด
const file = this.app.vault.getFileByPath(filePath);const folderPath = 'folder';
// ๋๋ ํด๋๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด
const folder = this.app.vault.getFolderByPath(folderPath);์ ๊ณต๋ ๊ฒฝ๋ก๊ฐ ํด๋์ฉ์ธ์ง ํ์ผ์ฉ์ธ์ง ํ์คํ์ง ์์ ๊ฒฝ์ฐ ๋ค์์ ์ฌ์ฉํ์ธ์:
const abstractFile = this.app.vault.getAbstractFileByPath(filePath);
if (file instanceof TFile) {
// ํ์ผ์
๋๋ค
}
if (file instanceof TFolder) {
// ํด๋์
๋๋ค
}์ฌ์ฉ์ ์ ์ ๊ฒฝ๋ก๋ฅผ ์ ๋ฆฌํ๊ธฐ ์ํด normalizePath() ์ฌ์ฉํ๊ธฐ
์ ์ฅ์์ ํ์ผ์ด๋ ํด๋์ ๋ํ ์ฌ์ฉ์ ์ ์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๊ฑฐ๋ ํ๋ฌ๊ทธ์ธ ์ฝ๋์์ ์์ฒด ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ฑํ ๋๋ง๋ค normalizePath()๋ฅผ ์ฌ์ฉํ์ธ์.
normalizePath()๋ ๊ฒฝ๋ก๋ฅผ ๋ฐ์ ํ์ผ ์์คํ
๋ฐ ํฌ๋ก์ค ํ๋ซํผ ์ฌ์ฉ์ ์์ ํ๋๋ก ์ ๋ฆฌํฉ๋๋ค. ์ด ํจ์๋ ๋ค์์ ์ํํฉ๋๋ค:
\๋๋/๋ฅผ ํ๋ ์ด์์\๋๋/๋ฅผ ๋จ์ผ/๋ก ๋ฐ๊พธ๋ ๋ฑ ์๋ฐฉํฅ ๋ฐ ์ญ๋ฐฉํฅ ์ฌ๋์ ์ฌ์ฉ์ ์ ๋ฆฌํฉ๋๋ค.- ์ ํ ๋ฐ ํํ ์๋ฐฉํฅ ๋ฐ ์ญ๋ฐฉํฅ ์ฌ๋์๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
- ์ค ๋ฐ๊ฟ ์๋ ๊ณต๋ฐฑ
\u00A0์ ์ผ๋ฐ ๊ณต๋ฐฑ์ผ๋ก ๋ฐ๊ฟ๋๋ค. - ๊ฒฝ๋ก๋ฅผ String.prototype.normalize๋ฅผ ํตํด ์คํํฉ๋๋ค.
import { normalizePath } from 'obsidian';
const pathToPlugin = normalizePath('//my-folder\file');
// pathToPlugin์ "//my-folder\"๊ฐ ์๋ "my-folder/file"์ ํฌํจํฉ๋๋ค์๋ํฐ
์๋ํฐ ํ์ฅ ๋ณ๊ฒฝ ๋๋ ์ฌ๊ตฌ์ฑํ๊ธฐ
registerEditorExtension()์ ์ฌ์ฉํ์ฌ ์๋ํฐ ํ์ฅ์ ๋ฑ๋กํ ํ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ฌ๊ตฌ์ฑํ๋ ค๋ฉด updateOptions()๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์๋ํฐ๋ฅผ ์ ๋ฐ์ดํธํ์ธ์.
class MyPlugin extends Plugin {
private editorExtension: Extension[] = [];
onload() {
//...
this.registerEditorExtension(this.editorExtension);
}
updateEditorExtension() {
// ๋์ผํ ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ฉด์ ๋ฐฐ์ด ๋น์ฐ๊ธฐ
// (์ฌ๊ธฐ์ ์ ๋ฐฐ์ด์ ๋ง๋ค์ง ๋ง์ธ์)
this.editorExtension.length = 0;
// ์ ์๋ํฐ ํ์ฅ ๋ง๋ค๊ธฐ
let myNewExtension = this.createEditorExtension();
// ๋ฐฐ์ด์ ์ถ๊ฐํ๊ธฐ
this.editorExtension.push(myNewExtension);
// ๋ชจ๋ ์๋ํฐ์ ๋ณ๊ฒฝ ์ฌํญ ์ ์ฉํ๊ธฐ
this.app.workspace.updateOptions();
}
}
์คํ์ผ๋ง
ํ๋์ฝ๋ฉ๋ ์คํ์ผ๋ง ๊ธ์ง
์ด๋ ๊ฒ ํ์ง ๋ง์ธ์:
const el = containerEl.createDiv();
el.style.color = 'white';
el.style.backgroundColor = 'red';์ฌ์ฉ์๊ฐ ํ๋ฌ๊ทธ์ธ์ ์คํ์ผ๋ง์ ์ฝ๊ฒ ์์ ํ ์ ์๋๋ก ํ๋ ค๋ฉด CSS ํด๋์ค๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ํ๋ฌ๊ทธ์ธ ์ฝ๋์ ์คํ์ผ๋ง์ ํ๋์ฝ๋ฉํ๋ฉด ํ ๋ง์ ์ค๋ํซ์ผ๋ก ์์ ํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํด์ง๋๋ค.
๋์ ์ด๋ ๊ฒ ํ์ธ์:
const el = containerEl.createDiv({cls: 'warning-container'});ํ๋ฌ๊ทธ์ธ CSS์ ๋ค์์ ์ถ๊ฐํ์ธ์:
.warning-container {
color: var(--text-normal);
background-color: var(--background-modifier-error);
}ํ๋ฌ๊ทธ์ธ์ ์คํ์ผ๋ง์ Obsidian ๋ฐ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ๊ณผ ์ผ๊ด๋๊ฒ ๋ง๋ค๋ ค๋ฉด Obsidian์์ ์ ๊ณตํ๋ CSS variables๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ฌ์ฉ ์ฌ๋ก์ ๋ง๋ ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ ์ง์ ๋ง๋ค ์ ์์ต๋๋ค.
TypeScript
var ๋์ const์ let ์ ํธํ๊ธฐ
์์ธํ ๋ด์ฉ์ ํ๋ JavaScript์์ var๊ฐ ๊ตฌ์์ผ๋ก ๊ฐ์ฃผ๋๋ 4๊ฐ์ง ์ด์ ๋ฅผ ์ฐธ์กฐํ์ธ์.
Promise ๋์ async/await ์ ํธํ๊ธฐ
์ต์ ๋ฒ์ ์ JavaScript์ TypeScript๋ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํด async ๋ฐ await ํค์๋๋ฅผ ์ง์ํ์ฌ Promise๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ ์ฝ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ํ์ง ๋ง์ธ์:
function test(): Promise<string | null> {
return requestUrl('https://example.com')
.then(res => res.text
.catch(e => {
console.log(e);
return null;
});
}๋์ ์ด๋ ๊ฒ ํ์ธ์:
async function AsyncTest(): Promise<string | null> {
try {
let res = await requestUrl('https://example.com');
let text = await r.text;
return text;
}
catch (e) {
console.log(e);
return null;
}
}