From a3f9d4e1e6eb648ecf49d5c3b73a3f3d605756df Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Tue, 17 Dec 2024 21:26:26 +0100 Subject: [PATCH] feat(core): template service to use any available template engine to post-process templates --- src/core/template/BasicTemplateService.ts | 26 ++++++++++++++ src/core/template/TemplateError.ts | 14 ++++++++ src/core/template/TemplateService.ts | 16 +++++++++ src/core/template/TemplaterService.ts | 41 +++++++++++++++++++++++ src/core/template/getTemplateService.ts | 16 +++++++++ src/core/template/index.ts | 5 +++ 6 files changed, 118 insertions(+) create mode 100644 src/core/template/BasicTemplateService.ts create mode 100644 src/core/template/TemplateError.ts create mode 100644 src/core/template/TemplateService.ts create mode 100644 src/core/template/TemplaterService.ts create mode 100644 src/core/template/getTemplateService.ts create mode 100644 src/core/template/index.ts diff --git a/src/core/template/BasicTemplateService.ts b/src/core/template/BasicTemplateService.ts new file mode 100644 index 0000000..f71ebb9 --- /dev/null +++ b/src/core/template/BasicTemplateService.ts @@ -0,0 +1,26 @@ +import { TE } from "@std"; +import { App, normalizePath } from "obsidian"; +import { Logger } from "src/utils/Logger"; +import { TemplateError } from "./TemplateError"; +import { TemplateService } from "./TemplateService"; + +/** + * Basic template service that creates notes with unchanged content + */ +export class BasicTemplateService implements TemplateService { + constructor( + private app: App, + private logger: Logger, + ) {} + + createNoteFromTemplate = ( + template: string, + targetPath: string, + ): TE.TaskEither => + TE.tryCatch( + async () => { + await this.app.vault.create(normalizePath(targetPath), template); + }, + TemplateError.of("Error creating note from template"), + ); +} diff --git a/src/core/template/TemplateError.ts b/src/core/template/TemplateError.ts new file mode 100644 index 0000000..0ee6ef8 --- /dev/null +++ b/src/core/template/TemplateError.ts @@ -0,0 +1,14 @@ +export class TemplateError extends Error { + public readonly _tag = "TemplateError"; + constructor( + message: string, + public readonly cause?: unknown, + ) { + super(message); + this.name = "TemplateError"; + } + + static of(message: string) { + return (cause: unknown) => new TemplateError(message, cause); + } +} diff --git a/src/core/template/TemplateService.ts b/src/core/template/TemplateService.ts new file mode 100644 index 0000000..d9f62d2 --- /dev/null +++ b/src/core/template/TemplateService.ts @@ -0,0 +1,16 @@ +import { TE } from "@std"; +import { TemplateError } from "./TemplateError"; + +export interface TemplateService { + /** + * Creates a note from a template content + * @param template The template content + * @param targetPath Path where the new note should be created + */ + createNoteFromTemplate( + templateContent: string, + targetFolder: string, + filename: string, + openNewNote: boolean, + ): TE.TaskEither; +} diff --git a/src/core/template/TemplaterService.ts b/src/core/template/TemplaterService.ts new file mode 100644 index 0000000..717fba3 --- /dev/null +++ b/src/core/template/TemplaterService.ts @@ -0,0 +1,41 @@ +import { TE } from "@std"; +import { App } from "obsidian"; +import { Logger } from "src/utils/Logger"; +import { TemplateError } from "./TemplateError"; +import { TemplateService } from "./TemplateService"; + +export interface TemplaterApi { + create_new_note_from_template: ( + content: string, + folder: string, + title: string, + openNewNote: boolean, + ) => Promise; +} + +/** + * Template service that uses the Templater plugin + */ +export class TemplaterService implements TemplateService { + constructor( + private app: App, + private logger: Logger, + private templaterApi: TemplaterApi, + ) {} + + createNoteFromTemplate = ( + templateContent: string, + targetFolder: string, + filename: string, + openNewNote: boolean, + ): TE.TaskEither => + TE.tryCatch(async () => { + const title = filename; + await this.templaterApi.create_new_note_from_template( + templateContent, + targetFolder, + title, + openNewNote, + ); + }, TemplateError.of("Error creating note from template")); +} diff --git a/src/core/template/getTemplateService.ts b/src/core/template/getTemplateService.ts new file mode 100644 index 0000000..eb098cd --- /dev/null +++ b/src/core/template/getTemplateService.ts @@ -0,0 +1,16 @@ +import { App } from "obsidian"; +import { Logger } from "src/utils/Logger"; +import { BasicTemplateService } from "./BasicTemplateService"; +import { TemplaterService } from "./TemplaterService"; +import { TemplateService } from "./TemplateService"; + +export function getTemplateService(app: App, logger: Logger): TemplateService { + const templaterApi = app.plugins.plugins["templater-obsidian"]?.templater; + if (templaterApi) { + logger.debug("Using Templater plugin for templates"); + return new TemplaterService(app, logger, templaterApi); + } + + logger.debug("Using basic template service"); + return new BasicTemplateService(app, logger); +} diff --git a/src/core/template/index.ts b/src/core/template/index.ts new file mode 100644 index 0000000..2d74315 --- /dev/null +++ b/src/core/template/index.ts @@ -0,0 +1,5 @@ +export * from "./TemplateService"; +export * from "./TemplateError"; +export * from "./BasicTemplateService"; +export * from "./TemplaterService"; +export * from "./getTemplateService";