Color a TODO, WIP, DONE prefix for every list item in the current text note. #7264
-
I'm trying to create a new frontend script, similarly to the word count example, I can add to an existing note of mine as an attribute. This script should add a new button, to the currently edited note, which once clicked, should find all the list items in the current note, find those that start with a certain prefix (TODO, WIP, DONE, WONTDO) and based on the found prefix, change the foreground color for that word. How would I go about implementing this? At the moment I can find all the list items in the currently edited note and Can I edit a note via a JS frontend script or do I have to iimplement it as a background script? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
You can edit note content from a JS frontend script in Trilium by creating a custom widget (a JS frontend note with a #widget label) that adds UI elements like buttons to the note UI. To persistently modify note content (such as coloring TODO, WIP, DONE, WONTDO prefixes in list items), fetch the note's HTML content, process it in JavaScript (e.g., use regex or DOM parsing to wrap the prefixes in a with a style), and then save the modified HTML back using note.save(). Direct DOM changes won't persist—always use the API to update note content. See the custom widget guide and discussion for more details and examples of this workflow. To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
-
For what it's worth, here's the script I ended up with. It's quite crude, since it operates on the HTML returned by /*
* Custom widget: Colors all the TODO, WIP, BLOCKED, DONE, etc. words that it finds.
* To activate, label the note (or a parent) with `todoColorizer`.
*/
const TPL = `<div style="padding: 10px; border-top: 1px solid var(--main-border-color); contain: none;">
<button class="show-lis-btn">Show List Items</button>
</div>`;
class todoColorizer extends api.NoteContextAwareWidget {
get position() { return 100; } // position in the center pane (bottom)
get parentWidget() { return 'center-pane'; }
doRender() {
this.$widget = $(TPL);
this.$button = this.$widget.find('.show-lis-btn');
this.$button.on('click', async () => {
const noteId = this.note.noteId;
await api.runOnBackend(function(frontendNoteId) {
const bNote = api.getNote(frontendNoteId);
if (!bNote) return;
let html = bNote.getContent();
if (!html) return;
// keyword → background color
const map = {
TODO: 'orange',
WIP: 'lightblue',
DONE: 'lightgreen',
WONTDO: 'lightgreen',
FAILED: 'lightcoral',
BLOCKED: 'plum'
};
for (const [keyword, color] of Object.entries(map)) {
const style = `background-color:${color}; color:black; font-weight:bold`;
const regex = new RegExp(`\\b${keyword}\\b`, 'g');
html = html.replace(regex, `<span style="${style}">${keyword}</span>`);
}
bNote.setContent(html);
}, [noteId])
})
return this.$widget;
}
async refreshWithNote(note) {
if (note.type !== "text" || !note.hasLabel("todoColorizer")) {
this.toggleInt(false);
return;
}
this.toggleInt(true);
}
async entitiesReloadedEvent({ loadResults }) {
// Refresh if note content changes
if (loadResults.isNoteContentReloaded(this.noteId)) {
this.refresh();
}
}
}
module.exports = new todoColorizer(); |
Beta Was this translation helpful? Give feedback.
For what it's worth, here's the script I ended up with. It's quite crude, since it operates on the HTML returned by
getContent
but for now it gets the job done.