-
-
Notifications
You must be signed in to change notification settings - Fork 261
feat: merge frontmatter properties when inserting a template & allow templater to work with Bases core plugin #1601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
912b646
8e868e5
4868c4a
3e8af20
2cc0480
c0ce024
26f4001
0243630
f84ea88
108c3cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { | ||
| App, | ||
| getFrontMatterInfo, | ||
| MarkdownPostProcessorContext, | ||
| MarkdownView, | ||
| normalizePath, | ||
|
|
@@ -13,6 +14,7 @@ import { | |
| get_active_file, | ||
| get_folder_path_from_file_path, | ||
| resolve_tfile, | ||
| merge_front_matter, | ||
| } from "utils/Utils"; | ||
| import TemplaterPlugin from "main"; | ||
| import { | ||
|
|
@@ -22,6 +24,7 @@ import { | |
| import { errorWrapper, errorWrapperSync, TemplaterError } from "utils/Error"; | ||
| import { Parser } from "./parser/Parser"; | ||
| import { log_error } from "utils/Log"; | ||
| import * as yaml from "js-yaml"; | ||
|
|
||
| export enum RunMode { | ||
| CreateNewFromTemplate, | ||
|
|
@@ -254,10 +257,20 @@ export class Templater { | |
| return; | ||
| } | ||
|
|
||
| const front_matter_info = getFrontMatterInfo(output_content); | ||
| const frontmatter = yaml.load(front_matter_info.frontmatter); | ||
| await merge_front_matter( | ||
| this.plugin.app, | ||
| active_editor.file, | ||
| frontmatter | ||
| ); | ||
|
|
||
| const editor = active_editor.editor; | ||
| const doc = editor.getDoc(); | ||
| const oldSelections = doc.listSelections(); | ||
| doc.replaceSelection(output_content); | ||
| doc.replaceSelection( | ||
| output_content.slice(front_matter_info.contentStart) | ||
| ); | ||
| if (active_view) { | ||
| // Wait for view to finish rendering properties widget | ||
| await delay(100); | ||
|
|
@@ -293,7 +306,7 @@ export class Templater { | |
| file, | ||
| RunMode.OverwriteFile | ||
| ); | ||
| const output_content = await errorWrapper( | ||
| let output_content = await errorWrapper( | ||
| async () => this.read_and_parse_template(running_config), | ||
| "Template parsing error, aborting." | ||
| ); | ||
|
|
@@ -302,7 +315,30 @@ export class Templater { | |
| await this.end_templater_task(path); | ||
| return; | ||
| } | ||
| await this.plugin.app.vault.modify(file, output_content); | ||
|
|
||
| let existing_front_matter = null; | ||
| await delay(100); // Sometimes the front matter is not yet available if the file was just created | ||
| await this.plugin.app.fileManager.processFrontMatter( | ||
| file, | ||
| (front_matter) => { | ||
| existing_front_matter = front_matter; | ||
| } | ||
| ); | ||
|
|
||
| const front_matter_info = getFrontMatterInfo(output_content); | ||
| const frontmatter = yaml.load(front_matter_info.frontmatter); | ||
|
|
||
| if (existing_front_matter) { | ||
| // Bases can create frontmatter, merge this into the template frontmatter | ||
| await merge_front_matter(this.plugin.app, file, frontmatter); | ||
| await this.plugin.app.vault.append( | ||
| file, | ||
| output_content.slice(front_matter_info.contentStart) | ||
| ); | ||
| output_content = await this.plugin.app.vault.read(file); | ||
| } else { | ||
| await this.plugin.app.vault.modify(file, output_content); | ||
| } | ||
|
Comment on lines
+319
to
+341
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a lot of reading and writing going on that could potentially cause issues with other plugins. Ideally we should be doing a single atomic operation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To counter this. What if you have a template that includes another template which sets a property, then you want to use the value of the property in the parent template. Each template should have access to the frontmatter introduced by the included templates. I think the most reliable way of doing that is merging and writing the frontmatter for each included template. An example
Note I think the above example doesn't work with either of our code since the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather update |
||
| // Set cursor to first line of editor (below properties) | ||
| // https://github.com/SilentVoid13/Templater/issues/1231 | ||
| if ( | ||
|
|
@@ -491,8 +527,13 @@ export class Templater { | |
| return; | ||
| } | ||
|
|
||
| const file_content = await app.vault.read(file); | ||
| const frontmatter_info = getFrontMatterInfo(file_content); | ||
| const content_size = | ||
| file_content.length - frontmatter_info.contentStart; | ||
|
|
||
| if ( | ||
| file.stat.size == 0 && | ||
| content_size == 0 && | ||
| templater.plugin.settings.enable_folder_templates | ||
| ) { | ||
| const folder_template_match = | ||
|
|
@@ -512,7 +553,7 @@ export class Templater { | |
| } | ||
| await templater.write_template_to_file(template_file, file); | ||
| } else if ( | ||
| file.stat.size == 0 && | ||
| content_size == 0 && | ||
| templater.plugin.settings.enable_file_templates | ||
| ) { | ||
| const file_template_match = | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| import { InternalModule } from "../InternalModule"; | ||
| import { log_error } from "utils/Log"; | ||
| import * as yaml from "js-yaml"; | ||
| import { | ||
| FileSystemAdapter, | ||
| getAllTags, | ||
| getFrontMatterInfo, | ||
| moment, | ||
| normalizePath, | ||
| parseLinktext, | ||
|
|
@@ -13,6 +15,7 @@ import { | |
| } from "obsidian"; | ||
| import { TemplaterError } from "utils/Error"; | ||
| import { ModuleName } from "editor/TpDocumentation"; | ||
| import { merge_front_matter } from "utils/Utils"; | ||
|
|
||
| export const DEPTH_LIMIT = 10; | ||
|
|
||
|
|
@@ -210,14 +213,20 @@ export class InternalModuleFile extends InternalModule { | |
| } | ||
| } | ||
|
|
||
| const active_file = this.plugin.app.workspace.getActiveFile(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may not always be the active file, since you can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can use the target file from the running config? Same place we get |
||
|
|
||
| try { | ||
| const parsed_content = | ||
| await this.plugin.templater.parser.parse_commands( | ||
| inc_file_content, | ||
| this.plugin.templater.current_functions_object | ||
| ); | ||
| const front_matter_info = getFrontMatterInfo(parsed_content); | ||
| const frontmatter = yaml.load(front_matter_info.frontmatter); | ||
| await merge_front_matter(this.plugin.app, active_file, frontmatter); | ||
AndyEveritt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| this.include_depth -= 1; | ||
| return parsed_content; | ||
| return parsed_content.slice(front_matter_info.contentStart); | ||
| } catch (e) { | ||
| this.include_depth -= 1; | ||
| throw e; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use
parseYamlandstringifyYamlfrom'obsidian'instead.