Show properties of a note in the published pages

Oh, what a pity, I guess it doesn’t works with sliding pages…

Really needed!!!

1 Like

Would be great to have this for last edited time and created and links

1 Like

I just assumed this would be included by default. Would love to see it available

1 Like

My usecase is that I use the properties to link notes together. For example a note could link to a map of content note or another related note using frontmatter properties.
It seems obsidian publish ignores this entirely. Is there a way around that or any plan to support this feature?

2 Likes

Same use case!

+1 this feature

Same need here. +1 for this feature !

+1 would be great to have all Tags in the properties but they are still visible in publish (with no custom domain)

1 Like

This was exactly the kind of workaround I have been hoping to implement! Thank you!

I was able to combine both a date and tags, but I noticed that on some notes with a lot of tags, the list will run off page and cut off information. Would you happen to have any ideas on how to fix this? I attached a screenshot below and a URL to an example page.

Also, and I’m not sure if this is because I combined dates and tags, but clicking on the date seems to treat it like a tag, pulling up a dialog that says

“Pages with tag Published:2024/05/10
There are no pages that contain this tag.”

Looking at your page does seem to indicate to me that this is a goof on my part. :sweat_smile: Any ideas on how to separate the two? Worse case, I could ditch tags I suppose. I care more about the date in this instance.

I appreciate any help you could give!

I found your tutorial @tadashi-aikawa and was able to figure out both of my questions. Thanks for creating that! I appreciate it. :grin:

1 Like

another +1 on this!

+1 from me!

Based on @tadashi-aikawa 's solution, I expanded the publish.js code to accommodate more detailed CSS formatting through publish.css and allow more granular selection of properties shown.

In the example below I included Aliases, Tags and one string-property (“Type”) - other properties can be added by copy-pasting the Type sections. The CSS file definitely has to be modified to match each theme but hopefully the code is clear enough.

Note: as far as I can tell, it doesn’t work with sliding panes and I haven’t been able to fix it myself. I don’t actually know Javascript, I just fiddled until something worked lol

/* PUBLISH.JS PROPERTIES */

let id;

function insertMetaDates() {
  const frontmatter = app.site.cache.cache[app.currentFilepath].frontmatter;
  if (!frontmatter) {
    return;
  }

/* selects the properties to be published */

  const type = frontmatter["type"]?.replaceAll("-", "/");
  const tags = frontmatter["tags"];
  const aliases = frontmatter["aliases"];

/* maps out and formats the tags */

  const tagElms = tags
  .map(
    (tag) => `
  <a href="#${tag}" class="tag" target="_blank" rel="noopener">#${tag}</a>
  `
  )
  .join("");

/* maps out and formats the aliases */

  const aliasElms = aliases
  .map(
    (alias) => `
  <a class="alias" target="_blank" rel="noopener">${alias}</a>
  `
  )
  .join("");


  const frontmatterEl = document.querySelector(".frontmatter");
  if (!frontmatterEl) {
    return;
  }

/* inserts the html */

  frontmatterEl.insertAdjacentHTML(
    "afterend",
    `
      <div class="propertyitemtable">
       <div id="typeproperty" class="propertyitem">type: ${type}</div>
      </div>
      <div id="tagsproperty" class="propertyitemtags">
       ${tagElms}
      </div>
      <div id="aliasesproperty" class="propertyitemaliases">
       ${aliasElms}
      </div>
`
  );


  /* makes sure that only existing properties are shown */

if (type) {
  document.getElementById('typeproperty').style.display = ""
} else {
  document.getElementById('typeproperty').style.display = "none"
}

if (aliases) {
  document.getElementById('aliasesproperty').style.display = ""
} else {
  document.getElementById('aliasesproperty').style.display = "none"
}

if (tags) {
  document.getElementById('tagsproperty').style.display = ""
} else {
  document.getElementById('tagsproperty').style.display = "none"
}

  clearInterval(id);
}

/* put the properties after the note title */

const onChangeDOM = (mutationsList, observer) => {
  for (let mutation of mutationsList) {
    if (
      mutation.type === "childList" &&
      mutation.addedNodes[0]?.className === "page-header"
    ) {
      clearInterval(id);
      id = setInterval(insertMetaDates, 50);
    }
  }
};

const targetNode = document.querySelector(
  ".markdown-preview-sizer.markdown-preview-section"
);
const observer = new MutationObserver(onChangeDOM);
observer.observe(targetNode, { childList: true, subtree: true });
id = setInterval(insertMetaDates, 50);
/* PUBLISH.CSS PROPERTIES */

/* formats the overall properties block except aliases and tags */

.propertyitemtable {
    display: block; 
    justify-content: end; 
    gap: 3px; 
    font-family: var(--font-monospace); 
    font-size: var(--font-smaller);
}

/* formats each row of properties */

.propertyitem {
    font-size: var(--font-smallest);
    font-weight: normal;
    z-index: 1;
    cursor: default;
    padding: 5px 20px;
    text-align: justify;
    font-family: var(--font-monospace);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-bottom: 1px solid var(--background-modifier-border);
}

/* formats the row of tags */

.propertyitemtags {
    margin:10px;
    font-size: var(--font-smaller);
}

/* formats each tag */

.propertyitemtags a.tag {
	background-color: var(--tag-background);
	border: var(--tag-border-width) solid var(--tag-border-color);
	border-radius: var(--tag-radius);
	color: var(--tag-color);
	font-size: var(--tag-size);
	font-weight: var(--tag-weight);
	text-decoration: var(--tag-decoration);
	padding: var(--tag-padding-y) var(--tag-padding-x);
	line-height: 1;
}

/* formats the row of aliases*/

.propertyitemaliases {
    margin:10px; 
    font-size: var(--font-smaller); 
    text-align: center;    
    cursor: default;
}

/*formats each alias */

.propertyitemaliases a.alias {
	background-color: var(--tag-background);
	border: var(--tag-border-width) solid var(--tag-border-color);
	border-radius: var(--tag-radius);
	color: var(--tag-color);
	font-size: var(--tag-size);
	font-weight: var(--tag-weight);
	text-decoration: var(--tag-decoration);
	padding: var(--tag-padding-y) var(--tag-padding-x);
	line-height: 1;
}
2 Likes

For some reason, I’m getting tons of errors on my site README - Cybersader Wiki - it doesn’t even seem to know what the “map” function is. Confused about what’s going on when I try to use it.

this is a big setback to my trial month of publish :frowning: I see many small and average half-baked features, which one does not expect after paying 10$.
My idea of using publish was that it would allow me to publish without changing my workflow at all. As I see it now, I need to re-adjust and put all the links in the post body instead of properties…
I think I will return to quartz, because it is practically the same, but free.

+1, I’d really like to see this feature.

+1 This would really help clean up the published version and align workflows with the desktop.

+1!

I tried out @elkadre’s solution and it worked except I got the same error as you on some of my note pages. Turns out if your note only has one tag, then the tags variable is a string and not an array, hence why map() breaks. I fixed it by adding this:

let tags = frontmatter['tags'] || [];
const aliases = frontmatter['aliases'] || [];

if (typeof tags === 'string') {
	tags = [tags];
}

/* maps out and formats the tags */

Which creates a single length array in the case that you only have one tag.


Also, +1 for this feature please!