Need help using templater formulas for periodic notes querying habits

What I’m trying to do

Hi everyone. I just went full Obsidian after spending a year using it alongside Todoist (Tasks), Daylio (Journal) and Loop Habits (Habits).

So I’m using a combinaison of Tasks, Calendar, Periodic Notes, Templater and Dataview to create myself Daily, Weekly, Monthly, Quarterly and Yearly notes.

I thought about using Archiver as well but it seems like Tasks is doing a great job at queriying done tasks, so I’m not using it. But I’m having issue using Templater instead of relying on relative date from Task plugin.

I’m done with my Daily Note template that I show at the end of my post.

I used the relative date using “today” in my task queries, but changed because if I was on another Daily Note, let’s say yesterday, it wasn’t showing yesterday done note, but today’s one.

So I went from :

done on today

To :

done on <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>

My issue is that while obsidian tasks understand my standard week number for querying notes done during this week, I don’t know how to querry my habits done during the week given the week number.

Here are my periodic notes formats :

  • Daily : YYYY-MM-DD
  • Weekly : gggg-[W]ww
  • Monthly : YYYY-MM
  • Quarterly : YYYY-[Q]Q
  • Yearly : YYYY

Thanks in advance !

Things I have tried

I tried using different combinaison of ``this.file.day.weekyear` but the querry doesn’t give me anything.

My Daily Note template


title: ‘<% moment(tp.file.title, “YYYY-MM-DD”).format(“YYYY-MM-DD”) %>’
date created:
date modified:
tags: daily-notes
aliases:
source:
type:
author:
date:

<% moment(tp.file.title, “YYYY-MM-DD”).format(“YYYY-MM-DD”) %>

<%*
const currentMoment = moment(tp.file.title, “YYYY-MM-DD”);
const hash = '# ';
const slash = ’ / ';
const pipe = ’ | ‘;
const leftAngle = ‘❮ ‘;
const rightAngle = ’ ❯’;
tR += leftAngle;
tR += ‘[[’ + currentMoment.format(‘YYYY’) + ‘]]’ + slash;
tR += ‘[[’ + currentMoment.format(‘YYYY-[Q]Q|[Q]Q’) + ‘]]’ + slash;
tR += ‘[[’ + currentMoment.format(‘YYYY-MM|MMMM’) + ‘]]’ + slash;
tR += ‘[[’ + currentMoment.format(‘gggg-[W]ww’) + ‘|’ + currentMoment.format(’[Week] ww’) + ‘]]’;
tR += rightAngle;
tR += ‘\n’;
tR += ‘\n’;
tR += leftAngle;
currentMoment.add(-1,‘days’);
tR += ‘[[’ + currentMoment.format(‘YYYY-MM-DD’) + ‘]]’ + pipe;
currentMoment.add(1,‘days’);
tR += currentMoment.format(‘YYYY-MM-DD’) + pipe;
currentMoment.add(1,‘days’);
tR += ‘[[’ + currentMoment.format(‘YYYY-MM-DD’) + ‘]]’;
currentMoment.add(-1,‘days’);
tR += rightAngle;
%>

[!Quote]+ Quote of the Day
<% tp.web.daily_quote() %>

Brain Dump - Today Notes

Overdue

not done
due before <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>

Do Today

not done
due <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>

Upcoming

not done
due after <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>
due before <% moment(tp.file.title, "YYYY-MM-DD").add(10,'days').format("YYYY-MM-DD") %>
short mode
hide edit button
hide backlink

Next Actions

not done
(created before <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>) OR (created on <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>)
tags include #next

Waiting For

not done
(created before <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>) OR (created on <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>)
tags include #waiting
short mode

Delegated

not done
(created before <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>) OR (created on <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>)
tags include #delegated
short mode

Task Log

done on <% moment(tp.file.title, "YYYY-MM-DD").format("YYYY-MM-DD") %>

Habits

Morning water::
Mobility::
Meditation::
Stretching::

Journal

My Weekly note template


title: ‘<% moment(tp.file.title, “gggg-[W]ww”).format(“gggg-[W]ww”) %>’
date created:
date modified:
tags: weekly-notes
aliases:
source:
type:
author:
date:

<% moment(tp.file.title, “gggg-[W]ww”).format(“gggg-[W]ww”) %>

Task Log

done in <% moment(tp.file.title, "gggg-[W]ww").format("gggg-[W]ww") %>

Habits

TABLE WITHOUT ID
  file.link as Date,
  choice("Morning water"=1,"✅","❌") as "Morning Water",
  choice("Mobility"=1,"✅","❌") as "Mobility",
  choice("Meditation"=1,"✅","❌") as "Meditation",
  choice("Stretching"=1,"✅","❌") as "Stretching"
FROM "-Daily-Notes"
WHERE file.day.weekyear = "<% moment(tp.file.title, "gggg-[W]ww").format("gggg-[W]ww") %>"
SORT file.day ASC

Nice templates! Looks like we have a lot of similarities in how we use our vaults, a lot of my templates look similar.

I haven’t used Templater much, so I’m not sure how you would go about doing this with that plugin. However, I do use Dataview extensively, and I’ve solved this for myself using DataviewJS. Since Templater also uses JS, I imagine you could adapt this pretty easily to work with it, or since you have Dataview you could use the script as-is.

Here’s how I query my daily habits in my weekly note:

```dataviewjs
var startOfWeek = '2023-01-01';
var nextWeek = moment(startOfWeek).add(7, 'days');
var dateformat = "YY-MM-DD";
var journals = dv.pages('"2 Areas/Journal/Daily Notes/2023"');

function getWeeklyJournals(today) {
	return journals
		.where(f => {
			if (!f.file.name) return false;
			var pastDate = moment(startOfWeek).subtract(1, "days");
			var docDate = moment(f.file.name, dateformat);
			return docDate.isBetween(pastDate, nextWeek);
		});
}

function formatHabit(habit) {
	return (habit) ? '✅' : '❌';
}

// creating the table
var weeklyNotes = getWeeklyJournals(startOfWeek);

dv.table(['Date', 'Workout', 'Pray'], weeklyNotes
	.sort(f => f.date)
	.map(b => [b.file.name, formatHabit(b.workout), formatHabit(b.pray)])
);

I use the built-in template plugin to autofill the date for the week, so in my weekly template note the initial variable looks like this:

var startOfWeek = '{{date:YYYY-MM-DD}}';

This script takes the above date and finds all Daily Notes that exist for that week, pulls the habits out of them, and spits them out in a table. The generated table looks something like this:

It’ll need to be tweaked for your use-case, you’ll likely have to change the dateformat and journals variables, and you’ll have to customize the table to include your own habits. But hopefully that gives you an idea of one way to do this.

Based on the info you provided, this should be reasonably close to the script you need:

```dataviewjs
var startOfWeek = '<% tp.date.now("YYYY-MM-DD") %>';
var nextWeek = moment(startOfWeek).add(7, 'days');
var dateformat = "YYYY-MM-DD";
var journals = dv.pages('"-Daily-Notes"');

function getWeeklyJournals(today) {
	return journals
		.where(f => {
			if (!f.file.name) return false;
			var pastDate = moment(startOfWeek).subtract(1, "days");
			var docDate = moment(f.file.name, dateformat);
			return docDate.isBetween(pastDate, nextWeek);
		});
}

function formatHabit(habit) {
	return (habit) ? '✅' : '❌';
}

// creating the table
var weeklyNotes = getWeeklyJournals(startOfWeek);

dv.table(['Date', 'Morning Water', 'Mobility', 'Meditation', 'Stretching'], weeklyNotes
	.sort(f => f.date)
	.map(b => [b.file.name, formatHabit(b['morning-water']), formatHabit(b.mobility), formatHabit(b.meditation), formatHabit(b.stretching)])
);

Untested, but it might work :slight_smile:

Hi ! Thanks for your answer.

I came across this one that work well : WHERE file.day <= date(now) AND file.day >= date(now) - dur(7days)

But it doesn’t use my weekly note title, hence it is not worth using for my weekly archives. I’ll try using yours when I’m home !

1 Like

It doesn’t work, I get the same result : “Dataview : No results to show for table query.”

I’m getting crazy, why isn’t there any easy “check if daily note title is in week number” type of filter in dataview. It sure is somewhere, but can’t find it.

Are your daily notes in a folder called “-Daily-Notes”? I assumed so from above, but with a no results error, I would suspect perhaps that path is wrong. Capitalization and punctuation have to be exact for it to find the right notes.

Yes, the folder is correct. I don’t know what’s missing there.

I’m trying something else using this code : =dateformat(date(this.file.name), "yyyy-WW")

It gets me 2023-18, and I’m looking at getting 2023-W18.

If I get that to work, I might be able to use it in my simple WHERE query.

Ah, I think we have a different setup after all. I don’t store habits inside the weekly note, only the dailies, so I don’t need to access the weekly note from the dailies. I think I misunderstood your problem.

You should be able to get “2023-W18” by escaping the W, like this: = dateformat(date(this.file.name), "yyyy-'W'WW")

I’m sorry I’m having trouble explaining myself recently due to some health issues.

I do have my habits inside my daily notes, under a ## Habit section and with the inline metadata approach Meditation::0.

However, I want to be able to see my weekly progress on habits, hence the question.

I managed to make it work with the 2023-XX format :

TABLE WITHOUT ID
  file.link as Date,
  choice("Morning water"=1,"✅","❌") as "Morning Water",
  choice("Mobility"=1,"✅","❌") as "Mobility",
  choice("Meditation"=1,"✅","❌") as "Meditation",
  choice("Stretching"=1,"✅","❌") as "Stretching"
FROM "-Daily-Notes"
WHERE dateformat(date(file.name), "yyyy-WW") = "2023-18"
SORT file.link ASC

I just need to add your escaping and I’ll be good to go !

Alright, it works with the following code :

TABLE WITHOUT ID
  file.link as Date,
  choice("Morning water"=1,"✅","❌") as "Morning Water",
  choice("Mobility"=1,"✅","❌") as "Mobility",
  choice("Meditation"=1,"✅","❌") as "Meditation",
  choice("Stretching"=1,"✅","❌") as "Stretching"
FROM "-Daily-Notes"
WHERE dateformat(date(file.name), "yyyy-'W'WW") = "<% moment(tp.file.title, "gggg-[W]ww").format("gggg-[W]ww") %>"
SORT file.link ASC

Thanks a lot for your time and help, I really appreciate. As you’ve seen, I am not ready to use Javascript yet and ended up trying a simplier, or at least using the basic of Dataview functions and attributes to gather what I wanted to see.

You really helped me sort things out, I’m really glad you were here. Thanks again and have a great day !

1 Like

Heeeey glad you got it worked out. Happy I could help!

1 Like

Edit : I used string instead of metadatas, here is the corrected version that works :

TABLE WITHOUT ID
  file.link as Date,
  choice(Morning-water=1,"✅","❌") as "Morning Water",
  choice(Mobility=1,"✅","❌") as "Mobility",
  choice(Meditation=1,"✅","❌") as "Meditation",
  choice(Stretching=1,"✅","❌") as "Stretching"
FROM "-Daily-Notes"
WHERE dateformat(date(file.name), "yyyy-'W'WW") = "<% moment(tp.file.title, "gggg-[W]ww").format("gggg-[W]ww") %>"
SORT file.link ASC

And when will "Morning" ever be like 1 ? Doesn’t this always show X’s in your table?

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.