|
1 | | -import { MarkdownView, TFile, type App } from "obsidian"; |
| 1 | +import { MarkdownView, TFile, type App, parseYaml } from "obsidian"; |
2 | 2 | import invariant from "src/utils/invariant"; |
3 | 3 | import { |
4 | 4 | fileExistsAppendToBottom, |
@@ -249,38 +249,23 @@ export class TemplateChoiceEngine extends TemplateEngine { |
249 | 249 |
|
250 | 250 | const { frontmatter, body } = this.splitFrontmatter(templaterContent); |
251 | 251 | const hasBody = body.trim().length > 0; |
252 | | - const hasFrontmatter = frontmatter?.trim().length; |
| 252 | + |
| 253 | + if (frontmatter) { |
| 254 | + await this.applyFrontmatterProperties(activeFile, frontmatter); |
| 255 | + } |
253 | 256 |
|
254 | 257 | if (insertion.placement === "top" || insertion.placement === "bottom") { |
255 | 258 | const fileContent = await this.app.vault.read(activeFile); |
256 | | - let nextContent = this.applyFrontmatterInsertion( |
257 | | - fileContent, |
258 | | - frontmatter, |
259 | | - ); |
260 | | - if (hasBody) { |
261 | | - nextContent = |
262 | | - insertion.placement === "top" |
263 | | - ? this.insertBodyAtTop(nextContent, body) |
264 | | - : this.insertBodyAtBottom(nextContent, body); |
265 | | - } |
| 259 | + const nextContent = hasBody |
| 260 | + ? insertion.placement === "top" |
| 261 | + ? this.insertBodyAtTop(fileContent, body) |
| 262 | + : this.insertBodyAtBottom(fileContent, body) |
| 263 | + : fileContent; |
266 | 264 | if (nextContent !== fileContent) { |
267 | 265 | await this.app.vault.modify(activeFile, nextContent); |
268 | 266 | } |
269 | | - } else { |
270 | | - if (hasFrontmatter) { |
271 | | - const fileContent = await this.app.vault.read(activeFile); |
272 | | - const nextContent = this.applyFrontmatterInsertion( |
273 | | - fileContent, |
274 | | - frontmatter, |
275 | | - ); |
276 | | - if (nextContent !== fileContent) { |
277 | | - await this.app.vault.modify(activeFile, nextContent); |
278 | | - } |
279 | | - } |
280 | | - |
281 | | - if (hasBody) { |
282 | | - this.insertBodyIntoEditor(body, insertion.placement); |
283 | | - } |
| 267 | + } else if (hasBody) { |
| 268 | + this.insertBodyIntoEditor(body, insertion.placement); |
284 | 269 | } |
285 | 270 |
|
286 | 271 | if (this.shouldPostProcessFrontMatter(activeFile, templateVars)) { |
@@ -382,27 +367,45 @@ export class TemplateChoiceEngine extends TemplateEngine { |
382 | 367 | }; |
383 | 368 | } |
384 | 369 |
|
385 | | - private applyFrontmatterInsertion( |
386 | | - content: string, |
387 | | - frontmatter: string | null, |
388 | | - ): string { |
389 | | - if (!frontmatter || frontmatter.trim().length === 0) { |
390 | | - return content; |
391 | | - } |
| 370 | + private async applyFrontmatterProperties( |
| 371 | + file: TFile, |
| 372 | + frontmatter: string, |
| 373 | + ): Promise<void> { |
| 374 | + const trimmed = frontmatter.trim(); |
| 375 | + if (!trimmed) return; |
392 | 376 |
|
393 | | - const trimmedInsert = frontmatter.trimEnd(); |
394 | | - const match = TemplateChoiceEngine.FRONTMATTER_REGEX.exec(content); |
395 | | - if (!match) { |
396 | | - return `---\n${trimmedInsert}\n---\n${content}`; |
| 377 | + let parsed: unknown; |
| 378 | + try { |
| 379 | + parsed = parseYaml(trimmed); |
| 380 | + } catch (error) { |
| 381 | + log.logWarning( |
| 382 | + `Template insertion: failed to parse frontmatter for ${file.path}: ${String( |
| 383 | + error, |
| 384 | + )}`, |
| 385 | + ); |
| 386 | + return; |
397 | 387 | } |
398 | 388 |
|
399 | | - const existing = match[2]; |
400 | | - const merged = |
401 | | - existing.trim().length === 0 |
402 | | - ? trimmedInsert |
403 | | - : `${existing.trimEnd()}\n${trimmedInsert}`; |
| 389 | + if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { |
| 390 | + log.logWarning( |
| 391 | + `Template insertion: frontmatter did not parse to an object for ${file.path}.`, |
| 392 | + ); |
| 393 | + return; |
| 394 | + } |
404 | 395 |
|
405 | | - return `${match[1]}${merged}${match[3]}${content.slice(match[0].length)}`; |
| 396 | + try { |
| 397 | + await this.app.fileManager.processFrontMatter(file, (fm) => { |
| 398 | + for (const [key, value] of Object.entries(parsed as Record<string, unknown>)) { |
| 399 | + fm[key] = value; |
| 400 | + } |
| 401 | + }); |
| 402 | + } catch (error) { |
| 403 | + log.logWarning( |
| 404 | + `Template insertion: failed to apply frontmatter for ${file.path}: ${String( |
| 405 | + error, |
| 406 | + )}`, |
| 407 | + ); |
| 408 | + } |
406 | 409 | } |
407 | 410 |
|
408 | 411 | private insertBodyAtTop(content: string, body: string): string { |
|
0 commit comments