166 lines
5.2 KiB
Markdown
166 lines
5.2 KiB
Markdown
#meta
|
||
|
||
Page templates can be used to automate or simplify the creation of pages based on a template.
|
||
|
||
# Creating a page template
|
||
To create a page template, create a page and tag it with `#meta/template/page`.
|
||
|
||
The last component of the page name will be used as the template name.
|
||
|
||
## Cursor placement
|
||
In the template’s body text, you can optionally use `|^|` as a placeholder for where the cursor should be after creating
|
||
the page.
|
||
|
||
## Configuration
|
||
Optional keys you can set in the page’s frontmatter:
|
||
|
||
* `suggestedName`: the proposed name for the new page, can use embedded Lua expressions, like `Daily/${date.today()}`.
|
||
* `confirmName`: Confirm the suggested page name before creating it (defaults to `true`).
|
||
* `openIfExists`: If a page with the `suggestedName` already exists, open it rather than attempting to create it anew.
|
||
* `command`: expose the page template as a command with this name.
|
||
* `key`: Bind the snippet to a keyboard shortcut (note: this requires to _also_ specify the `command` configuration).
|
||
* `mac`: Bind the snippet to a Mac-specific keyboard shortcut.
|
||
* `frontmatter`: Frontmatter (encoded as a string) to set in the resulting page.
|
||
* `priority`: Similar to how space lua scripts are loaded, this controls the order in which page template _commands_ are
|
||
created (see "overriding page templates" below)
|
||
|
||
## Example: Daily note
|
||
The following creates a page template that can be run using the `Journal: Daily Note` command, it automatically creates
|
||
`Daily/today’s date` if it does not already exist with a bulleted list, putting the cursor at the first bullet. If the
|
||
page already exists, it navigates there.
|
||
|
||
~~~
|
||
---
|
||
command: "Journal: Daily Note"
|
||
suggestedName: "Daily/${date.today()}"
|
||
confirmName: false
|
||
openIfExists: true
|
||
tags: meta/template/page
|
||
---
|
||
* |^|
|
||
~~~
|
||
|
||
# Currently active page templates
|
||
|
||
${template.each(query[[
|
||
from index.tag "meta/template/page"
|
||
where _.tag == "page"
|
||
]], templates.fullPageItem)}
|
||
|
||
# Instantiating page templates
|
||
|
||
You can create a page based on a page template via the ${widgets.commandButton("Page: From Template")} command, or via
|
||
the command name that you defined in your template’s frontmatter.
|
||
|
||
# Overriding page templates
|
||
|
||
If you would like to override an existing page template (for instance the Quick Note) template with your own, you can
|
||
take advantage of the load order determined by the `priority` frontmatter. Built in page templates will have a priority
|
||
set that is higher than the default. Therefore, their commands and keybindings will be set early. Therefore, by simply
|
||
defining your own version of the page template _with the same command name_ will let that version override the versions
|
||
that are built in.
|
||
|
||
## Example: overriding the Quick Note template
|
||
|
||
~~~
|
||
---
|
||
command: Quick Note
|
||
key: "Alt-Shift-n"
|
||
suggestedName: "Quick notes/${os.date('%Y-%m-%d/%H-%M-%S')}"
|
||
confirmName: false
|
||
tags: meta/template/page
|
||
---
|
||
This is my quick note version
|
||
~~~
|
||
|
||
# Implementation
|
||
```space-lua
|
||
-- priority: 10
|
||
|
||
local function createPageFromTemplate(templatePage, pageName)
|
||
-- Won't override an existing page
|
||
if space.pageExists(pageName) then
|
||
editor.flashNotification("Page " .. pageName .. " already exists", "error")
|
||
return
|
||
end
|
||
local tpl, fm = template.fromPage(templatePage)
|
||
local initialText = ""
|
||
if fm.frontmatter then
|
||
initialText = "---\n"
|
||
.. string.trim(template.new(fm.frontmatter)())
|
||
.. "\n---\n"
|
||
end
|
||
-- Write an empty page to start
|
||
space.writePage(pageName, initialText)
|
||
editor.navigate(pageName)
|
||
-- Insert there, supporting |^| cursor placeholder
|
||
editor.insertAtPos(tpl(), #initialText, true)
|
||
end
|
||
|
||
-- Create commands for all page templates with a command key in frontmatter
|
||
for pt in query[[
|
||
from index.tag "meta/template/page"
|
||
where _.tag == "page" and _.command
|
||
order by _.priority desc
|
||
]] do
|
||
command.define {
|
||
name = pt.command,
|
||
key = pt.key,
|
||
mac = pt.mac,
|
||
run = function()
|
||
local pageName
|
||
if pt.suggestedName then
|
||
pageName = (template.new(pt.suggestedName))()
|
||
end
|
||
if pt.confirmName != false then
|
||
pageName = editor.prompt("Page name", pageName)
|
||
end
|
||
if not pageName then
|
||
return
|
||
end
|
||
if pt.openIfExists and space.pageExists(pageName) then
|
||
editor.navigate(pageName)
|
||
return
|
||
end
|
||
createPageFromTemplate(pt.name, pageName)
|
||
end
|
||
}
|
||
print("Registered", pt.command)
|
||
end
|
||
|
||
local function cleanName(path)
|
||
-- Just pull the last part
|
||
local parts = path:split("/")
|
||
return parts[#parts]
|
||
end
|
||
|
||
command.define {
|
||
name = "Page: From Template",
|
||
key = "Alt-shift-t",
|
||
run = function()
|
||
local pageTemplates = query[[
|
||
from index.tag "meta/template/page"
|
||
where _.tag == "page"
|
||
select {
|
||
name = cleanName(_.name),
|
||
fullName = _.name,
|
||
suggestedName = _.suggestedName
|
||
}
|
||
]]
|
||
local selected = editor.filterBox("Page template", pageTemplates, "Pick the template you would like to instantiate")
|
||
if not selected then
|
||
return
|
||
end
|
||
local pageName
|
||
if selected.suggestedName then
|
||
pageName = (template.new(selected.suggestedName))()
|
||
end
|
||
pageName = editor.prompt("Page name", pageName)
|
||
if not pageName then
|
||
return
|
||
end
|
||
createPageFromTemplate(selected.fullName, pageName)
|
||
end
|
||
}
|
||
```
|