diff --git a/src/main.ts b/src/main.ts index 9260a2f..4fc76b8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -175,6 +175,7 @@ export default class OmnivorePlugin extends Plugin { folderDateFormat, isSingleFile, frontMatterVariables, + frontMatterTemplate, } = this.settings; if (syncing) { @@ -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" ); @@ -246,6 +249,7 @@ export default class OmnivorePlugin extends Plugin { this.settings.dateSavedFormat, isSingleFile, frontMatterVariables, + frontMatterTemplate, fileAttachment ); // use the custom filename @@ -690,7 +694,7 @@ class OmnivoreSettingTab extends PluginSettingTab { }) ); - containerEl.createEl("h3", { + containerEl.createEl("h5", { cls: "omnivore-collapsible", text: "Advanced Settings", }); @@ -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 plugin's GitHub page or email us at feedback@omnivore.app.`; diff --git a/src/settings/index.ts b/src/settings/index.ts index 64bd9bf..e77b80b 100644 --- a/src/settings/index.ts +++ b/src/settings/index.ts @@ -39,6 +39,7 @@ export const DEFAULT_SETTINGS: OmnivoreSettings = { frequency: 0, intervalId: 0, frontMatterVariables: [], + frontMatterTemplate: "", }; export enum Filter { @@ -72,4 +73,5 @@ export interface OmnivoreSettings { frequency: number; intervalId: number; frontMatterVariables: string[]; + frontMatterTemplate: string; } diff --git a/src/settings/template.ts b/src/settings/template.ts index 8534c64..64536eb 100644 --- a/src/settings/template.ts +++ b/src/settings/template.ts @@ -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, @@ -164,6 +164,7 @@ export const renderArticleContnet = async ( dateSavedFormat: string, isSingleFile: boolean, frontMatterVariables: string[], + frontMatterTemplate: string, fileAttachment?: string ) => { // filter out notes and redactions @@ -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; + } } }