From 509ece91f00ef70f2d0c9719b5c6d20b2e0a312e Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Thu, 11 Jan 2024 14:06:24 +0100 Subject: [PATCH] Adding an "enabled" attribute to templates --- plugs/editor/page.ts | 13 ++++++++++--- plugs/index/builtins.ts | 1 + plugs/index/template_widget.ts | 7 ++++++- plugs/markdown/markdown_render.ts | 9 +++++++-- plugs/template/complete.ts | 7 +++++-- website/Live Template Widgets.md | 1 + website/Slash Templates.md | 2 +- website/Template Sets.md | 4 ++-- website/template/widget/federated-template-copy.md | 10 ++++++++++ 9 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 website/template/widget/federated-template-copy.md diff --git a/plugs/editor/page.ts b/plugs/editor/page.ts index 3b086f0..520a111 100644 --- a/plugs/editor/page.ts +++ b/plugs/editor/page.ts @@ -1,4 +1,5 @@ import { editor, space } from "$sb/syscalls.ts"; +import { isFederationPath } from "$sb/lib/resolve.ts"; export async function deletePage() { const pageName = await editor.getCurrentPage(); @@ -13,9 +14,15 @@ export async function deletePage() { await space.deletePage(pageName); } -export async function copyPage() { +export async function copyPage(_def: any, predefinedNewName: string) { const oldName = await editor.getCurrentPage(); - const newName = await editor.prompt(`New page title:`, `${oldName} (copy)`); + let suggestedName = predefinedNewName || oldName; + + if (isFederationPath(oldName)) { + const pieces = oldName.split("/"); + suggestedName = pieces.slice(1).join("/"); + } + const newName = await editor.prompt(`Copy to new page:`, suggestedName); if (!newName) { return; @@ -26,7 +33,7 @@ export async function copyPage() { await space.getPageMeta(newName); // So when we get to this point, we error out throw new Error( - `Page ${newName} already exists, cannot rename to existing page.`, + `"${newName}" already exists, cannot copy to existing page.`, ); } catch (e: any) { if (e.message === "Not found") { diff --git a/plugs/index/builtins.ts b/plugs/index/builtins.ts index bda714d..b7f0f9a 100644 --- a/plugs/index/builtins.ts +++ b/plugs/index/builtins.ts @@ -84,6 +84,7 @@ export const builtins: Record> = { trigger: "string", where: "string", priority: "number", + enabled: "boolean", }, }; diff --git a/plugs/index/template_widget.ts b/plugs/index/template_widget.ts index b838877..a944c54 100644 --- a/plugs/index/template_widget.ts +++ b/plugs/index/template_widget.ts @@ -31,7 +31,12 @@ export async function renderTemplateWidgets(side: "top" | "bottom"): Promise< const allFrontMatterTemplates = await queryObjects( "template", { - filter: ["=", ["attr", "type"], ["string", `widget:${side}`]], + // where type = "widget:X" and enabled != false + filter: ["and", ["=", ["attr", "type"], ["string", `widget:${side}`]], [ + "!=", + ["attr", "enabled"], + ["boolean", false], + ]], orderBy: [{ expr: ["attr", "priority"], desc: false }], }, ); diff --git a/plugs/markdown/markdown_render.ts b/plugs/markdown/markdown_render.ts index 9f78610..313b1bd 100644 --- a/plugs/markdown/markdown_render.ts +++ b/plugs/markdown/markdown_render.ts @@ -326,12 +326,17 @@ function render( }; case "CommandLink": { // Child 0 is CommandLinkMark, child 1 is CommandLinkPage - const commandText = t.children![1].children![0].text!; + const command = t.children![1].children![0].text!; + let commandText = command; + const aliasNode = findNodeOfType(t, "CommandLinkAlias"); + if (aliasNode) { + commandText = aliasNode.children![0].text!; + } return { name: "button", attrs: { - "data-onclick": JSON.stringify(["command", commandText]), + "data-onclick": JSON.stringify(["command", command]), }, body: commandText, }; diff --git a/plugs/template/complete.ts b/plugs/template/complete.ts index 94590fa..64c6963 100644 --- a/plugs/template/complete.ts +++ b/plugs/template/complete.ts @@ -51,8 +51,11 @@ export async function templateSlashComplete( completeEvent: CompleteEvent, ): Promise { const allTemplates = await queryObjects("template", { - // Only return templates that have a trigger - filter: ["attr", "trigger"], + // Only return templates that have a trigger and are not expliclty disabled + filter: ["and", ["attr", "trigger"], ["!=", ["attr", "enabled"], [ + "boolean", + false, + ]]], }); return allTemplates.map((template) => ({ label: template.trigger!, diff --git a/website/Live Template Widgets.md b/website/Live Template Widgets.md index 93ee086..5306645 100644 --- a/website/Live Template Widgets.md +++ b/website/Live Template Widgets.md @@ -12,6 +12,7 @@ Live Template Widgets follow the same pattern as other [[Templates]] with a few * `type`: should be set to `widget:top` or `widget:bottom` depending on where you would like it to appear * `where`: should contain an [[Live Queries$expression]] that evaluates to true for the _pages_ you would like to apply this template to, usually this checks for a specific tag, but it can be any expression. Think of this as a `where` clause that should match for the pages this template is applied to. * `priority` (optional): in case you have multiple templates that have matching `where` expression, the one with the priority set to the lowest number wins. +* `enabled` (defaults to `true`): in case you want to (temporarily) disable this template, set this to `false`. # Example The following widget template applies to all pages tagged with `person` (see the `where`). It uses the [[!silverbullet.md/template/live/incoming]] template, to show all incomplete tasks that reference this particular page. diff --git a/website/Slash Templates.md b/website/Slash Templates.md index 6f299c2..d1edc1d 100644 --- a/website/Slash Templates.md +++ b/website/Slash Templates.md @@ -1,7 +1,7 @@ Slash templates allow you to define custom [[Slash Commands]] that expand “snippet style” templates inline. # Definition -You can define a slash template by creating a [[Templates|template page]] with a template tag and `trigger` attribute. +You can define a slash template by creating a [[Templates|template page]] with a template tag and `trigger` attribute. If you’d like to (temporarily) disable the template, you can set the `enabled` attribute to `false`. Example: diff --git a/website/Template Sets.md b/website/Template Sets.md index 3d84023..fc6bf7c 100644 --- a/website/Template Sets.md +++ b/website/Template Sets.md @@ -5,7 +5,7 @@ This is an attempt at collecting useful, reusable templates so you don’t have While you may just copy & paste these templates to your own space, the most convenient ways to use them is using [[Federation]]. This will synchronize these templates into your space and make them available for use instantly. -To set this up, add the following this to your [[SETTINGS]]: +To set this up, add the following to your [[SETTINGS]]: ```yaml federate: @@ -56,7 +56,7 @@ render [[template/documented-template]] ``` # Live Widget Templates -Use these to add [[Table of Contents]] and [[Linked Mentions]] to your pages. +Use these to add various useful [[Live Template Widgets]] to your pages. ```query template diff --git a/website/template/widget/federated-template-copy.md b/website/template/widget/federated-template-copy.md new file mode 100644 index 0000000..25aa4ca --- /dev/null +++ b/website/template/widget/federated-template-copy.md @@ -0,0 +1,10 @@ +--- +description: > + Adds a convenient "Copy to my space" button to any + template found via federation +tags: template +type: widget:bottom +where: 'name =~ /^!/ and tags="template"' +--- +# Template actions +* {[Page: Copy|Copy to my space]}: use this template in your space by making a local copy of it (and tweaking it as you like) \ No newline at end of file