Help with dataviewjs image rendering

What I’m trying to do

Sorry if this is a basic question but I am struggling with formatting my dataviewjs block. I have added a moonday property to my Daily Note frontmatter in the format of moonday : mXX (where XX is the moonday). This helps me track the Moon’s age in the sidereal calendar. I have a folder of pixelated .png files that follow the name format of the moonday (mXX.png). I would like to set up my daily notes so that once I populate the moonday property, the appropriate png will be displayed.

Things I have tried

plugins used: dataview
css-snippets: ITS-image-adjustment

I quickly realized that using $= dv.current().moonday was not possible to insert into an inline link and therefore opted to write a dataviewjs block.

1st attempt:

let currentMoonday = dv.current().moonday
dv.paragraph( "![[" + currentMoonday + ".png|right htiny clear-hr]]" )

This did not work as only the alt text would be displayed depending on the source mode and the file would not update dynamically if the moonday property was changed.

2nd attempt
I was able to stumble upon a very amazing post on this forum and was able to get the task to work properly by modifying the code presented as so:

const myField = app.vault.getFiles().filter(file => file.extension === 'png' && file.path.includes('moon') && file.name.includes(dv.current().moonday))
const myFieldType = dv.func.typeof(myField)

if ( myFieldType == "link" ) {
 dv.span(imgDisplay(dv.fileLink(dv.current().ID + ".png")))
} else if ( myFieldType == "array" ) {
 myField.forEach(i => dv.span(imgDisplay(i)))
}

function imgDisplay(imageLink) {
 return '<img src="' + app.vault.getResourcePath(dv.fileLink(imageLink.path)) + '" alt="right htiny clear-hr"/>'
}

My question, however refers to the reply noting that this code is incomplete as the elif statement logic should allow escaping with an error given multiple or unknown values. I do have an image named munknown.png and the Daily Note template defaults to moonday: munknown upon creation. However, I would love to escape my block with an error if moonday is not found in the folder or if multiple values exist.

Apologies if this is a basic question. I am slowly teaching myself JavaScript from scratch but am having ++issues with combining standard JS learning with Dataviewjs codeblocks.

I’d rather use something like the following:

```dataviewjs

const myImgFiles = app.vault.getFiles()
  .filter(file => file.extension === 'png' && 
                  file.path.includes('moon') && 
                  file.name.includes(dv.current().moonday))

if ( myImgFiles.length == 1 ) {
  dv.span(imgDisplay(myImgFiles[0].path))
} else {
  dv.span("Found none or more than one moon image")
}

function imgDisplay(imageLink) {
 return '<img src="' + app.vault.getResourcePath(dv.fileLink(imageLink)) + '" alt="right htiny clear-hr"/>'
}
```

This would be slightly better at picking out that one file and have logical handling if moonday was missing or the script would return multiple image file into myImgFiles.


Then again, this script was written for a specific scenario where it wasn’t using the getFiles() call, and in your case I believe the image path to these files are known in front of the script, so I’d rather use something like:

```dataviewjs
const imgLink = app.vault.getFileByPath("_img/" + dv.current().moonday + ".png")

if (imgLink) {
 dv.span('<img src="' + app.vault.getResourcePath(imgLink) +
         '" alt="right htiny clear-hr"/>')
} else {
  dv.span("Couldn't find moonday image for \`" + dv.current().moonday +"\`")
}
```

Of course you would need to change _img/ to the folder of your images.

But this would be a much cleaner way to display an image when you want to present just part of the name in your field. In general though I do believe it would be better in recent versions of Obsidian to have the full link in the frontmatter directly, as that would allow for link renaming, backlinks and so on to be properly recognised. And then the circle is complete by referring to where I originally defined this script in the post below:

1 Like

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