Link to next/previous available weekly note (NOT current week but relative to that note)

First, search the help docs and this forum. Maybe your question has been answered! The debugging steps can help, too. Still stuck? Delete this line and proceed.

What I’m trying to do

I want to make internal links for weekly notes, not based on the current week we are in, but relative to the week number in the file, so in 2023-W23, the next week would be 2023-W24 and not 2023-W32 (I am writing this on week 31).

Things I have tried

These work for weeks adjacent to current week
$= '[['+moment().add(1, 'week').format("YYYY-[W]ww")+ ']]'
$= '[['+moment().add(-1, 'week').format("YYYY-[W]ww")+ ']]'

Other solutions here in the forum seem to be related to this solution, but what I want is different.

On my daily notes I have this (now I remember that I borrowed it from a code made by @Moonbase59), and the notes says that it works for other files having a date yaml entry, In my weekly notes I have week-n: entry, so maybe it could be adapted to that.

/*
    previous/next note by date for Daily Notes
    Also works for other files having a `date:` YAML entry.
    MCH 2021-06-14
*/
var none = '(none)';
var p = dv.pages('"' + dv.current().file.folder + '"').where(p => p.file.day).map(p => [p.file.name, p.file.day.toISODate()]).sort(p => p[1]);
var t = dv.current().file.day ? dv.current().file.day.toISODate() : luxon.DateTime.now().toISODate();
// Obsidian uses moment.js; Luxon’s format strings differ!
var format = app['internalPlugins']['plugins']['daily-notes']['instance']['options']['format'] || 'YYYY-MM-DD';
var current = '(' + moment(t).format(format) + ')';
var nav = [];
var today = p.find(p => p[1] == t);
var next = p.find(p => p[1] > t);
var prev = undefined;
p.forEach(function (p, i) {
    if (p[1] < t) {
        prev = p;
    }
});
nav.push(prev ? '[[' + prev[0] + ']]' : none);
//nav.push(today ? today[0] : none);
nav.push(today ? today[0] : current);
nav.push(next ? '[[' + next[0] + ']]' : none);

//dv.list(nav);
//dv.paragraph(nav.join(" · "));
dv.paragraph(nav[0] + ' ← ' + nav[1] + ' → ' + nav[2]);

Note: I have templater and periodic notes if that helps. Would prefer a solution that uses those instead of adding more complexity to my notes.

:triangular_flag_on_post:EDIT: Might be nice that the link looks for the first available weekly note, so there are weeks 23 and 25, if I am in week 25 it would jump to week 23 and NOT the non-existing 24.

1 Like

I’m also in the process of setting up my weekly template [without dataview] and will be following Danny Hatcher’s instructions …

Habit tracking vault build from SCRATCH
Weekly template @ 10:28

There is a link to his templates.

[[Journal/Weekly/<%moment(tp.file.title).subtract(1,‘week’).format(“gggg-[W]ww”)%>| ↶ Previous Week]] | [[Journal/Weekly/<%moment(tp.file.title).add(1,‘week’).format(“gggg-[W]ww”)%>| ↷ Next Week]]

1 Like

Yes! Thanks! That solves the basic issue! Now I will wait some more to see if anyone else can find a solution to that other issue (I do not have notes for every week so I’d like to jump to the first available one instead of going in a straight sequence) but this will do the trick so far! Thanks @ichmoimeyo ! :wink:

take a look at this dataviewjs method …

1 Like

This is looking more like it, and I stumbled this snippet before. The issue is I do not know how to retro fit it to the weekly ones, despite it is clearly stated that it is possible. My weeklies have a week-n tag in the YAML, but that is as far as I can go.

Maybe @Moonbase59 can help in this (sorry if I double tagged you!)

What is the format of your week-n tag? Is it just a number, or is the year included as well?

1 Like

Now that you mention, I should consider the year (this is the first year I am doing this). For now week-n is just a number. I think I should add another year tag, maybe? (EDIT: the year tag is already there)

Next question, what is the folder path that you store your weekly notes in? Is there a tag for the weekly notes that sets them apart from your other notes?

1 Like

weekly notes are in /journaling/weeklynotes

I do not have any weekly notes of my own set up, so I can’t 100% guarantee this works, but I think this should do it.

```dataviewjs
/*
	previous/next weekly note by date for weekly notes
	2023-08-02
	original: https://forum.obsidian.md/t/dataviewjs-snippet-showcase/17847/21
*/
var none = '(none)';
var opt = '/journaling/weeklynotes';
var p = dv.pages('"' + opt + '"').where(p => p.file.week-n && p.file.year).map(p => [p.file.name, `${p.file.year}-W${p.file.n-week}`]).sort(p => p[1]);
var t = dv.current().file.n-week && dv.current().file.year ? `${dv.current().file.year}-W${dv.current().file.n-week}` : moment(dv.current().file.cdate).format("YYYY-[W]ww");
// Obsidian uses moment.js; Luxon’s format strings differ!
// I don't know where the weekly note formatting is stored, but the formatting is basically already hardcoded any
// var format = app['internalPlugins']['plugins']['daily-notes']['instance']['options']['format'] || 'YYYY-MM-DD';
var current = '(' + t + ')';
var nav = [];
var today = p.find(p => p[1] == t);
var next = p.find(p => p[1] > t);
var prev = undefined;
p.forEach(function (p, i) {
	if (p[1] < t) {
		prev = p;
	}
});
nav.push(prev ? '[[' + prev[0] + ']]' : none);
//nav.push(today ? today[0] : none);
nav.push(today ? today[0] : current);
nav.push(next ? '[[' + next[0] + ']]' : none);

//dv.list(nav);
//dv.paragraph(nav.join(" · "));
dv.paragraph(nav[0] + ' ← ' + nav[1] + ' → ' + nav[2]);
```

I’m not using weekly notes but I use this dataview inline code within my daily note to dynamically link to the last and next daily note (if that exists). I’m not really that disciplined with my daily notes so I may sometimes skip a day or two and that way I can shuffle easily through my notes.

Maybe the code can be adapted to your weekly notes use case.

<< $= {const query = dv.pages('#daily-note AND !"assets"').sort(p => p.file.ctime, 'asc'); const index = query.map(p => p.file.name).findIndex(name => name === dv.current().file.name); query.map(p => '[['+p.file.name+'|Last]]')[index > 0 ? index-1 : 0]} | $= {const query = dv.pages('#daily-note AND !"assets"').sort(p => p.file.ctime, 'asc'); const index = query.map(p => p.file.name).findIndex(name => name === dv.current().file.name); query.map(p => '[['+p.file.name+'|Next]]')[query.length > index ? index+1 : index]} >>

The script is evaluated without errors, but for some reason it does not seem to be catching what it should, @mr_abomination. There was a typo in the tag and in the folder capitalization, so here is the updated script:

/*
	previous/next weekly note by date for weekly notes
	2023-08-02
	original: https://forum.obsidian.md/t/dataviewjs-snippet-showcase/17847/21
*/
var none = '(none)';
var opt = '/Journaling/weeklynotes';
var p = dv.pages('"' + opt + '"').where(p => p.file.week-n && p.file.year).map(p => [p.file.name, `${p.file.year}-W${p.file.week-n}`]).sort(p => p[1]);
var t = dv.current().file.week-n && dv.current().file.year ? `${dv.current().file.year}-W${dv.current().file.week-n}` : moment(dv.current().file.cdate).format("YYYY-[W]ww");
// Obsidian uses moment.js; Luxon’s format strings differ!
// I don't know where the weekly note formatting is stored, but the formatting is basically already hardcoded any
// var format = app['internalPlugins']['plugins']['daily-notes']['instance']['options']['format'] || 'YYYY-MM-DD';
var current = '(' + t + ')';
var nav = [];
var today = p.find(p => p[1] == t);
var next = p.find(p => p[1] > t);
var prev = undefined;
p.forEach(function (p, i) {
	if (p[1] < t) {
		prev = p;
	}
});
nav.push(prev ? '[[' + prev[0] + ']]' : none);
//nav.push(today ? today[0] : none);
nav.push(today ? today[0] : current);
nav.push(next ? '[[' + next[0] + ']]' : none);

//dv.list(nav);
//dv.paragraph(nav.join(" · "));
dv.paragraph(nav[0] + ' ← ' + nav[1] + ' → ' + nav[2]);

This is what ends being displayed in the note (and the note is from W32, so the number of the current week is somehow wrong):
image

This looks cool but I am not sure if I can adapt it that easily. If I understand this correctly you also sort the files by the file time creation (sort(p => p.file.ctime, 'asc')) and not some other internal reference, I believe this will create some issues in my vault because I sometimes create weekly notes from the future, so the file creation is not a good parameter to query.

based on the output, the p.find is not working correctly which likely means I got something mixed up somewhere.

Can you add the following line to the end of the script console.log(p);, and then copy the output from the console (press ctrl/cmd + shift + i). Open up the Proxy object, then open the [[target]] key, then right click on values and click copy. Put it in a codeblock here and we can see what the script is actually grabbing.

1 Like

Instead of using the p.file.ctime you can use any value from your file’s frontmatter and sort for it.

You can access the YAML frontmatter of your file with p.file.frontmatter.key (where key can be replaced by any YAML key of your frontmatter).

1 Like

edit: after some debugging the part where the generated array becomes empty is at this particular section of the code:

var p = dv.pages('"' + opt + '"').where(p => p.file.week-n && p.file.year);

the where() function there :point_up:

/edit


there are two Proxy objects (I guess one for each previous and next), both of them are empty arrays, so they appear like this:

[]

A screenshot of the console, in case I am doing something wrong.

image

So I think I adapted your code to this for the “Last” item:

`$= {const query = dv.pages('"Journaling/weeklynotes"').sort(p => p.file.frontmatter.week-n, 'asc'); const index = query.map(p => p.file.name).findIndex(name => name === dv.current().file.name); query.map(p => '[['+p.file.name+'|Last]]')[index > 0 ? index-1 : 0]}`

But the order is off, and I am not sure why. If I do just:

dv.list(dv.pages('"Journaling/weeklynotes"').sort(p => p.file.frontmatter.week-n, 'asc').file.name); 

The list that I get is the following, which does not make any sense :confused:

image

I checked the numbers in the tags and they are correct.

I don’t know how you store the week number in your week-n tag. The result of your sort indeed doesn’t seem to have any logical order.

But if you are using the year followed by the week number as your note name you could just apply the sort to the file name (p.file.name) .

As well as year, they are both integers, no quotes, no fancy stuff. I did notice that the “-” sign at the tag might be interfering with something so I changed the frontmatter to just weekn.

Other than that, this is how my frontmatter looks like

---
tags: nice3
weekn: 31
year: 2023
status:
---