Skip to content

Commit

Permalink
feat: add a optional front matter template under advanced settings
Browse files Browse the repository at this point in the history
  • Loading branch information
sywhb committed May 30, 2023
1 parent 942b93e commit afde987
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 24 deletions.
47 changes: 46 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export default class OmnivorePlugin extends Plugin {
folderDateFormat,
isSingleFile,
frontMatterVariables,
frontMatterTemplate,
} = this.settings;

if (syncing) {
Expand All @@ -196,7 +197,9 @@ export default class OmnivorePlugin extends Plugin {
manualSync && new Notice("🚀 Fetching articles ...");

// pre-parse template
frontMatterTemplate && preParseTemplate(frontMatterTemplate);
const templateSpans = preParseTemplate(template);
// check if we need to include content or file attachment
const includeContent = templateSpans.some(
(templateSpan) => templateSpan[1] === "content"
);
Expand Down Expand Up @@ -246,6 +249,7 @@ export default class OmnivorePlugin extends Plugin {
this.settings.dateSavedFormat,
isSingleFile,
frontMatterVariables,
frontMatterTemplate,
fileAttachment
);
// use the custom filename
Expand Down Expand Up @@ -690,7 +694,7 @@ class OmnivoreSettingTab extends PluginSettingTab {
})
);

containerEl.createEl("h3", {
containerEl.createEl("h5", {
cls: "omnivore-collapsible",
text: "Advanced Settings",
});
Expand All @@ -712,6 +716,47 @@ class OmnivoreSettingTab extends PluginSettingTab {
})
);

new Setting(advancedSettings)
.setName("Front Matter Template")
.setDesc(
createFragment((fragment) => {
fragment.append(
"Enter template to render the front matter with ",
fragment.createEl("a", {
text: "Reference",
href: "https://docs.omnivore.app/integrations/obsidian.html#controlling-the-layout-of-the-data-imported-to-obsidian",
}),
fragment.createEl("br"),
"If this is empty, the front matter will be rendered with the front matter variables."
);
})
)
.addTextArea((text) => {
text
.setPlaceholder("Enter the template")
.setValue(this.plugin.settings.frontMatterTemplate)
.onChange(async (value) => {
this.plugin.settings.frontMatterTemplate = value;
await this.plugin.saveSettings();
});

text.inputEl.setAttr("rows", 10);
text.inputEl.setAttr("cols", 30);
})
.addExtraButton((button) => {
// add a button to reset template
button
.setIcon("reset")
.setTooltip("Reset front matter template")
.onClick(async () => {
this.plugin.settings.frontMatterTemplate =
DEFAULT_SETTINGS.frontMatterTemplate;
await this.plugin.saveSettings();
this.display();
new Notice("Front matter template reset");
});
});

const help = containerEl.createEl("p");
help.innerHTML = `For more information, please visit the <a href="https://github.com/omnivore-app/obsidian-omnivore/blob/master/README.md">plugin's GitHub page</a> or email us at <a href="mailto:feedback@omnivore.app">feedback@omnivore.app</a>.`;

Expand Down
2 changes: 2 additions & 0 deletions src/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const DEFAULT_SETTINGS: OmnivoreSettings = {
frequency: 0,
intervalId: 0,
frontMatterVariables: [],
frontMatterTemplate: "",
};

export enum Filter {
Expand Down Expand Up @@ -72,4 +73,5 @@ export interface OmnivoreSettings {
frequency: number;
intervalId: number;
frontMatterVariables: string[];
frontMatterTemplate: string;
}
74 changes: 51 additions & 23 deletions src/settings/template.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { truncate } from "lodash";
import Mustache from "mustache";
import { stringifyYaml } from "obsidian";
import { parseYaml, stringifyYaml } from "obsidian";
import { Article, HighlightType, PageType } from "../api";
import {
compareHighlightsInFile,
Expand Down Expand Up @@ -164,6 +164,7 @@ export const renderArticleContnet = async (
dateSavedFormat: string,
isSingleFile: boolean,
frontMatterVariables: string[],
frontMatterTemplate: string,
fileAttachment?: string
) => {
// filter out notes and redactions
Expand Down Expand Up @@ -242,33 +243,60 @@ export const renderArticleContnet = async (
...functionMap,
};

const frontMatter: { [id: string]: unknown } = {
let frontMatter: { [id: string]: unknown } = {
id: article.id, // id is required for deduplication
};

for (const item of frontMatterVariables) {
// split the item into variable and alias
const aliasedVariables = item.split("::");
const variable = aliasedVariables[0];
// we use snake case for variables in the front matter
const articleVariable = snakeToCamelCase(variable);
// use alias if available, otherwise use variable
const key = aliasedVariables[1] || variable;
if (
variable === "tags" &&
articleView.labels &&
articleView.labels.length > 0
) {
// tags are handled separately
// use label names as tags
frontMatter[key] = articleView.labels.map((l) => l.name);
continue;
// if the front matter template is set, use it
if (frontMatterTemplate) {
const frontMatterTemplateRendered = Mustache.render(
frontMatterTemplate,
articleView
);
try {
// parse the front matter template as yaml
const frontMatterParsed = parseYaml(frontMatterTemplateRendered);

frontMatter = {
...frontMatterParsed,
...frontMatter,
};
} catch (error) {
// if there's an error parsing the front matter template, log it
console.error("Error parsing front matter template", error);
// and add the error to the front matter
frontMatter = {
...frontMatter,
omnivore_error:
"There was an error parsing the front matter template. See console for details.",
};
}
} else {
// otherwise, use the front matter variables
for (const item of frontMatterVariables) {
// split the item into variable and alias
const aliasedVariables = item.split("::");
const variable = aliasedVariables[0];
// we use snake case for variables in the front matter
const articleVariable = snakeToCamelCase(variable);
// use alias if available, otherwise use variable
const key = aliasedVariables[1] || variable;
if (
variable === "tags" &&
articleView.labels &&
articleView.labels.length > 0
) {
// tags are handled separately
// use label names as tags
frontMatter[key] = articleView.labels.map((l) => l.name);
continue;
}

const value = (articleView as any)[articleVariable];
if (value) {
// if variable is in article, use it
frontMatter[key] = value;
const value = (articleView as any)[articleVariable];
if (value) {
// if variable is in article, use it
frontMatter[key] = value;
}
}
}

Expand Down

0 comments on commit afde987

Please sign in to comment.