Skip to content

feat: support merging frontmatter with tp.file.include#1643

Merged
Zachatoo merged 6 commits intoSilentVoid13:masterfrom
AndyEveritt:fix-mergefrontmatter
Jan 28, 2026
Merged

feat: support merging frontmatter with tp.file.include#1643
Zachatoo merged 6 commits intoSilentVoid13:masterfrom
AndyEveritt:fix-mergefrontmatter

Conversation

@AndyEveritt
Copy link
Copy Markdown
Contributor

@AndyEveritt AndyEveritt commented Sep 24, 2025

This adds support for merging template frontmatter when using tp.file.include

eg:

Root

---
some_frontmatter:
root_func: <% tp.date.now() %>
not_overwritten: 1
overwritten: 1
---
<%- tp.file.include("[[Sub]]") %>

top content

Sub

---
sub: 2
not_overwritten:
overwritten: 2
---

sub content
<% tp.file.include("[[Sub 2]]") %>

Sub 2

---
sub_func: <% tp.date.now() %>
---
sub 2 content

The expected output for this template is

---
some_frontmatter:
root_func: 2025-09-24
not_overwritten: 1
overwritten: 2
sub_func: 2025-09-24
sub: 2
---
sub content
sub 2 content

top content

This also works with tp.file.create_new() and files created with Bases

@AndyEveritt
Copy link
Copy Markdown
Contributor Author

AndyEveritt commented Sep 24, 2025

For details on how this feature works:

  • The frontmatter for the template is maintained separately from the contents of the template by adding a new field to RunningConfig called frontmatter
  • Parsing of <% tp... %> blocks is executed
    • Any tp.file.include has it's frontmatter processed, merged into the running_config.frontmatter, and removed from the included content
  • Once parsing of the root template has finished, any frontmatter is extracted
    • It is done at this point so tp functions like tp.date.now() are still parsed correctly
  • The running_config.frontmatter is merged into the root frontmatter and running_config.frontmatter is updated with the result
    • It is done this way so included templates overwrite the parent if they have overlapping property keys
  • The running_config.frontmatter is now a parsed & merged frontmatter for the root and all included templates
  • Depending on how templater was initiated the following happens:
    • create_new_note_from_template(): this is from tp.file.create_new() or the Obsidian command Templater: Create new note from template, the output_content is updated to have the merged frontmatter
    • append_template_to_active_file(): the merged template frontmatter is merged into any existing file frontmatter
    • write_template_to_file: frontmatter is merged with existing file frontmatter. Existing file frontmatter will typically only exist if the file was created by a Base

@AndyEveritt
Copy link
Copy Markdown
Contributor Author

Btw I think there is a fundamental issue with the config system in Templater. When you have nested calls such as a tp.file.create_new() inside a template included with tp.file.include(), the config for create_new overwrites the config for include so even after the create_new has finished processing, the include config is uses the create_new config.

This essentially means that config.target_file, config.active_file and the new config.frontmatter are now pointing to the wrong thing which will cause various weird issues.

In this case it means if you have a template which is includes another template that creates a file, the frontmatter of the template which creates the file won't be merged into the frontmatter of the root template.

@AndyEveritt
Copy link
Copy Markdown
Contributor Author

I've fixed the config issue by creating a new instance of the modules in functions_object each time the Templater.parse_template() is called. Before a singleton was used for each InternalModule which was leading to issues as the configs were getting overwritten

@AndyEveritt
Copy link
Copy Markdown
Contributor Author

@Zachatoo have you had a chance to review this?

@Zachatoo
Copy link
Copy Markdown
Collaborator

Sorry I have not! I'll need to do some testing with this, hopefully I'll have time this weekend

@Fred-Vatin
Copy link
Copy Markdown

Fred-Vatin commented Dec 11, 2025

Any chance this PR can be merged since it has no conflicts ?

Just tested and it works flawlessly. Thanks @AndyEveritt

@AndyEveritt
Copy link
Copy Markdown
Contributor Author

@Zachatoo would it be possible to merge this pr?

Copy link
Copy Markdown
Collaborator

@Zachatoo Zachatoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndyEveritt Can you also update the docs in documentation.toml to briefly describe how frontmatter will be merged from included templates? Search for [tp.file.functions.include] in that file to find the right section.

Comment thread src/core/Templater.ts
Copilot AI review requested due to automatic review settings January 27, 2026 10:02
@AndyEveritt
Copy link
Copy Markdown
Contributor Author

@Zachatoo all your comments have been addressed

This comment was marked as off-topic.

@Zachatoo Zachatoo merged commit db9a91e into SilentVoid13:master Jan 28, 2026
5 of 7 checks passed
@Zachatoo
Copy link
Copy Markdown
Collaborator

@AndyEveritt There have been several reports of other plugins breaking with this latest update (chhoumann/quickadd#1085, chhoumann/quickadd#1086, #1695). There may be others that I haven't seen yet. I'm going to revert this change for now as I don't have time to try to fix this. Feel free to put up another PR with your changes that has backwards compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants