readFile directory

I want to readFile a file that is within my posts directory as in

/content/posts/my-post/post.svg

First thing I tried within a shortcode was:

{{ with .Get "svg" }}
{{ readFile . | safeHTML }}
{{ end}}

but that’s picking the wrong directory (as documented).
How do get the directory of the post the shortcode is used in?

This is working for me. See below to for what may be different on your end.

Given this svg:

content/posts/my-post/post.svg

And this shortcode definition at layouts/shortcodes/readFile.html:

{{ with .Get "svg" }}
  {{ readFile . | safeHTML }}
{{ end }}

Called like so from another content file:

{{< readFile svg="content/posts/my-post/post.svg" >}}

I get the expected svg output.

Thanks for the reply. Sorry, that wasn’t obvious from my question but I don’t want to write the full path as attribute. Rather just

{{< readFile svg="post.svg" >}}

I am trying to use the variables like .File.Dir from https://gohugo.io/variables/files/ but so far I could not figure it out.

Other than hardcoding the path in the shortcode definition, I don’t know of a way to do this. Since it’s an svg and not a page, you can’t use site.GetPage

And shortcodes don’t have access to context related variables like .File?

They do. You’d call it like .Page.File

But am not seeing how that would be helpful here (assuming you want to call this shortcode from any page, not just one in the same bundle)

TBH I don’t understand your comment on the bundle yet.
But every page that calls the shortcode should have a directory where it lives.

The idea would be to combine this directory with the provided relative filename to turn it into an absolute path. Unfortunately

  {{ .Page.File }}

gives

 at <.Page.File>: can't evaluate field Page in type string

This is got me closer

{{ with .Get "svg" }}
  {{ $svg := $.Page.Resources.GetMatch . }}
  {{ $svg }}
{{ end}}

but I failed to see how to get to the path from the resource. The “$” gave an aha moment though. This seems to do the trick now.

{{ with .Get "svg" }}
  {{ readFile (print $.Page.File.Dir "/" .) | safeHTML }}
{{ end}}

If you do it this way then you need to use .Content

{{ with .Get "svg" }}
  {{ $svg := $.Page.Resources.GetMatch . }}
  {{ $svg.Content }}
{{ end }}
1 Like