Repository navigation
fix: resolve Templater lazily so its syntax is processed in templates - #497
Merged
Merged
Conversation
The template service was resolved once, during our onload, by reading `app.plugins.plugins["templater-obsidian"]?.templater`. Obsidian enables plugins in the order they appear in `community-plugins.json`, and Templater only exposes that API partway through its own onload, so whenever we happen to load first the lookup found nothing and we silently fell back to the basic template service for the whole session. The basic service creates notes with the content untouched and its `replaceVariablesInFile` is a no-op, so templater syntax was left unprocessed in both the "Insert template" and "Create note from template" commands, for the whole session, depending only on plugin load order. Resolve the service on every access instead, caching it once Templater is actually there. Closes #411
Greptile SummaryThe PR replaces eager template-service selection with a lazy resolver so Modal Form can discover Templater after plugin startup ordering initially makes its API unavailable.
Confidence Score: 5/5The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issues identified. The lazy resolver preserves fallback behavior while allowing subsequent template operations to discover and cache Templater after its API becomes available.
|
| Filename | Overview |
|---|---|
| src/core/template/getTemplateService.ts | Adds lazy service resolution that repeatedly checks for Templater and caches it once available; no actionable defect was established. |
| src/main.ts | Replaces the eagerly assigned service field with a getter backed by the lazy resolver while preserving existing call sites. |
| src/core/template/getTemplateService.test.ts | Covers basic and Templater selection, delayed API availability, and successful-service caching. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Template operation accesses templateService] --> B{Templater service cached?}
B -->|Yes| C[Return cached TemplaterService]
B -->|No| D{Templater API currently available?}
D -->|Yes| E[Create and cache TemplaterService]
D -->|No| F[Return BasicTemplateService without caching]
E --> G[Execute template operation]
C --> G
F --> G
Reviews (1): Last reviewed commit: "fix: resolve Templater lazily so its syn..." | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #411
The bug
getTemplateServicewas called exactly once, fromonload:and it decides which service to use by reading:
Obsidian enables plugins in the order they appear in
community-plugins.json, and Templater only assignsthis.templater = new Templater(this)partway through its ownonload. Whenever Modal Form loads before Templater, that lookup finds nothing and we bindBasicTemplateServicefor the entire session.BasicTemplateServicewrites the note content verbatim and itsreplaceVariablesInFileis a literal no-op, so templater syntax is left untouched in:Insert template: <form>andInsert form template(thereplaceVariablesInFilecall after saving does nothing)Create note from template: <form>andCreate new note from a form(vault.createwith the raw content)Because it depends only on plugin ordering, it reproduces for some vaults and not others. This repo's own
EXAMPLE_VAULT/.obsidian/community-plugins.jsonhasmodalformslisted beforetemplater-obsidian, which is the broken order.Why it isn't a template syntax error on the user's side
If Templater had run and failed to parse,
create_new_note_from_templatedeletes the created note and returnsundefined, whichTemplaterServicealready detects and turns into the retry form. Reporters instead get a note containing the raw<% ... %>text and no retry form, including for trivially valid snippets like<% "---" %>— Templater was never invoked.The fix
Resolve the service at the moment it is used instead of at load time, via a new
makeTemplateServiceResolver. It re-checks for Templater while only the basic fallback is available, and caches the service once Templater is actually there (Templater cannot vanish without a plugin reload).main.tskeeps atemplateServicegetter, so every existing call site is unchanged.Testing
src/core/template/getTemplateService.test.tscovers both services being selected correctly, the resolver picking up Templater when it loads after the resolver was created, and the caching behaviour.npm run buildandnpm run testpass locally (230 tests).Not verified against a real Obsidian vault — the diagnosis is derived from the plugin load-order behaviour and Templater's source.
Noted but not changed
setImmediate(this.templateService.replaceVariablesInFile(file))(src/main.ts, both insert commands) discards theLeftand relies onsetImmediate, which does not exist on Obsidian mobile. Worth a separate fix.