Skip to content

Instantly share code, notes, and snippets.

@Grayda
Last active December 27, 2024 04:56
Show Gist options
  • Save Grayda/fe71dfebb4d46339184ed95d7c74cfa5 to your computer and use it in GitHub Desktop.
Save Grayda/fe71dfebb4d46339184ed95d7c74cfa5 to your computer and use it in GitHub Desktop.
Infobox for Trilium Next Notes

This is an (in-progress) infobox for Trilium Next Notes.

Installation

Installing the template

  1. Create a new note somewhere (preferably under a Scripts note or something to keep everything organized)
  2. Create a new note called Infobox
  3. Create a new note under Infobox called template and make the Note Type HTML
  4. Create a new note under template and call it js and make the Note Type JS Frontend
  5. Create two new notes under js. Call the first one dayjs_plugin_relativeTime and call the second one dayjs_plugin_advancedFormat. Set both Note Types to JS Frontend
  6. Add a new Relation to the Infobox note (not the template note!). The Name will be renderNote and the Target Note will be the template you created in step 3. This tells Trilium to render the HTML, instead of just displaying the raw text

At this point, your folder structure should look like this:

Scripts or wherever you're storing this
└── Infobox (Type: Render Note)
    └── template (Type: HTML)
        └── js (Type: JS Frontend)
            ├── dayjs_plugin_relativeTime (Type: JS Frontend)
            └── dayjs_plugin_advancedFormat (Type: JS Frontend)
  1. Copy and paste the code from template.html in this gist into the template note you created in step 3
  2. Copy and paste the code from js.js in this gist into the js note you created in step 4
  3. Copy and paste the code from this file into the dayjs_plugin_advancedFormat note you made in step 5
  4. Copy and paste the code from this file into the dayjs_plugin_relativeTime note you made in step 5

Now you have all the files you need to get started.

Setting up your notes

This relies on three labels, DateOfBirth, DateOfDeath and Address. It's best to add them to a template note so you don't have to recreate them every time. My label code looks like this:

#label:DateOfBirth(inheritable)="promoted,alias=Date of Birth,single,date" #label:DateOfDeath(inheritable)="promoted,alias=Date of Death,single,date" #label:Address(inheritable)="promoted,alias=Address,single,text"

Adding the Infobox to the notes

  1. Go to the note you want to add this to or create a new note with those three labels
  2. Use the Include Note button in the toolbar and add your Infobox note: image image

Caveats

This is a work in progress. It may throw up errors or not work entirely. It currently doesn't work with multi-value labels, and there may be much better ways to accomplish this, but it works for my needs.

// Import day.js extra plugins for working with relative dates and ordinal numbers
var dayjs_plugin_relativeTime = require("dayjs_plugin_relativeTime")
var dayjs_plugin_advancedFormat = require("dayjs_plugin_advancedFormat")
dayjs.extend(dayjs_plugin_relativeTime)
dayjs.extend(dayjs_plugin_advancedFormat)
// Now we get the "parent" note (i.e. the note that this will be embedded into)
// I think this is kind of hacky, as I think by default a note doesn't know what it's being embedded into
const note = await api.getActiveContextNote()
// Now we deconstruct / set up properties we need to work with
var [
titleElement,
dob,
dobElement,
dod,
dodElement,
address,
addressElement,
related,
relatedElement
] = [
document.getElementById("note_title"),
await note.getLabelValue("DateOfBirth"),
document.getElementById("note_dob"),
await note.getLabelValue("DateOfDeath"),
document.getElementById("note_dod"),
await note.getLabelValue("Address"),
document.getElementById("note_addresses"),
await note.getRelations("Related"),
document.getElementById("note_related"),
]
// If the note_title HTML element exists,
if(titleElement) {
// Set the note title or default to "this note" if not set for some reason.
titleElement.innerHTML = note.title ?? "this note"
}
// If the note_dob HTML element exists
if(dobElement) {
// If we don't specify a date, we want to show n/a
if(dob ?? "" != "") {
var tempDob = dayjs(dob)
dob = `${tempDob.format("Do \of MMMM YYYY")} (${tempDob.fromNow()})`
} else {
dob = "n/a"
}
dobElement.innerHTML = dob
}
// if the note_dod HTML element exists
if(dodElement) {
// If the DoD is set, make it into a relative day
// If it's NOT set, we set the style to hide it. Too depressing otherwise!
if(dod ?? "" != "") {
var tempDod = dayjs(dod)
dod = `${tempDod.format("Do \of MMMM YYYY")} (${tempDod.fromNow()})`
} else {
// IF we don't have a DoD, we find the nearest TR (i.e. the row this line is on) and hide it
dodElement.closest("tr").style = "display: none;"
}
dodElement.innerHTML = dod
}
// If we've got a note_addresses HTML element
if(addressElement) {
// If we've set an address
if(address) {
// Make a brand new link tag
const linkTag = document.createElement("a")
// Set the HREF attribute, then set the text
linkTag.setAttribute("href", "https://www.google.com.au/maps/search/" + encodeURIComponent(address))
linkTag.innerHTML = address ?? "n/a"
// Append the newly created tag. We do this because (eventually) we'll support multiple addresses
addressElement.appendChild(linkTag)
}
}
<div>
<p>Info about <span id="note_title"></span></p>
<table class="table stats-table">
<tr>
<th>Date of Birth</th>
<td><span id="note_dob"></span></td>
</tr>
<tr>
<th>Date of Death</th>
<td><span id="note_dod"></span></td>
</tr>
<tr>
<th>Address</th>
<td id="note_addresses"></td>
</tr>
</table>
</div>
@TheBig-O
Copy link

This is great. The instructions work well and are pretty clear. I can think of a lot of things I would do with this capability.
If I were to suggest improvements, I can think of two. (I know you just got started on this prjoect, so those tips are intended to help, not complain. I'm really liking the work you've done on this!)
The first would be to break down years into decimals. Right now, it appears you break the year in half. Anything before July 1 adds a year (to the age), and anything after July 1 keeps things with the straight math. For example, when you ask a person born in June 2000 how old they are, you would expect them to say 24 years old. Instead, this InfoBox reports 25 years. If you adjusted this to 24.5 years, it seems like it would give a clearer and more expected result.
The second change would be to have an aggregate list of all the dates from notes associated with InfoBox. That way, you can click on a note similar to "Collection Views" and see all the birthdates and addresses in a single page.

This is great work! Thanks!!!

@Grayda
Copy link
Author

Grayda commented Dec 27, 2024

Right now, it appears you break the year in half. Anything before July 1 adds a year (to the age), and anything after July 1 keeps things with the straight math. For example, when you ask a person born in June 2000 how old they are, you would expect them to say 24 years old. Instead, this InfoBox reports 25 years

I'm using DayJS's "Relative Time" plugin and it doesn't give you any nuance because I guess they figure people don't really care too much about specifics (e.g. "Six months ago" or "1 day from now" is fine), but for dates of birth and such, I'd say it'd be nice to be accurate. I'll look and see if there's a way to get more specific with it (e.g. "24 years and 3 months") but it might involve using something other than DayJS (which is built into Trilium)

The second change would be to have an aggregate list of all the dates from notes associated with InfoBox. That way, you can click on a note similar to "Collection Views" and see all the birthdates and addresses in a single page.

I'll look into that as well. There's some scripting examples that work with Trilium's SQL to do things like find the most linked notes.

At some point I might move this to a dedicated repo so people can just import it from Trilium, no manual steps required, but I'll see how I go, as this is mostly for a personal project I've been planning for years, so it might end up just supporting features I need, but be open source so people can tweak it.

@TheBig-O
Copy link

That makes perfect sense and totally understand building tools for the things you need.
I really appreciate your sharing what you have!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment