What I’m Trying to do:
I already have a CSS snippet that hides “tags”. This CSS is toggled via an entry hide-tags in cssclasses in the YAML frontmatter.
Now I’m trying to achieve the same thing for hiding contexts in tasks. My tasks look like this, sometimes with an appended @Context (which I would like to be able to hide):
- [ ] Task @Context
I’ve spent the entire weekend trying to get this working with the help of ChatGPT (and other AI systems). What I have so far works to some extent, but I would like the @Context to be hidden by default when opening a note, which I haven’t been able to achieve yet.
With my current setup (see below), this does not work properly. Although the YAML entry hideTaskContexts is already set to true when the note is opened, the setting only takes effect after pressing the button twice (first “Show Context”, then “Hide Context” again).
What I Would Like to Achieve:
- A reasonably simple solution (what I currently have feels rather complicated)
- Ideally, toggling should be controlled via an entry in cssclasses that enables or disables a CSS snippet
- @Context should be hidden by default when a note is opened
- Solution should work for all contexts beginning with @, not just @Context
What I Currently Have:
CSS
.hide-task-contexts .task-context.obsidian-context {
display: none !important;
}
meta-bind-js-view
{hideTaskContexts} as hide
const contexts = document.querySelectorAll(
".task-context"
);
contexts.forEach(context => {
context.classList.toggle(
"obsidian-context",
context.textContent.trim() === "
"
);
});
const preview = document.querySelector(
".markdown-preview-view"
);
if (preview) {
preview.classList.toggle(
"hide-task-contexts",
context.bound.hide === true
);
}
return "";
meta-bind-button to toggle
style: default
label: "Contexts ausblenden"
class: "task-context-toggle"
actions:
type: inlineJS
code: |
const file = app.workspace.getActiveFile();
if (!file) return;
const current = app.metadataCache.getFileCache(file)?.frontmatter?.hideTaskContexts ?? false;
const newValue = !current;
await app.fileManager.processFrontMatter(file, frontmatter => {
frontmatter.hideTaskContexts = newValue;
});
const button = document.querySelector(".task-context-toggle button");
if (button) {
button.textContent = newValue
? "Contexts anzeigen"
: "Contexts ausblenden";
}
document.body.classList.toggle(
"hide-task-contexts",
newValue
);
// Tasks neu verarbeiten
document.querySelectorAll(
".markdown-preview-view .task-list-item"
).forEach(task => {
task.querySelectorAll(".task-context").forEach(el => {
el.replaceWith(
document.createTextNode(el.textContent)
);
});
});
document.querySelectorAll(
".markdown-preview-view .task-list-item"
).forEach(task => {
const walker = document.createTreeWalker(
task,
NodeFilter.SHOW_TEXT
);
const nodes = [];
let node;
while (node = walker.nextNode()) {
if (
!node.parentElement?.classList.contains(
"task-context"
) &&
/@[A-Za-zÄÖÜäöüß0-9_-]+/.test(node.nodeValue)
) {
nodes.push(node);
}
}
nodes.forEach(textNode => {
const parts = textNode.nodeValue.split(
/(\s+@[A-Za-zÄÖÜäöüß0-9_-]+)/g
);
if (parts.length <= 1) return;
const fragment =
document.createDocumentFragment();
parts.forEach(part => {
if (
/^\s+@[A-Za-zÄÖÜäöüß0-9_-]+$/.test(part)
) {
const span =
document.createElement("span");
span.className = "task-context";
span.textContent = part;
fragment.appendChild(span);
} else {
fragment.appendChild(
document.createTextNode(part)
);
}
});
textNode.parentNode.replaceChild(
fragment,
textNode
);
});
});
Any help, ideas, or suggestions would be very welcome. Thanks in advance!
