Render file metadata in Publish

What I’m trying to do

I have files that represent references to external resources. I use tags and url metadata fields.
In the app they look great because the url is visible and clickable. But on Publish they don’t. I would like the url at least to be visible. And I would rather keep the information in metadata since the file content might be a summary of the content.

Things I have tried

I use publish on a custom domain so having a publish.js to achieve this is an option.

I see that there is a <pre class="frontmatter language-yaml" style="display: none;" tabindex="0"> in the publish pages with the metadata. I guess I could parse it’s innerText as frontmatter to grab the url.

:question: Is there a better api to access the current file metadata in publish.js? I was not able to find documentation on that.

Another alternative would be to have some kind of template for these external references files. I tried templater and dataview. My attempts to have some sort of base template or partial to be included in all files and have a single template code to expand url and tags have failed.

:question: Is there a way to have this sort of base template embedded in other files and use the embedding file as context for the template?

:question: Is there any other approach to render the metadata in a nice way in publish?

Thanks!

Based on other publish.js examples I ended up with this solution that will extract the url field from the metadata and render a link.

For more structured metadata a yaml js parser should be used.

function initialize() {
  document.querySelectorAll('pre.frontmatter.language-yaml').forEach(fm => {
    if (fm.classList.contains("done")) return;
    fm.classList.add("done");

    const url = fm.innerText.split("\n").filter(x => x.startsWith("url: "))[0].slice(5);

    const n = document.createElement("a");
    n.innerText = "🔗 " + url;
    n.setAttribute("href", url);
    n.setAttribute("target", "_blank");
    fm.insertAdjacentElement("afterend", n);
  });
}

// Observer to watch for changes in the DOM
const observer = new MutationObserver(function (mutations) {
  mutations.forEach(function (mutation) {
    if (mutation.addedNodes.length > 0) {
      initialize();
    }
  });
});

// Start observing the document body for added nodes
observer.observe(document.body, {
  childList: true,
  subtree: true
});

// Run initialize at the start to catch any images already in the DOM
initialize();

Thanks for adding the final publish.js. I have added this to Obsidian Publish resources :slight_smile:

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.