diff --git a/README.md b/README.md index 5a3e0902..c7a94ea5 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,77 @@ The plugin allows you to set a template note that gets added to the end of any n The plugin also offers simple template tags, for example `{{ title }}`, which will be replaced by the title of the media being imported. Note that template tags are surrounded by two curly braces and spaces. The spaces inside the curly braces are important! -For arrays, there are two special ways of displaying them: +**Array Operators** + +For arrays, there are several operators available for different formatting needs: + +Body Text Operators (no quotes) + +- `{{ LIST:variable_name }}` - Unlinked list: -- using `{{ LIST:variable_name }}` will result in: ``` - element 1 - element 2 - element 3 - - ... ``` -- using `{{ ENUM:variable_name }}` will result in: + +- `{{ LIST:[[variable_name]] }}` - Wikilinked list: + + ``` + - [[element 1]] + - [[element 2]] + - [[element 3]] + ``` + +- `{{ ENUM:variable_name }}` - Unlinked comma-separated: + + ``` + element 1, element 2, element 3 + ``` + +- `{{ ENUM:[[variable_name]] }}` - Wikilinked comma-separated: + ``` + [[element 1]], [[element 2]], [[element 3]] ``` - element 1, element 2, element 3, ... + +YAML Frontmatter Operators (with quotes) + +- `{{ LISTYAML:variable_name }}` - Unlinked YAML list: + + ```yaml + variable_name: + - element 1 + - element 2 + - element 3 ``` +- `{{ LISTYAML:[[variable_name]] }}` - Wikilinked YAML list (recognized by Obsidian): + + ```yaml + variable_name: + - '[[element 1]]' + - '[[element 2]]' + - '[[element 3]]' + ``` + +- `{{ ENUMYAML:variable_name }}` - Comma-separated for YAML (no wikilink support): + ```yaml + variable_name: element 1, element 2, element 3 + ``` + +Single Element Operators + +- `{{ FIRST:variable_name }}` - Returns the first element of an array +- `{{ FIRST:[[variable_name]] }}` - Returns the first element as a wikilink: `[[element 1]]` +- `{{ LAST:variable_name }}` - Returns the last element of an array +- `{{ LAST:[[variable_name]] }}` - Returns the last element as a wikilink: `[[element 3]]` + +**Wikilink Support** + +Wrap the variable name in double brackets `[[variable_name]]` to create wikilinks for array elements. This works with `LIST`, `LISTYAML`, `ENUM`, `FIRST`, and `LAST` operators. Note that `ENUMYAML` does not support wikilinks - the `[[]]` syntax will be ignored. + +**Important:** Use `YAML` variants (`LISTYAML`, `ENUMYAML`) in frontmatter and regular variants (`LIST`, `ENUM`) in the note body. + Available variables that can be used in template tags are any front-matter properties. I also published my own templates [here](https://github.com/mProjectsCode/obsidian-media-db-templates). @@ -125,7 +182,7 @@ Now you select the result you want, and the plugin will cast its magic, creating | [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) | The Wikipedia API allows access to all Wikipedia articles. | wiki articles | No | None | No | | [Steam](https://store.steampowered.com/) | The Steam API offers information on all Steam games. | games | No | 10000 per day | No | | [Open Library](https://openlibrary.org) | The OpenLibrary API offers metadata for books | books | No | Cover access is rate-limited when not using CoverID or OLID by max 100 requests/IP every 5 minutes. This plugin uses OLID, so there shouldn't be a rate limit. | No | -| Comic Vine | The Comic Vine API offers metadata for comic books | comicbooks | Yes, by making an account [here](https://comicvine.gamespot.com/login-signup/) and going to the [api section](https://comicvine.gamespot.com/api/) of the site | 200 requests per resource, per hour. There is also a velocity detection to prevent malicious use. If too many requests are made per second, you may receive temporary blocks to resources. | No | +| [Comic Vine](https://comicvine.gamespot.com/) | The Comic Vine API offers metadata for comic books | comicbooks | Yes, by making an account [here](https://comicvine.gamespot.com/login-signup/) and going to the [api section](https://comicvine.gamespot.com/api/) of the site | 200 requests per resource, per hour. There is also a velocity detection to prevent malicious use. If too many requests are made per second, you may receive temporary blocks to resources. | No | | [VNDB](https://vndb.org/) | The VNDB API offers metadata for visual novels | games | No | 200 requests per 5 minutes | Yes | | [Boardgame Geek](https://boardgamegeek.com) | The Boardgame Geek API offers metadata for boardgames | boardgames | Yes, by making an account [here](https://boardgamegeek.com/join/) and then [requesting an application token](https://boardgamegeek.com/applications) | Exact usage limits are still undetermined | No | diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 00000000..cef7de28 Binary files /dev/null and b/bun.lockb differ diff --git a/packages/obsidian/src/settings/Settings.ts b/packages/obsidian/src/settings/Settings.ts index b0885f55..e5da015d 100644 --- a/packages/obsidian/src/settings/Settings.ts +++ b/packages/obsidian/src/settings/Settings.ts @@ -581,7 +581,7 @@ export class MediaDbSettingTab extends PluginSettingTab { apiKeyGroup.addSetting( setting => void setting - .setName('OMDb API key') + .setName('OMDb API Key') .setDesc('API key for "www.omdbapi.com".') .addComponent(el => { const component = new SecretComponent(this.app, el); @@ -613,7 +613,7 @@ export class MediaDbSettingTab extends PluginSettingTab { apiKeyGroup.addSetting( setting => void setting - .setName('Moby Games key') + .setName('Moby Games Key') .setDesc('API key for "www.mobygames.com".') .addComponent(el => { const component = new SecretComponent(this.app, el); diff --git a/packages/obsidian/src/utils/Utils.ts b/packages/obsidian/src/utils/Utils.ts index cc5b2bd9..6dae5f38 100644 --- a/packages/obsidian/src/utils/Utils.ts +++ b/packages/obsidian/src/utils/Utils.ts @@ -34,9 +34,9 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel, ignoreUndefin tag = tag.trim(); const parts = tag.split(':'); + if (parts.length === 1) { const path = parts[0].split('.'); - const obj = traverseMetaData(path, mediaTypeModel); if (obj === undefined) { @@ -47,9 +47,18 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel, ignoreUndefin return obj?.toString() ?? 'null'; } else if (parts.length === 2) { const operator = parts[0]; + let pathString = parts[1]; - const path = parts[1].split('.'); + // Check if the path is wrapped in [[]] for wikilinks + const wikilinkMatch = /^\[\[(.+?)\]\]$/.exec(pathString); + const useWikilinks = !!wikilinkMatch; + // Extract the actual path (remove [[ ]] if present) + if (wikilinkMatch) { + pathString = wikilinkMatch[1]; + } + + const path = pathString.split('.'); const obj = traverseMetaData(path, mediaTypeModel); if (obj === undefined) { @@ -61,11 +70,39 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel, ignoreUndefin return '{{ INVALID TEMPLATE TAG - operator LIST is only applicable on an array }}'; } - return obj.map((e: unknown) => `- ${e}`).join('\n'); + if (useWikilinks) { + // LIST with wikilinks: no quotes for body text + return obj.map((e: unknown) => `\n - [[${e}]]`).join(''); + } else { + return obj.map((e: unknown) => `\n - ${e}`).join(''); + } + } else if (operator === 'LISTYAML') { + if (!Array.isArray(obj)) { + return '{{ INVALID TEMPLATE TAG - operator LISTYAML is only applicable on an array }}'; + } + + if (useWikilinks) { + // LISTYAML with wikilinks: quoted for frontmatter + return obj.map((e: unknown) => `\n - "[[${e}]]"`).join(''); + } else { + return obj.map((e: unknown) => `\n - ${e}`).join(''); + } } else if (operator === 'ENUM') { if (!Array.isArray(obj)) { return '{{ INVALID TEMPLATE TAG - operator ENUM is only applicable on an array }}'; } + + if (useWikilinks) { + // ENUM with wikilinks: no quotes for body text + return obj.map((e: unknown) => `[[${e}]]`).join(', '); + } else { + return obj.join(', '); + } + } else if (operator === 'ENUMYAML') { + if (!Array.isArray(obj)) { + return '{{ INVALID TEMPLATE TAG - operator ENUMYAML is only applicable on an array }}'; + } + // ENUMYAML - always comma-separated, no wikilinks support and [[]] syntax is simply ignored since they are not valid in comma-separated YAML values return obj.join(', '); } else if (operator === 'FIRST') { if (!Array.isArray(obj)) { @@ -73,14 +110,26 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel, ignoreUndefin } const first = obj[0] as unknown; - return first?.toString() ?? 'null'; + const value = first?.toString() ?? 'null'; + + if (useWikilinks && value !== 'null') { + return `[[${value}]]`; + } else { + return value; + } } else if (operator === 'LAST') { if (!Array.isArray(obj)) { return '{{ INVALID TEMPLATE TAG - operator LAST is only applicable on an array }}'; } const last = obj[obj.length - 1] as unknown; - return last?.toString() ?? 'null'; + const value = last?.toString() ?? 'null'; + + if (useWikilinks && value !== 'null') { + return `[[${value}]]`; + } else { + return value; + } } return `{{ INVALID TEMPLATE TAG - unknown operator ${operator} }}`;