f30b1d3418
Templates 2.0 and a whole bunch of other refactoring
92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
import {
|
|
codeWidget,
|
|
editor,
|
|
language,
|
|
markdown,
|
|
space,
|
|
} from "$sb/silverbullet-syscall/mod.ts";
|
|
import { parseTreeToAST, renderToText } from "$sb/lib/tree.ts";
|
|
import { CodeWidgetContent } from "$sb/types.ts";
|
|
import { loadPageObject } from "../template/page.ts";
|
|
import { queryObjects } from "./api.ts";
|
|
import { TemplateObject, WidgetConfig } from "../template/types.ts";
|
|
import { expressionToKvQueryExpression } from "$sb/lib/parse-query.ts";
|
|
import { evalQueryExpression } from "$sb/lib/query.ts";
|
|
import { renderTemplate } from "../template/plug_api.ts";
|
|
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
|
|
import { rewritePageRefs } from "$sb/lib/resolve.ts";
|
|
|
|
export async function refreshWidgets() {
|
|
await codeWidget.refreshAll();
|
|
}
|
|
|
|
export async function renderTemplateWidgets(side: "top" | "bottom"): Promise<
|
|
CodeWidgetContent | null
|
|
> {
|
|
const text = await editor.getText();
|
|
let pageMeta = await loadPageObject(await editor.getCurrentPage());
|
|
const parsedMd = await markdown.parseMarkdown(text);
|
|
const frontmatter = await extractFrontmatter(parsedMd);
|
|
|
|
pageMeta = { ...pageMeta, ...frontmatter };
|
|
|
|
const blockTemplates = await queryObjects<TemplateObject>(
|
|
"template",
|
|
{
|
|
// where hooks.top/bottom exists
|
|
filter: ["attr", ["attr", "hooks"], side],
|
|
orderBy: [{
|
|
// order by hooks.top/bottom.order asc
|
|
expr: ["attr", ["attr", ["attr", "hooks"], side], "order"],
|
|
desc: false,
|
|
}],
|
|
},
|
|
);
|
|
// console.log(`Found the following ${side} templates`, blockTemplates);
|
|
const templateBits: string[] = [];
|
|
// Strategy: walk through all matching templates, evaluate the 'where' expression, and pick the first one that matches
|
|
for (const template of blockTemplates) {
|
|
if (!template.hooks) {
|
|
console.warn(
|
|
"No hooks specified for template",
|
|
template.ref,
|
|
"this should never happen",
|
|
);
|
|
continue;
|
|
}
|
|
const blockDef = WidgetConfig.parse(template.hooks[side]!);
|
|
const exprAST = parseTreeToAST(
|
|
await language.parseLanguage("expression", blockDef.where!),
|
|
);
|
|
const parsedExpression = expressionToKvQueryExpression(exprAST[1]);
|
|
if (evalQueryExpression(parsedExpression, pageMeta)) {
|
|
// Match! We're happy
|
|
const templateText = await space.readPage(template.ref);
|
|
let renderedTemplate = (await renderTemplate(
|
|
templateText,
|
|
pageMeta,
|
|
frontmatter,
|
|
)).text;
|
|
|
|
const parsedMarkdown = await markdown.parseMarkdown(renderedTemplate);
|
|
rewritePageRefs(parsedMarkdown, template.ref);
|
|
renderedTemplate = renderToText(parsedMarkdown);
|
|
|
|
// console.log("Rendering template", template.ref, renderedTemplate);
|
|
templateBits.push(renderedTemplate.trim());
|
|
}
|
|
}
|
|
const summaryText = templateBits.join("\n");
|
|
return {
|
|
markdown: summaryText,
|
|
buttons: [
|
|
{
|
|
description: "Reload",
|
|
svg:
|
|
`<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-refresh-cw"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>`,
|
|
invokeFunction: "index.refreshWidgets",
|
|
},
|
|
],
|
|
};
|
|
}
|