Embed internal images in dataviewjs table from frontmatter?

What I’m trying to do

I want to embed an internal image in a dataview table. The image will sit in a frontmatter property. I want to input [[image.jpg]] as the property (as opposed to ![[image.jpg]]), so it remains dynamic regardless of name or location changes.

e.g.

--- 
cover: [[image.jpg]] 
--- 

will show the image in a dataview table.
Following the documentation, I found you can use the meta function like so

dataview 
TABLE embed(link(meta(cover).path)) 
WHERE file.name = this.file.name 

and this has the desired effect, but I have other fields in the table that can only be achieved using dataviewJS. So I want to translate this result into dataviewJS.

Things I have tried

dataviewjs 
dv.table(["Cover"], 
    dv.pages() 
        .filter(p => 
                p.file.name === dv.current().file.name) 
        .map(p => [ 
            embed(link(meta(cover).path)) 
        ]) 
) 

Obviously doesn’t work as embed, link and meta aren’t defined.

Prior to this, because I had successfully been able to get the following to work for external images (i.e. those of type https://website.com/image.jpg)

.map(p => [
`![](${p.cover})` 
]) 

so I was trying to map

.map(p => [ `!${p.cover}` ]) 

or

.map(p => [ `![[${p.cover}]]` ]) 

or

.map(p => [ `![[${String(p.cover)}]]` ]) 

and several other variations, but these only return text.

I assume the best way would be to find the file path of internal image using dataviewJS, because that’s the method for base dataview. But I’m not bothered about the method, as long as it can convert properties of format property: [[image.jpg]] into an embedded image. Thanks for you help!

Does your code work as you’ve written it? I can’t see how that would come about, as your definition of the cover link, should be:

---
cover:  "[[image.jpg]]"
---

The point being that if cover is properly defined, you should be able to do cover.path within your dataviewjs script directly to access the different parts of the link. Try doing a console.log(cover) within your script to see how it behaves.

Still you’re entering a shady part of dataview with embedding stuff, which is a little bit random at times, as I’ve (and the issue I linked) indicates in this answer:

I’m greatly interested in this as well, I’m hoping to do the same but with 1 or more pdf links in a frontmatter property. As you suggest, my links have quotes around them:

drugLabel:
  - "[[20240104 - ACME Pharmacy.pdf]]"
  - "[[20240102 - ACME Pharmacy.pdf]]"

I found this works with just one link, but not more (they show up as text):

```dataviewjs
const label = "!" + dv.current().drugLabel
dv.span(label)
```

Maybe this meets @doe 's needs as long as quotes are added to their links?

1 Like

The most reliable way I’ve found to display an image, given proper links in a field/property is like the following:

---
image: "[[myImage]]"
---

```dataviewjs

dv.span('<img src="' + app.vault.getResourcePath(dv.fileLink( dv.current().image.path )) + '" />'))
```

You could also construct such monstrosities as the following if you don’t know whether your myField is one link or an array of links:

```dataviewjs

const myField = dv.current().myField
const myFieldType = dv.func.typeof(myField)
if ( myFieldType == "link" ) {
  dv.span(imgDisplay(myField))
} else if ( myFieldType == "array" ) {
  myField.forEach(i => dv.span(imgDisplay(i)))
}

function imgDisplay(imageLink) {
  return '<img src="' + app.vault.getResourcePath(dv.fileLink(imageLink.path)) + '" />'
}
```

Replace the first dv.current().myField with your field name, and hopefully that should work consistently for you as it do for me! :smiley:

4 Likes

Sorry, I had done it like this. I was using the Properties core, so I had forgotten to write the quotation marks on here.
Thanks for suggesting cover.path. It does return the right path, but again .map(p => [ `![](${p.cover})` ]) leads to nothing being displayed.

Here’s what I get from console.log()

  • cover : Evaluation Error: ReferenceError: cover is not defined (in the codeblock, not the console)

  • `cover` : cover

  • p.cover : Link {path: '_imagestest/20240112_135340.jpg', type: 'file', subpath: undefined, display: undefined, embed: false}

  • p.cover.link : undefined

  • p.cover.path : _imagestest/20240112_135340.jpg

  • `![ ](${p.cover.path})` : ![](_imagestest/20240112_135340.jpg)

  • “![ ](” + p.cover.path + “)” : ![](_imagestest/20240112_135340.jpg)

  • “!” + p.cover : ![[_imagestest/20240112_135340.jpg|20240112_135340.jpg]]

  • dv.span(“!” + p.cover) : <span alt="20240112_135340.jpg" src="_imagestest/20240112_135340.jpg" class="internal-embed">20240112_135340.jpg</span>

  • dv.current().cover and variations worked the same as p.cover, except it wasn’t restricted to only working within the mapping.

The last two (dv.span & “!” + …) flashed the photo for about a second, then reverted to showing the text 20240112_135340.jpg in the table. The two prior show no photo and no text. Both of the results work if pasted outside of the codeblock, so I’m not sure.

Thanks! I wish I had scrolled down before trying all of that because the first one here works for me :smile: Regardless I learned some new things so thanks for those as well. Are you able do determine the size of the image with this technique?

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