Dataviewjs question: change link colour depending on condition

Yes, I opened the Agenda note and then performed an insert Template. I was in the edit mode when I ran all my tests, but I’m not certain this is a requirement. It does not matter where the cursor is, since the template works with the entire content of the note before overwriting it with updated content. When it’s done, the cursor will end up at the end of the note. (One way the template could be improved would be to put the cursor back where it was before the template ran.)

2 Likes

I am going to test this right now, I missed you answer to my question, sorry!

Would you know if there is a way inside obsidian, to have this template run each time I open the Agenda? I wouldn’t know how to adapt the code, but something similar to this is discussed here. Because if that is possible, this is a very good solution that would not even need user intervention.

You peepz are so smart with code, awesome!!!

1 Like

I just tried out your template and got a parsing error… I figured that this might be, because above where the it says # Agenda 2022, I have added an image and some links to other files. So I generated a brand new Agenda file without those additions, but the error was still there. Could it be the locale (nl_NL) perhaps?

Anyway, I copied what was in the dev tools log, maybe you can make sense of what it says…

  1. Audit usage of navigator.userAgent, navigator.appVersion, and navigator.platform

  2. A page or script is accessing at least one of navigator.userAgent, navigator.appVersion, and navigator.platform. Starting in Chrome 101, the amount of information available in the User Agent string will be reduced.

To fix this issue, replace the usage of navigator.userAgent, navigator.appVersion, and navigator.platform with feature detection, progressive enhancement, or migrate to navigator.userAgentData.

Note that for performance reasons, only the first access to one of the properties is shown.

  1. AFFECTED RESOURCES
1. 1 source

  1. codemirror.js:1
    • Learn more: User-Agent String Reduction
  1. 1

Deprecated Feature Used

  1. SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021. See SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92 - Chrome Developers for more details.

  2. AFFECTED RESOURCES

1. 1 source

  1. app.js:1
  1. 1

SharedArrayBuffer usage is restricted to cross-origin isolated sites

  1. SharedArrayBuffers (SABs) can be used to construct high-resolution timers. High-resolution timers simplify Spectre attacks on cross-origin resources.

To mitigate security risks across browsers, SharedArrayBuffers are gated behind cross-origin isolated contexts starting with Chrome 92 (July 2021). To continue using SharedArrayBuffers, please ensure that this page opts-into cross-origin isolation by setting Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy appropriately.

Note that for each iframe, only the first issue is reported for performance reasons.

  1. AFFECTED RESOURCES
1. 1 violation

  1. 

Source Location: app.js:1
Trigger: Instantiation
Status: warning

1 Like

That error in the log does not make much sense to me, but it suggests to me that maybe you need update one of the underlying pieces of software: Chrome, Obsidian, and/or Templater. It could also be a difference between what platform (mobile vs. desktop, windows vs. Mac vs. Linux) you’re using and I. I’m on a Mac (Big Sur) with Obsidian 0.14.15 and I updated to the latest Chrome a couple days ago.

The error mentions codemirror which is the editor platform Obsidian uses. Then it’s likely the last three lines of the template that are causing the problem, because those are where it’s working directly with the editor. You could comment out those three lines to verify that’s the problem spot. In looking that section over, the ‘this.’ keyword does not need to be there, so you could try removing that.

Could you post the current Agenda.md file? I’ll try it on my system to rule out the changes you’ve made, but I don’t think they’re the culprit.

2 Likes

I’ve been only superficially following the Obsidian 0.15 insider release notes, but there have been mentions in those of changes to APIs with names similar to “active leaf”. I’m also on 0.14.15, so I don’t remember the specifics, but since @FiekeB has an “Insider” tag I’m wondering if there might be something to look at there? Apologies in advance if this is not useful - I haven’t tried to learn the codemirror parts of the API yet.

1 Like

I am on Obsidian Versie 0.15.4 (installer 0.14.6). Which in my case, is the latest version, as it updates automatically. I am on a MacBook Pro, also Big Sur. I do not know how to check for what you call Chrome. I don’t think you mean the browser Google Chrome, but if you do, I just updated it to be sure, to the latest version 103.0.5060.114. If the browser is not what you mean, how can I update the Chrome that you do mean?

Let me first try your suggestion before posting the Agenda.md again, because it hasn’t really changed.

Update:

  • I removed the ‘this.’ keyword → no change, still errors
  • I commented out the last 3 lines as you indicated: NO errors, but (of course) also no update of the monthly calendar of Agenda.md
  • The releasenotes for Insider build 0.15.4 are here if that might be of any help

I mentioned Chrome (the web browser) because the error mentioned a depreciation of a feature in Chrome. But frankly I don’t see how it would have an impact on Obsidian.

The fact that you’re on version 0.15.4 and I’m on version 0.14.15 is probably the issue. @scholarInTraining is likely on the right track. I grabbed that code from someone’s older shared template, so it is quite possible there’s a breaking change that has happened. If so, it should just be a matter of working out what the new equivalent is.

1 Like

How likely, do you think, is it that things will break in the future ? Because if we put this out to the public and that keeps happening, that would mean we need someone to maintain that template. And we actually were not not really willing to go the plugin road, just because @scholarInTraining explained she doesn’t really have the time to do plugin maintenance. We planned to publish it as is, so just a script with a couple of templates to generate and update the Agenda. Hence my question :slight_smile:

PS @ninjineer, you are on Discord too, aren’t you? Would it be faster if we do a call with a screenshare so you can look for yourself? You can then tell me what to show you and paste in Discord’s DM what you need me to change. I did that today with AB1908 and that went really well and we solved my problem in 15 minutes. You don’t have to of course, but if it is easier we could do it.

1 Like

@ninjineer Hey I know the answer to this one! Obsidian on desktop/laptop is built on top of a platform called Electron, which itself is built on top of - among other pieces - Chromium, the open-source portion of Google Chrome. (Related terms I encountered when learning about this: Blink engine, V8 Javascript engine.) So although updating your Chrome browser is always a good thing to do, that is not the Chrome that is being referred to here. Instead, the Chromium inside Electron is complaining about various codemirror things (which I am hoping mean that they are old codemirror 5 things) and Obsidian Insider builds are using codemirror 6.
There was a forum post from the Obsidian devs about the changes from codemirror 5 to 6 Plugin developers: CodeMirror 6 migration guide for v6.0 - not sure if any of the individual Obsidian 0.15.1-0.15.4 changes have superseded anything written there.

I’m actually not on Discord or GitHub, both of which seem go-to platforms for the members of the Obsidian community. Maybe I really need to join one or both.

I just tore through the various 0.15.x release notes and the migration guide that @scholarInTraining mentions. Unfortunately, nothing there jumped out at me that would point to a problem.

Here’s a work around. Instead of those three lines at the end, try this instead:

const tf = app.vault.getAbstractFileByPath(tp.file.path(true));
await app.vault.modify(tf,source);
1 Like

I know in very general terms that it would require hooking a callback function into an event, but the specifics elude me. I suspect that this is straying into plugin territory.

The discussion mentioned above works because Templater has an option to trigger itself (the callback) when a new note is created (the event). That would not apply here as the note is already present.

This is why a DataView solution would have been preferable. It acts when the content is being rendered for preview mode.

1 Like

I have changed the last 3 lines into the two new lines you gave me, no error, but unfortunately also no change to bold

Curious …

If you’re not seeing errors or changes, then there are three possibilities: 1) the script is not correctly identifying which days have content, or 2) the script is not finding matches to the day entries in the calendar, or 3) the modify command is not actually updating.

Can you post your current version of Agenda.md, so I can see if something is different than expected? Alternately below is a slightly modified template. The main difference is that it has the workaround and a couple of console.log statements.

<%*
//Retrieve the original content
let source = tp.file.content;

//Build a map where each key is a day (i.e. '01 januari') and its value is false 
//if the first line after the header line is an empty task or true otherwise
const emptyTask = '- [ ] ';
let map = new Map();
let days = source.split("##### ");
for (let i = 1; i < days.length; i++)
{
   let lines = days[i].split(`\n`);
   if (lines[1] == emptyTask) { map.set(lines[0],false); } 
   else                       { map.set(lines[0],true); }
}
console.log(map);

//Step through the map and update the calendar days in the source to be bold 
//when the map value is true and normal when it is false.
const iterator = map.keys();
let key = iterator.next();
while(!key.done)
{
   const norm = `|[[#${key.value}\\|${key.value.slice(0,2)}]]|`;
   const bold = `|**[[#${key.value}\\|${key.value.slice(0,2)}]]**|`;
   if (map.get(key.value)) { source = source.replace(norm,bold); }
   else                    { source = source.replace(bold,norm); }
   key = iterator.next();
}
console.log(source);

//Replace the original content with the updated content
//let ed = app.workspace.activeLeaf.view.editor;
//ed.setSelection({ line: 0, ch: 0 }, { line: ed.lastLine(), ch: 9999 });
//ed.replaceSelection(source);
const tf = app.vault.getAbstractFileByPath(tp.file.path(true));
await app.vault.modify(tf,source);
-%>

In the Console (Cmd+Option+I) you should see something like the following (note: I’ve added content to the first few days of the year so it’s easier to see the changes and highlighted with red boxes where I expected to see values.):

If you don’t see true values where you know you have content, then possibility 1 is the problem. If you don’t see ** around the days the map says are true, then possibility 2 is the problem. And if all looks right in the console, then it’s possibility 3.

2 Likes

Okay, just made sure there are indeed tasks in the Agenda, both completed and uncompleted. I will test your code with the Agenda.md that I will attach to this message. Thanks for your time and effort ! I really appreciate it :kissing_heart:
Agenda.md (41.4 KB)

I just tested it. Got a whole file full of errors, saw a mention of "Sekund"which is a plugin I recently installed. Decided to uninstall and delete that plugin and restart Obsidian. That solved all the errors apparently, BUT, still no bold in Agenda.md. I even restarted Obsidian again just to make sure.

I cannot find anything n the console log, thta’s looking like the image you posted. But I have copied what I did see into a note and I will attach that here.

I also copied your template and my Agenda.md into a test vault with Templater as the only plugin. Saves me turning off and back on all other plugins in my usual vault. Unless it works in the test vault, then I will have to do the plugin turning on/off to find the culprit.

BUT…No errors, but also no changes to bold in this test vault.

Obsidian Developer Console.md (9.7 KB)

I’ve found the problem. In the original Agenda.md days were formatted like 01 januari. In the newer one they include the day name zaterdag 01 januari. My code Is grabbing the first two characters of this string to get the day number. It works correctly for the first instance but not the second. Also the newer Agenda.md has spaces around the | in the table.

Here’s an updated template that accounts for these differences:

<%*
//Retrieve the original content
let source = tp.file.content;

//Build a map where each key is a day (i.e. '01 januari') and its value is false 
//if the first line after the header line is an empty task or true otherwise
const emptyTask = '- [ ] ';
let map = new Map();
let days = source.split("##### ");
for (let i = 1; i < days.length; i++)
{
   let lines = days[i].split(`\n`);
   if (lines[1] == emptyTask) { map.set(lines[0],false); } 
   else                       { map.set(lines[0],true); }
}

//Step through the map and update the calendar days in the source to be bold 
//when the map value is true and normal when it is false.
const iterator = map.keys();
let key = iterator.next();
while(!key.done)
{
   const pieces = key.value.split(' ');
   const norm = `| [[#${key.value}\\|${pieces[1]}]] |`;
   const bold = `| **[[#${key.value}\\|${pieces[1]}]]** |`;
   if (map.get(key.value)) { source = source.replace(norm,bold); }
   else                    { source = source.replace(bold,norm); }
   key = iterator.next();
}

//Replace the original content with the updated content
const tf = app.vault.getAbstractFileByPath(tp.file.path(true));
await app.vault.modify(tf,source);
-%>
2 Likes

IT’S WORKING!!!

MANY many many thanks for this, dear @ninjineer! :gift_heart:

1 Like

Hi @ninjineer and @scholarInTraining,

the Agenda is working fantastic(ally) !

  • I have added a top-banner with the Banners plugin that matches my themes colours and my tableStyles.css (made it myself)
  • I have - :drum: !! - made a BUTTON that updates the agenda in one simple click! →
```button
name Update
type command
action Templater: Insert 5. ------------------/Templates/updateAgenda template.md
color blue

so I think we are ready to release this as Agenda.zip to the Obsidianers, don’t you think?

In it would be:

  • the Agenda generating script [mdCalendarWithOptions.js] - can we call it agendaGenerator.js and do I need to change anything anywhere if I change the name of mdCalendarWithOptions.js ?
  • the template that goes with the script (testTemplate - can we call it agendaTemplate instead and do I need to change anything anywhere if I change the name of testTemplate ?
  • the Updating template [updateAgenda template]
  • the CSS Snippet to style the calendar tables [tableStyles]
  • a working example Agenda.md with some test tasks to play with
  • a readme.md which will contain:
  1. an explanation about how to use it (I will write this)
  2. credits to all who were involved in creating this [ @ninjineer, @ScholarInTraining, @derekvan, @AB1908, @FiekeB ]
  3. a list of the plugins I used: [Templater] to generate the Agenda itself and to update the Agenda after changes, [Buttons] to make the updating button work, [Banners] to add a top banner to please the eye
  4. confirmation that it works with [Tasks] and [Periodic Notes] as well as native Obsidian checkboxes - [ ]

And also: is there anything any of you would like to add to the readme.md or the zip?

@ScholarInTraining if you have the time (and only then!) you could add the options for just generating 1 month instead of 12, like we talked about. For me personally it is not needed, but maybe other folks could use that for their workflow/setup. I leave it up to you if you want to make time for this or not :blush:

Last: THANK YOU dear people for helping me BIGTIME to get my idea working! :heart_eyes: :heart: :pray: :people_hugging: :bouquet:

1 Like

I’m not sure from your description if this what you’re already planning, but I think you should package this as a vault with all the necessary files in their appropriate places rather than just a simple zip of the individual files. That way interested people get a fully working model to play with.

2 Likes

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