Skip to content

Commit 0a89dd7

Browse files
authored
[ENG-425] Fix template frontmatter bug (#219)
* fix bug * format * address PR comments * address PR comments
1 parent 00b93bc commit 0a89dd7

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

apps/obsidian/src/utils/templates.ts

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,49 @@
1-
import { App, TFile, TFolder, TAbstractFile } from "obsidian";
1+
import {
2+
App,
3+
TFile,
4+
TFolder,
5+
TAbstractFile,
6+
getFrontMatterInfo,
7+
} from "obsidian";
28

39
type TemplatePluginInfo = {
410
isEnabled: boolean;
511
folderPath: string;
612
};
713

14+
const mergeFrontmatter = (
15+
template: Record<string, any>,
16+
current: Record<string, any>,
17+
): Record<string, any> => {
18+
const result = { ...template };
19+
20+
for (const [key, currentValue] of Object.entries(current)) {
21+
const templateValue = result[key];
22+
23+
if (templateValue === undefined) {
24+
result[key] = currentValue;
25+
} else if (Array.isArray(templateValue) && Array.isArray(currentValue)) {
26+
const merged = [...templateValue, ...currentValue];
27+
result[key] = [...new Set(merged)];
28+
} else if (
29+
typeof templateValue === "object" &&
30+
templateValue !== null &&
31+
typeof currentValue === "object" &&
32+
currentValue !== null &&
33+
!Array.isArray(templateValue) &&
34+
!Array.isArray(currentValue)
35+
) {
36+
// Both are objects, merge recursively
37+
result[key] = mergeFrontmatter(templateValue, currentValue);
38+
} else {
39+
// Current value takes precedence for primitives
40+
result[key] = currentValue;
41+
}
42+
}
43+
44+
return result;
45+
};
46+
847
export const getTemplatePluginInfo = (app: App): TemplatePluginInfo => {
948
try {
1049
const templatesPlugin = (app as any).internalPlugins?.plugins?.templates;
@@ -86,11 +125,28 @@ export const applyTemplate = async ({
86125

87126
const templateContent = await app.vault.read(templateFile);
88127

89-
const currentContent = await app.vault.read(targetFile);
128+
const templateFrontmatter =
129+
app.metadataCache.getFileCache(templateFile)?.frontmatter || {};
130+
const currentFrontmatter =
131+
app.metadataCache.getFileCache(targetFile)?.frontmatter || {};
132+
133+
const mergedFrontmatter = mergeFrontmatter(
134+
templateFrontmatter,
135+
currentFrontmatter,
136+
);
90137

91-
const newContent = currentContent + templateContent;
138+
await app.fileManager.processFrontMatter(targetFile, (fm) => {
139+
Object.assign(fm, mergedFrontmatter);
140+
});
92141

93-
await app.vault.modify(targetFile, newContent);
142+
const frontmatterInfo = getFrontMatterInfo(templateContent);
143+
const templateBody = frontmatterInfo.exists
144+
? templateContent.slice(frontmatterInfo.contentStart)
145+
: templateContent;
146+
147+
if (templateBody.trim()) {
148+
await app.vault.append(targetFile, templateBody);
149+
}
94150

95151
return true;
96152
} catch (error) {

0 commit comments

Comments
 (0)