diff --git a/plug-api/lib/frontmatter.ts b/plug-api/lib/frontmatter.ts index 9f517cb9..40fb27d5 100644 --- a/plug-api/lib/frontmatter.ts +++ b/plug-api/lib/frontmatter.ts @@ -104,7 +104,7 @@ export async function extractFrontmatter( // Updates the front matter of a markdown document and returns the text as a rendered string export async function prepareFrontmatterDispatch( tree: ParseTree, - data: Record, + data: string | Record, ): Promise { let dispatchData: any = null; await traverseTreeAsync(tree, async (t) => { @@ -114,14 +114,20 @@ export async function prepareFrontmatterDispatch( const yamlText = renderToText(bodyNode); try { - const parsedYaml = await YAML.parse(yamlText) as any; - const newData = { ...parsedYaml, ...data }; + let frontmatterText = ""; + if (typeof data === "string") { + frontmatterText = yamlText + data + "\n"; + } else { + const parsedYaml = await YAML.parse(yamlText) as any; + const newData = { ...parsedYaml, ...data }; + frontmatterText = await YAML.stringify(newData); + } // Patch inline dispatchData = { changes: { from: bodyNode.from, to: bodyNode.to, - insert: await YAML.stringify(newData), + insert: frontmatterText, }, }; } catch (e: any) { @@ -133,12 +139,19 @@ export async function prepareFrontmatterDispatch( }); if (!dispatchData) { // If we didn't find frontmatter, let's add it + let frontmatterText = ""; + if (typeof data === "string") { + frontmatterText = data + "\n"; + } else { + frontmatterText = await YAML.stringify(data); + } + const fullFrontmatterText = "---\n" + frontmatterText + + "---\n"; dispatchData = { changes: { from: 0, to: 0, - insert: "---\n" + await YAML.stringify(data) + - "---\n", + insert: fullFrontmatterText, }, }; } diff --git a/plugs/directive/template_directive.ts b/plugs/directive/template_directive.ts index dbd96e09..600c5e6e 100644 --- a/plugs/directive/template_directive.ts +++ b/plugs/directive/template_directive.ts @@ -64,7 +64,7 @@ export async function templateDirectiveRenderer( // if it's a template injection (not a literal "include") if (directive === "use") { - newBody = await renderTemplate(newBody, pageMeta, parsedArgs); + newBody = (await renderTemplate(newBody, pageMeta, parsedArgs)).text; // Recursively render directives const tree = await markdown.parseMarkdown(newBody); diff --git a/plugs/template/api.ts b/plugs/template/api.ts index 53000874..91582a1b 100644 --- a/plugs/template/api.ts +++ b/plugs/template/api.ts @@ -16,7 +16,7 @@ export async function renderTemplate( templateText: string, pageMeta: PageMeta, data: any = {}, -): Promise { +): Promise<{ frontmatter?: string; text: string }> { const tree = await markdown.parseMarkdown(templateText); const frontmatter: Partial = await extractFrontmatter(tree, { removeFrontmatterSection: true, @@ -24,15 +24,20 @@ export async function renderTemplate( }); templateText = renderToText(tree).trimStart(); // If a 'frontmatter' key was specified in the frontmatter, use that as the frontmatter + let frontmatterText: string | undefined; if (frontmatter.frontmatter) { if (typeof frontmatter.frontmatter === "string") { - templateText = "---\n" + frontmatter.frontmatter + "---\n" + templateText; + frontmatterText = frontmatter.frontmatter; } else { - templateText = "---\n" + (await YAML.stringify(frontmatter.frontmatter)) + - "---\n" + templateText; + frontmatterText = await YAML.stringify(frontmatter.frontmatter); } } - return handlebars.renderTemplate(templateText, data, { page: pageMeta }); + return { + frontmatter: frontmatterText, + text: await handlebars.renderTemplate(templateText, data, { + page: pageMeta, + }), + }; } /** diff --git a/plugs/template/plug_api.ts b/plugs/template/plug_api.ts index 37a64675..4087e02b 100644 --- a/plugs/template/plug_api.ts +++ b/plugs/template/plug_api.ts @@ -5,7 +5,7 @@ export function renderTemplate( templateText: string, pageMeta: PageMeta, data: any = {}, -): Promise { +): Promise<{ frontmatter?: string; text: string }> { return system.invokeFunction( "template.renderTemplate", templateText, diff --git a/plugs/template/template.ts b/plugs/template/template.ts index a74a3811..57fa037b 100644 --- a/plugs/template/template.ts +++ b/plugs/template/template.ts @@ -1,5 +1,8 @@ import { editor, handlebars, markdown, space, YAML } from "$sb/syscalls.ts"; -import { extractFrontmatter } from "$sb/lib/frontmatter.ts"; +import { + extractFrontmatter, + prepareFrontmatterDispatch, +} from "$sb/lib/frontmatter.ts"; import { renderToText } from "$sb/lib/tree.ts"; import { niceDate, niceTime } from "$sb/lib/dates.ts"; import { readSettings } from "$sb/lib/settings_page.ts"; @@ -29,13 +32,26 @@ export async function templateSlashComplete( export async function insertSlashTemplate(slashCompletion: SlashCompletion) { const pageObject = await loadPageObject(slashCompletion.pageName); - let templateText = await space.readPage(slashCompletion.templatePage); - templateText = await renderTemplate(templateText, pageObject); + const templateText = await space.readPage(slashCompletion.templatePage); + let { frontmatter, text } = await renderTemplate(templateText, pageObject); const cursorPos = await editor.getCursor(); - const carretPos = templateText.indexOf("|^|"); - templateText = templateText.replace("|^|", ""); - await editor.insertAtCursor(templateText); + + if (frontmatter) { + frontmatter = frontmatter.trim(); + const pageText = await editor.getText(); + const tree = await markdown.parseMarkdown(pageText); + + const dispatch = await prepareFrontmatterDispatch(tree, frontmatter); + if (cursorPos === 0) { + dispatch.selection = { anchor: frontmatter.length + 9 }; + } + await editor.dispatch(dispatch); + } + + const carretPos = text.indexOf("|^|"); + text = text.replace("|^|", ""); + await editor.insertAtCursor(text); if (carretPos !== -1) { await editor.moveCursor(cursorPos + carretPos); }