3.5 KiB
description, tags
| description | tags |
|---|---|
| APIs to create and render templates | meta/api |
APIs to create templates from strings or pages, and render query collections using templates.
API
template.new(templateStr, stripIndent)
Creates a template function from a string. The template string can contain ${expression} placeholders that will be interpolated when the template is called. Conventionally, template strings typically use [==[ and ]==] as delimiters.
If stripIndent is true or omitted, leading 4-space indentation is stripped from each line.
Example:
-- the `templates` global table is available for custom templates
templates.greet = template.new [==[Hello ${name}!]==]
Which elsewhere can be used, either directly:
${templates.greet {name = "Pete"}}
or directly in a query’s select clause:
${query[[from p = index.contentPages() limit 3 select templates.greet(p)]]}
Resulting in something along the lines of Hello index!Hello CONFIG!...
template.each(collection, fn)
Iterates over a collection and applies a template to each element, concatenating the results. While this API still works, but for queries the recommended approach is to call the template in the select clause directly (as shown above).
Example:
${query[[from p = index.contentPages() limit 3 select template.new[==[
* [[${name}]]
]==](p)]]}
Pre-built templates
The templates table contains ready-made templates for common query rendering patterns. These are defined in ^Library/Std/Infrastructure/Query Templates.
templates.pageItem— renders a page as* [[name]]templates.fullPageItem— renders a page as* [[name|name]](full path)templates.taskItem— renders a task as a togglable* [state] [[ref]] nametemplates.itemItem— renders an item as* [[ref]] nametemplates.paragraphItem— renders a paragraph as* [[ref]] texttemplates.tagItem— renders a tag as* [[tag:name|#name]]
Implementation
-- priority: 50
-- Template API root table
template = template or {}
-- Template storage table
templates = {}
-- Iterates over a table/array and applies a function to each element,
-- concatenating the results
function template.each(tbl, fn)
local result = {}
for _, item in ipairs(tbl) do
table.insert(result, fn(item))
end
return #result > 0 and table.concat(result) or nil
end
-- Creates a new template function from a string template
function template.new(templateStr, stripIndent)
-- Preprocess: strip indentation
if stripIndent == nil or stripIndent == true then
local lines = {}
local splitLines = string.split(templateStr, "\n")
for _, line in ipairs(splitLines) do
line = string.gsub(line, "^ ", "")
table.insert(lines, line)
end
templateStr = table.concat(lines, "\n")
end
return function(obj)
return spacelua.interpolate(templateStr, obj)
end
end
-- Reads a template from a page
-- Return value:
-- * The template itself
-- * The extracted frontmatter
function template.fromPage(name, raw)
local fm = index.extractFrontmatter(space.readPage(name), {
removeFrontMatterSection = true,
removeTagsPrefix = {"meta/template"}
})
local templateText = string.trimStart(fm.text)
if raw then
-- Don't actually parse this as a template, just pass it along
return function()
return templateText
end, fm.frontmatter
end
return template.new(templateText, false), fm.frontmatter
end