Templater
Templater copied to clipboard
Templater should parse, merge and write out frontmatter gracefully
Is your feature request related to a problem?
Many of the recent bug reports and feature requests concern managing and updating frontmatter/properties. app.fileManager.processFrontmatter()
has been proposed as a workaround for some of those problems, but has
- brought with it its own issues (especially regarding race conditions)
- failed to provide solutions for some of them (retrieving, parsing and applying frontmatter from the yaml block of a simple template file, for example)
- left most of the work to the end user
Describe the solution you'd like
I propose that Templater implements parsing and handling of frontmatter properties, whether they are initially defined as objects (compare console.log(tp.frontmatter)
)
{
"modified": "2024-05-29T16:36:31+02:00",
"tags": ["source"]
}
or as YAML strings
`---
modified: "2024-05-29T16:36:31+02:00",
tags: ["source"]
---`
Usage Example: Modularization of Template files. For example, I might want to add certain properties to all notes on "Beliefs" to define how strongly I believe in something and why, and also add a little section to add further comments. Let's call that an Epistemology Module
.
My note on a belief: Cows are mammals.md
---
created: 2020-12-12
tags: [#belief]
---
# Cows are mammals
I believe that cows are mammals. Because.
I only learned about epistemology statements in 2024, but have started adding them to all my beliefs:
epistemology-module.md
---
tags: [#belief, #epistemology]
credence: 60
effort: 30
---
## Epistemology statement
How strongly do I believe this? Hint: When creating a file, the default credence is <% tp.frontmatter["credence"] %>
How much effort did I put into this?
When did I last update this statement? <% tp.date.now() %>
I now want to tp.file.include("[[epistemology-module.md]]")
in my belief-template.md
template for new beliefs and also be able to Insert template
into existing ones.
When I create a new file using epistemology-module.md, it creates a new file with the correct YAML block just fine, but still fails on inserting the tp.frontmatter["credence"] (because the frontmatter of the new file is not defined yet, even though it is written out in the template). When I add that epistemology-module.md to the existing belief, it inserts the YAML-block at cursor position, not processing it at all, and obviously still fails inserting the credence.
To fix this, all frontmatter that is handled during execution of a script should:
- Be parsed from YAML to an object (possibly replacing
<% tp.stuff %>
where appropriate).- This is important during
tp.file.include(tFile)
or when Inserting a template to an existing file when the template in question contains its own metadata block and ... - ... useful for filling tp.frontmatter during creation of a new file
- This is important during
- Be merged gracefully when pulling frontmatter from more than one source (due to a non-empty file, several
tp.file.include
, etc.):- new keys should be added
- duplicate keys should be overwritten with the new value if that value is a primitive...
- ... or merged if the value itself is an object/array
- Be written out as a unified YAML-block at the top
Upon inserting the module into the existing file, we should thus get:
Cows are mammals.md
---
created: 2020-12-12
tags: [#belief, #epistemology]
credence: 60
effort: 30
---
# Cows are mammals
I believe that cows are mammals. Because.
## Epistemology statement
How strongly do I believe this? Hint: When creating a file, the default credence is 60
How much effort did I put into this?
When did I last update this statement? 2024-05-29
Describe alternatives you've considered
Currently, I use a haphazardly hacked-together mergeFrontmatter() function, write weird JS-Object definitions for my templates and modules (instead of simple .md templates) and then create a template literal containing the template to use for tp.file.create_new()
. My module-definitions have a method() for updating an existing file with that module (e.g.: an excalidraw-module would be adding the excalidraw-plugin: parsed
property using processFrontmatter()
and the Excalidraw body %%\n# Excalidraw Data\n## Text Elements [...]
by inserting that literal at the cursor position). I have not found a way to parse the template literals through Templater in the same step, yet (because only tp.file.create_new()
accepts a string for a template and Templater does not currently expose its parse_template()
function). Therefore, if my template or module definition includes eta-tags, I hit my "Replace templates in the active file" hotkey afterwards.
Additional context Both the built-in Templates-Plugin as well as the Excalidraw-Plugin parse templates of the format
---
excalidraw-plugin: parsed
---
# Excalidraw body ....
without any problems and can create a new file from such a template, or add that template to an existing file (merging the new key into an existing file's frontmatter).