# Daily Note Template
A dated note that files itself under Daily Notes/Year/Month and shows a live task dashboard. Save the code below as `Daily Note.md` in your vault's `Templates/` folder.
````md
<%*
const today = tp.date.now("YYYY-MM-DD");
const year = tp.date.now("YYYY");
const month = tp.date.now("MMMM");
const folderPath = `Daily Notes/${year}/${month}`;
// Ensure each level of the folder hierarchy exists
const segments = folderPath.split("/");
let cur = "";
for (const seg of segments) {
cur = cur ? `${cur}/${seg}` : seg;
if (!app.vault.getAbstractFileByPath(cur)) {
await app.vault.createFolder(cur);
}
}
const expected = `${folderPath}/${today}.md`;
if (tp.file.path(true) !== expected) {
await tp.file.move(`${folderPath}/${today}`);
}
_%>
# <% tp.date.now("dddd, MMMM D, YYYY") %>
## Notes
```dataviewjs
// ===== Date math =====
const today = new Date();
today.setHours(0, 0, 0, 0);
const localISO = (d) =>
`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
const todayStr = localISO(today);
// End of this week = upcoming Sunday (or today if today is Sunday).
const dow = today.getDay(); // 0=Sun, 6=Sat
const daysToSunday = (7 - dow) % 7;
const endOfWeek = new Date(today);
endOfWeek.setDate(today.getDate() + daysToSunday);
const endOfWeekStr = localISO(endOfWeek);
const sevenDaysAgo = new Date(today);
sevenDaysAgo.setDate(today.getDate() - 7);
const sevenDaysAgoStr = localISO(sevenDaysAgo);
// ===== Helpers =====
const dueISO = (p) => {
const d = p.due;
if (!d) return null;
if (d.toISODate) return d.toISODate();
if (typeof d === "string") return d.slice(0, 10);
return null;
};
const closedISO = (p) => {
const d = p.closed;
if (!d) return null;
if (d.toISODate) return d.toISODate();
if (typeof d === "string") return d.slice(0, 10);
return null;
};
const linksOf = (p) => {
const out = [];
for (const k of ["people", "projects", "classes", "assignments"]) {
const v = p[k];
if (!v) continue;
const arr = Array.isArray(v) ? v : [v];
for (const l of arr) if (l && l.path) out.push(l);
}
return out;
};
const closeTask = (p) => async () => {
const file = app.vault.getAbstractFileByPath(p.file.path);
if (!file) return;
const content = await app.vault.read(file);
const stamp = localISO(new Date());
let updated = content.replace(/^status:\s*["']?open["']?\s*$/m, "status: done");
if (/^closed:/m.test(updated)) {
updated = updated.replace(/^closed:.*$/m, `closed: ${stamp}`);
} else {
updated = updated.replace(/^(---\n[\s\S]*?\n)---\n/, `$1closed: ${stamp}\n---\n`);
}
if (updated !== content) await app.vault.modify(file, updated);
};
const reopenTask = (p) => async () => {
const file = app.vault.getAbstractFileByPath(p.file.path);
if (!file) return;
const content = await app.vault.read(file);
let updated = content.replace(/^status:\s*["']?done["']?\s*$/m, "status: open");
updated = updated.replace(/^closed:.*$/m, "closed: ");
if (updated !== content) await app.vault.modify(file, updated);
};
const openRow = (p) => {
const cb = document.createElement("input");
cb.type = "checkbox";
cb.addEventListener("click", closeTask(p));
return [cb, p.file.link, p.due, linksOf(p)];
};
const closedRow = (p) => {
const cb = document.createElement("input");
cb.type = "checkbox";
cb.checked = true;
cb.addEventListener("click", reopenTask(p));
return [cb, p.file.link, p.closed, linksOf(p)];
};
const renderSection = (title, items, headers, rowFn) => {
dv.header(2, title);
const arr = [...items];
if (arr.length === 0) {
dv.paragraph("_None._");
} else {
dv.table(headers, arr.map(rowFn));
}
};
// ===== Source data =====
const open = dv.pages('"Activities/Tasks"').where(p => p.status === "open");
const closed = dv.pages('"Activities/Tasks"').where(p => p.status === "done");
// ===== Sections =====
renderSection(
"Overdue",
open.where(p => { const d = dueISO(p); return d && d < todayStr; }).sort(p => p.due, "asc"),
["Done", "Task", "Due", "Links"],
openRow
);
renderSection(
"Due today",
open.where(p => dueISO(p) === todayStr).sort(p => p.due, "asc"),
["Done", "Task", "Due", "Links"],
openRow
);
renderSection(
"Due this week",
open.where(p => { const d = dueISO(p); return d && d > todayStr && d <= endOfWeekStr; }).sort(p => p.due, "asc"),
["Done", "Task", "Due", "Links"],
openRow
);
renderSection(
"Future",
open.where(p => { const d = dueISO(p); return d && d > endOfWeekStr; }).sort(p => p.due, "asc"),
["Done", "Task", "Due", "Links"],
openRow
);
renderSection(
"Recently closed",
closed.where(p => { const d = closedISO(p); return d && d >= sevenDaysAgoStr && d <= todayStr; }).sort(p => p.closed, "desc"),
["Reopen", "Task", "Closed", "Links"],
closedRow
);
```
````