Skip to content

Instantly share code, notes, and snippets.

@dannberg
Last active December 3, 2024 18:37
Show Gist options
  • Save dannberg/48ea2ba3fc0abdf3f219c6ad8bc78eb6 to your computer and use it in GitHub Desktop.
Save dannberg/48ea2ba3fc0abdf3f219c6ad8bc78eb6 to your computer and use it in GitHub Desktop.
Dann Berg's Daily Note Template for Obsidian. Uses Dataview & Templater plugins. Should be saved as a Markdown file in Obsidian. Read the full tour: https://dannb.org/blog/2022/obsidian-daily-note-template/
---
created: <% tp.file.creation_date() %>
---
tags:: [[+Daily Notes]]
# <% moment(tp.file.title,'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %>
<< [[Timestamps/<% tp.date.now("YYYY", -1) %>/<% tp.date.now("MM-MMMM", -1) %>/<% tp.date.now("YYYY-MM-DD-dddd", -1) %>|Yesterday]] | [[Timestamps/<% tp.date.now("YYYY", 1) %>/<% tp.date.now("MM-MMMM", 1) %>/<% tp.date.now("YYYY-MM-DD-dddd", 1) %>|Tomorrow]] >>
---
### 📅 Daily Questions
##### 🌜 Last night, after work, I...
-
##### 🙌 One thing I'm excited about right now is...
-
##### 🚀 One+ thing I plan to accomplish today is...
- [ ]
##### 👎 One thing I'm struggling with today is...
-
---
# 📝 Notes
- <% tp.file.cursor() %>
---
### Notes created today
```dataview
List FROM "" WHERE file.cday = date("<%tp.date.now("YYYY-MM-DD")%>") SORT file.ctime asc
```
### Notes last touched today
```dataview
List FROM "" WHERE file.mday = date("<%tp.date.now("YYYY-MM-DD")%>") SORT file.mtime asc
```
@geek-andi
Copy link

This is the first time I am playing with this, but I think if you add a "+" after the % like this:

# <%+ moment(tp.file.title,'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %>

To resolve the syntax on note creation, you need to enable the Templater setting "Trigger Templater on new file creation". IMHO no need for a dynamic command there, as linked later: https://github.com/SilentVoid13/Templater/blob/master/docs/src/commands/dynamic-command.md

@dannberg This would be a usefull info in your blog post (or as comment in the template, if that's possible)

@dannberg
Copy link
Author

@geek-andi Good call. Just added this additional information to the Setting up your Daily Note template section at the bottom of the blog post. Also linked back to this comment section in case anyone wants to read more.

@AsheeshSrivastava
Copy link

Just noticing that the section for "Notes created today" uses the current date, so if you create a note for a day in the future or past, it won't give the correct info. I sometimes create future or past notes for upcoming info or if I missed a day. Is there an easy way to update this?

If you use the date as the title for the Daily Note, you can use dataviewjs to get the date from the title and then use it for code forNotes created today. I am sharing my code. my Daily note title is in Do MMM Y format so you need to customise for your own format.

function parseCustomDate(dateStr) {
    const dateRegex = /(\d+)(st|nd|rd|th) (\w+) (\d{4})/;
    const match = dateStr.match(dateRegex);
    if (!match) return null;

    const [ , dayPart, , month, year] = match;
    const day = parseInt(dayPart.match(/\d+/)[0], 10); // Extract just the numeric part of the day
    const months = {
        "Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5,
        "Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11
    };
    const monthIndex = months[month];
    return new Date(year, monthIndex, day);
}

function formatDateISO(date) {
    const pad = (number) => number.toString().padStart(2, '0');
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
}

function ensureArray(value) {
    if (Array.isArray(value)) return value;
    return value ? [value] : [];
}

const currentNoteTitle = dv.current().file.name;
const targetDate = parseCustomDate(currentNoteTitle);

if (targetDate) {
    const formattedTargetDate = formatDateISO(targetDate);
    const pages = dv.pages()
        .where(p => p.file.ctime || p.file.mtime)
        .filter(p => {
            const creationDate = formatDateISO(new Date(p.file.ctime));
            const modifiedDate = formatDateISO(new Date(p.file.mtime));
            return creationDate === formattedTargetDate || modifiedDate === formattedTargetDate;
        });

    if (pages.length) {
        // Start the table.
        dv.table(["File", "Folder", "Tags", "Status"],
            pages.map(page => {
                return [
                    // Link to the file.
                    `[[${page.file.path}]]`,
                    // Folder of the file.
                    page.file.folder,
                    // Tags of the file, making sure to handle the case where tags may not be an array.
                    ensureArray(page.tags).join(", "),
                    // Status of the file.
                    page.status || ''
                ];
            })
        );
    } else {
        dv.paragraph(`No notes were found created or modified on ${formattedTargetDate}.`);
    }
} else {
    dv.paragraph("The current note's title does not contain a valid date.");
}

@adall
Copy link

adall commented Dec 8, 2023

Thanks for sharing this @dannberg - much appreciated. I'm enjoying experimenting with it. Heads up there could be a typo in one of the Daily Questions headings. I changed one of them from:

One thing I've excited about right now is...

To this:

One thing I'm excited about right now is...

@dannberg
Copy link
Author

dannberg commented Dec 8, 2023

@adall ah, good catch. I fixed that a while back in my personal library, but hadn't corrected the gist. Just made the update. Thanks!

@Robiton
Copy link

Robiton commented Jan 14, 2024

I have two concerns, figuring I am missing something on the one.

image

When I click yesterday, it makes a new note, but in a folder up. It also does not apply the template other than the name.
image

Clicking new daily note does work for today of course.

@faying93
Copy link

For folks who have a daily note with a non date name, or in a non US format, rather then using: # <% moment(tp.file.title,'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %> Which uses the file title for date formatting you can use: moment(tp.file.creation_date(),'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %> This allows you to name your Daily Notes in anyway you see fit (In my case I use a different date format with some extra characters), instead it takes the date the file created instead.

Which means now my daily notes are not from # Wednesday, January 20, 2021 😆

Hey, I use the format you meantioned which is instead of file title I use the 'file creation date' , but when I click on 'tomorrow' or 'yesterday, I am navigated to a page titled invalid date. Can you help? I understand I need to make changes in the template formula, but I am not sure how. Thank you

@gd03champ
Copy link

gd03champ commented Jan 28, 2024

Heya people 👋

I've made some changes in the template that solves most of the problem and so just sharing here

https://gist.github.com/gd03champ/6c8fe7739161c731859298b1bc96cfa0

  • Notes created and Notes last touched always shows todays data weather you are on today's note or some other day's note
  • Yesterday and tomorrow backlink doesn't create new note in organized sub directory

Have a great day !

@Robiton
Copy link

Robiton commented Feb 21, 2024

Figured out the issue with the template not applying to new notes. Though now I get a second note if I use the yesterday button.

Here is the code I am using. Just not seeing the issue.


created: <% tp.file.creation_date() %>

tags:: [[+Daily Notes]]

<% moment(tp.file.title,'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %>

<< [[Daily Notes/<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').subtract(1, 'd').format("/YYYY/MM-MMMM/YYYY-MM-DD-dddd") %>|Yesterday]] | [[Daily Notes/<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').add(1, 'd').format("/YYYY/MM-MMMM/YYYY-MM-DD-dddd") %>|Tomorrow]] >>

I did have to add this to templater,
image

Thoughts?
Thanks in advance

@Gryn23
Copy link

Gryn23 commented Feb 28, 2024

For everyone who has trouble because clicking the yesterday and tomorrow links will render empty files with just a title:
There's a small omission in the blog post. You need to go to settings > Templater > scroll down to Folder templates.

  1. Check "Enable folder templates" on
  2. Add New:
    Here you set the folder to "Timestamps" and Template to "Extra/Templates/Template, Daily Note.md"

Done! Now when you click tomorrow or yesterday, a new note will be made if it isn't there already, containing your template.

(haha, I'm a bit proud of myself for finding out, as this is the third day I use any PKM app in my life, and the first day I discovered templates!)

PS: also please use @szhydkov's useful correction of the folder structure above, so your new files are put in the right folder automatically.
Thanks for the script @dannberg. Could you please update it with the above?

@Robiton
Copy link

Robiton commented Feb 28, 2024

For everyone who has trouble because clicking the yesterday and tomorrow links will render empty files with just a title: There's a small omission in the blog post. You need to go to settings > Templater > scroll down to Folder templates.

1. Check "Enable folder templates" on

2. Add New:
   Here you set the folder to "Timestamps" and Template to "Extra/Templates/Template, Daily Note.md"

Done! Now when you click tomorrow or yesterday, a new note will be made if it isn't there already, containing your template.

(haha, I'm a bit proud of myself for finding out, as this is the third day I use any PKM app in my life, and the first day I discovered templates!)

PS: also please use @szhydkov's useful correction of the folder structure above, so your new files are put in the right folder automatically. Thanks for the script @dannberg. Could you please update it with the above?

When you do this, if you are on today and click to go back to yesterday, does it make a duplicate with a number like this?
image

That is the issue I noticed after adding the templater setup

@Gryn23
Copy link

Gryn23 commented Feb 28, 2024

No, it doesn't. If the file already exists, it just goes to that file. If the file doesn't exist yet, it's created.

@Robiton
Copy link

Robiton commented Feb 28, 2024

No, it doesn't. If the file already exists, it just goes to that file. If the file doesn't exist yet, it's created.

Hrm, how does the code I have compare to yours?

@dannberg
Copy link
Author

dannberg commented Feb 29, 2024

@Robiton @Gryn23 I'm having the same problem at @Gryn23.

I updated the "tomorrow" link Templater code to [[Timestamps/<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').add(1, 'd').format('YYYY-MM-DD-dddd') %>|Tomorrow]]. Then, I modified Templater settings so that all new files created in the Timestamps directory would have the Daily Note template applied automatically.

It works great when clicking that link to create a new note.

However, if a note currently exists (such as the Yesterday link), it does not recognize the note. Because the Timestamps/ in the [[]] link helps for creating a new note, but isn't necessary when linking to an existing note.

@Robiton if you have a solution for this, let me know. I was in the process of updating the original post but couldn't get it working myself.

@dannberg
Copy link
Author

@Robiton @Gryn23 Scratch that. I got it working. It doesn't really handle leap day correctly (of course I'm playing with it on 2/29 lol) but it should work every other day. I've updated the gist with the working code.

@Gryn23
Copy link

Gryn23 commented Mar 2, 2024

Nice!

Strange that leap day gave a problem with you, it didn't give problems with me.

This is my slightly altered version of your script, but I don't think there are big differences. Main difference is that I use it for daily to do lists, and I wanted the notes as a possibility, but out of the way to keep distractions at bay. Hence the many <br> lines. Also the date format is changed to Dutch order:

`tags: #task #todo

<% moment(tp.file.title, 'YYYY-MM-DD').format("dddd, DD MMMM, YYYY") %>

<< [[<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').subtract(1, 'd').format('[To_do]/YYYY/MM-MMMM/YYYY-MM-DD-dddd') %>|Yesterday]] | [[<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').add(1, 'd').format('[To_do]/YYYY/MM-MMMM/YYYY-MM-DD-dddd') %>|Tomorrow]] >>

---

#### To Do

- [ ] 

<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>

---
#### Notes

---
#### Notes created today

List FROM "" WHERE file.cday = date("<%tp.date.now("YYYY-MM-DD")%>") SORT file.ctime asc

#### Notes last touched today

List FROM "" WHERE file.mday = date("<%tp.date.now("YYYY-MM-DD")%>") SORT file.mtime asc

@Robiton
Copy link

Robiton commented Mar 2, 2024

@Robiton @Gryn23 Scratch that. I got it working. It doesn't really handle leap day correctly (of course I'm playing with it on 2/29 lol) but it should work every other day. I've updated the gist with the working code.

Sadly, updated code still creates a -1 if there is already a note for that day.

Anyone have any other ideas?

@dannberg
Copy link
Author

dannberg commented Mar 3, 2024

Hm, I'm at a loss.

The challenge is that the Daily Note template uses today (file.cday) as a base for all the Templater code. Which means if you click on "Tomorrow" in today's daily note to create tomorrow's note, then Tomorrow's note will have broken yesterday/tomorrow links as well as the two dataview tables.

I don't believe there's a way to pass through information through a link. Meaning, if you click on Tomorrow, you can tell the new note that you actually want file.cdate + 1 for all the Templater code.

Maybe there's a way to store the date we want as a variable in the note? Although I'm totally blanking on how to actually execute this.

@Gryn23
Copy link

Gryn23 commented Mar 6, 2024

@Robiton @dannberg I have no idea why it's not working with you guys, it is with me. If the note already exists, the tomorrow link will just open that file in my vault. Here's my latetst code. The code I posted before was already working, but since then I installed:

  1. Update time on edit
  2. Calender
  3. Periodic notes

explanation:

  1. plugin 1 makes sure that the date created and date modified are written into the properties of the file, and not overwritten when you migrate to a new computer, or sync to another device.
  2. plugin 2 speaks for itself. It will ask you if you want to migrate daily notes to it: do so.
  3. plugin 3 allows me to make a weekly note as well. You need to enter the settings and point the plugin to where your daily notes folder and your week folder lives, and where the templates for the two live.
  4. After that you need to do that again in Templater (!)
    afbeelding

This is the most important code of my daily note template:

`##### <% moment(tp.file.title, 'YYYY-MM-DD-DDDD').format("dddd, DD MMMM YYYY") %>

<< [[<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').subtract(1, 'd').format('[To_do/Dag]/YYYY/MM-MMMM/YYYY-MM-DD-dddd') %>|Yesterday]] | [[<% fileDate = moment(tp.file.title, 'YYYY-MM-DD-dddd').add(1, 'd').format('[To_do/Dag]/YYYY/MM-MMMM/YYYY-MM-DD-dddd') %>|Tomorrow]] >>`

@Gryn23
Copy link

Gryn23 commented Mar 6, 2024

This is the template for my weekly note. Of course you need to change the names of the folder, and translate "Volgende week" with 'next week'.

`##### <% moment(tp.file.title, 'YYYY-[W]-WW').format("[Week] ww - DD MMMM YYYY") %>

<< [[<% fileDate = moment(tp.file.title, 'YYYY-[W]-WW').subtract(1, 'w').format('[To_do/Week]/YYYY/MM-MMMM/YYYY-[W]-WW') %>|Vorige week]] | [[<% fileDate = moment(tp.file.title, 'YYYY-[W]-WW').add(1, 'w').format('[To_do/Week]/YYYY/MM-MMMM/YYYY-[W]-WW') %>|Volgende week]] >>`

@Gryn23
Copy link

Gryn23 commented Mar 6, 2024

My properties are in the template too. I've hidden properties after I made sure they work. Unhidden this is what shows in the template:

afbeelding

And this is what's spit out if I make a weekly note, (but only if you do so in the right folder! Select the right folder, click right and choose new note, or click "volgende week" on an existing note. Making weeknumbers visible in Calender and clicking an empty weeknumber (or day) works as well.) As you see the "Update time on edit" plugin automatically added date properties.

afbeelding

@pantsmasterson
Copy link

Am I the only person for whom this code just stays as pasted-in code when I start a new daily note?

Notes
<% tp.file.cursor() %>

It just stays in the note, like so:

image

@Gryn23
Copy link

Gryn23 commented Mar 21, 2024

@pantsmasterson you need to get rid of the quotation mark (') before and after the code. Or maybe you didn't install the templater plugin?

@pantsmasterson
Copy link

pantsmasterson commented Mar 21, 2024

I put the ticks in the comment so they'd appear as code in the Github comment -- they don't appear in the template itself. In the template, it is exactly as it appears in the screenshot, and renders as that piece of code rather than the cursor at that position (which I assume is what's supposed to happen). In the templater code, I've cut and pasted exactly what appears above. The Templater plugin is installed and active.

@Gryn23
Copy link

Gryn23 commented Mar 21, 2024

  • Did you tick "automatic jump to cursor" in Templator's options?
  • And maybe a stupid question, but you pasted '<% tp.file.cursor() %>' in your template, right? It's supposed to stay code in your template, and only when you 'create new note form template' it should give you a note without the code and just the cursor below your Notes heading.

@pantsmasterson
Copy link

Aha! It was automatic jump to cursor! Thank you so much -- I'd never have puzzled that through solo.

@Gryn23
Copy link

Gryn23 commented Mar 21, 2024

Haha, glad to help, I'm a beginner myself.

@dannberg
Copy link
Author

You're not the first person with a question about <% tp.file.cursor() %>. I should be explicit about this being a setting that needs to be enabled in the post. Will update!

@re3factor
Copy link

re3factor commented Mar 21, 2024

Anyone with a tip to stop odd formatting issue when trying to put in a block of code? Whenever I put in the code formatting ticks it opens code for everything below it, even after putting in the code in question and closing the formatting correctly?

image

@sprachlust
Copy link

First of all, thanks to @dannberg for laying all this out in your blog post! I've followed along to create my own dailynote setup.
For some reason, your "notes created today" and "notes last touched" dataview snippets wouldn't render at all once the daily note got created, so I did some googling and found this. I've modified the dataview snippet like below and now it's rendering perfectly!

For anyone who's having issues, try out this code instead!

List FROM "" WHERE file.cday = date("<% tp.date.now() %>") SORT file.ctime asc
List FROM "" WHERE file.mday = date("<% tp.date.now() %>") SORT file.mtime asc

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