Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] Add "Export view" fields in page frontmatter #266

Open
josephgarnier opened this issue Oct 28, 2024 · 1 comment
Open

[Suggestion] Add "Export view" fields in page frontmatter #266

josephgarnier opened this issue Oct 28, 2024 · 1 comment

Comments

@josephgarnier
Copy link

josephgarnier commented Oct 28, 2024

Hello dear dev!

Using the view can become quite time-consuming when you have to manage several export commands depending on the type of page.

It would be amazing if we could list the export commands to be executed in the frontmatter, with their arguments, and then call them with a single command Execute all commands on page.

A such page frontmatter declaration could be:

export:
  <name-of-export-command-1>:
    destination: <file-path>
    <param-1>: '<value-1>'
    <param-2>: ['<value-1>', '<value-2>']
  <name-of-export-command-2>:
    destination: <file-path>

The good news is that the Obsidian API can already handle frontmatter inner properties. Here is an example of code in JS to parse export and get its values:

/**
 * Get inside the frontmatter the value of the property `propertyName`.
 * @param {App} app A reference to the Obsidian `app`.
 * @param {Obsidian} obsidian A reference to the Obsidian API.
 * @param {TFile} file Vault file to parse.
 * @param {string} propertyName Property name of the value to get.
 * @returns {any|null} Value inside the frontmatter of `file`.
 * @throws {Error} If the property doesn't exists.
 */
static getFrontMatterEntry(app, obsidian, file, propertyName) {
  const fileFrontMatter = app.metadataCache.getFileCache(file)?.frontmatter;
  if (
    !fileFrontMatter ||
    !Object.keys(fileFrontMatter).includes(propertyName)
  )
    throw new Error(
      `The property '${propertyName}' doesn't exists in the file '${file.path}'.`
    );

  const propertyValue = obsidian.parseFrontMatterEntry(
    fileFrontMatter,
    propertyName
  );
  return propertyValue;
}

/**
 * Check if the frontmatter has a the property `propertyName`
 * @alias UtilityObsidian:getFrontMatterAliases
 * @param {App} app A reference to the Obsidian `app`.
 * @param {TFile} file Vault file to parse.
 * @param {string} propertyName Property name to check.
 * @returns {boolean} `true` if frontmatter has the property; otherwise `false`.
 */
static hasFrontMatterEntry(app, file, propertyName) {
  const fileFrontMatter = app.metadataCache.getFileCache(file)?.frontmatter;
  if (
    !fileFrontMatter ||
    !Object.keys(fileFrontMatter).includes(propertyName)
  )
    return false;

  return true;
}

/**
 * Extract the command arguments defined in the frontmatter property 'export' of the invoker page `invokerPage`.
 * @param {TFile} invokerPage Page that call the script.
 * @returns {Map<string,object>} Args of each command defined in the page. Map is in the form `{ key: <command-name>, value: <command-args-object> }`.
 * @throws {Error} If `invokerPage` has not property 'script' in its frontmatter, or if a script declaration is malformed.
 */
function extractAllCommandArgs(invokerPage) {
  if (!MyClass.hasFrontMatterEntry(Context.app, invokerPage, "export")) {
    throw new Error(
      `The frontmatter property 'export' is missing in '${invokerPage.basename}'!`
    );
  }

  /** @type {object} */
  const allScripts = MyClass.getFrontMatterEntry(
    Context.app,
    Context.obsidian,
    invokerPage,
    "export"
  );
  if (allScripts == null)
    throw new Error(
      `The frontmatter property 'export' is not defined in '${invokerPage.basename}'!`
    );

  /** @type {Map<string,Object|null>} */
  const scriptMap = new Map(Object.entries(allScripts));
  if (Array.from(scriptMap.values()).includes(null))
    throw new Error(
      `The frontmatter property 'export' is malformed! An argument list cannot be null, use '{}'.`
    );

  return scriptMap;
}

ps: Thank you very much for this very useful plugin.

@mokeyish
Copy link
Owner

Thanks for your suggestion, but my energy is limited and I don't need this feature. If you think it is useful, PR is welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants