[SOLVED] How to use the new Resource.Content feature

I would really like to use the new Resource.Content feature, but I cannot get it to work. I’ve use readFile like this before:

{{- $file := .Params.codefile -}}
{{ readFile $file }}

And I would like to replace it with that. I’ve tried:

{{- $file := .Resources.Match "code.txt" }} {{ .Resource.Content $file }}

and

{{ ( .Resources.Match "code.txt" ).Content }}

and a couple of other things I can’t remember now. But none of it works… :-/

You have a syntax error. Its .Resources.GetMatch

Example from the relevant GitHub issue
src="{{ (.Resources.GetMatch "mylogo.png").Content | base64Encode }}

Just to add a little bit of clarification… .Resources.Match is syntactically correct too, but not when used in this context: ( .Resources.Match "code.txt" ).ContentDocs on .Resources methods.

  • .Resources.Match -> Returns a slice of matches… so you need to then use a range to go through the returned slice/list.
  • .Resources.GetMatch -> Returns only the first match.

So yes, .Resources.GetMatch is the right method in this context.

2 Likes

Thank you for your answers.

The problem is that it doesn’t work. I try this:

{{ (.Resources.GetMatch "code.txt").Content }}

where I now have (and this works fine, but needs the “codefile” param set in the front matter to work):

{{- $file := .Params.codefile }}
{{ readFile $file }}

The error I get is:

Failed to render "themes/mytheme/layouts/_default/page.html": reflect: Method on nil interface value

Can you share your repository so that we can see what’s going on?

Cheers.

Unfortunately, I can’t. But I can give you a bit more info.

I have a content dir that looks like this:

content
├── about.md
├── blog
│   ├── _index.md
│   └── posts
└── products
    ├── product1.md
    └── my-product
        ├── code.txt
        ├── codeexample.md
        ├── feature-1.md
        ├── feature-2.md
        ├── feature-3.md
        ├── index.md
        └── pros.md

And I have a partial where I would like to use the content of the code.txt file, inside a <pre> tag:

    <!-- Code -->
    <pre class="pre-code">
{{ (.Resources.GetMatch "code.txt").Content }}
    </pre>
  </div>

Hope this clarifies it a bit…

In the error you posted above Hugo complains about the above template.

Typically Hugo uses _default/single.html template for single pages.

Try renaming your page.html into single.html and let me know.

Also if you want to use a template for the layout of page /_default is not the correct folder for it.

It should be under /layouts/page/single.html

See the Docs for more: https://gohugo.io/templates/lookup-order/#hugo-layouts-lookup-rules-with-theme

I’ve set layout=pagein my frontmatter, so it should be fine to use that template. And it works fine when I use the readFile method. Maybe I should change the structure, but I don’t think that is what cause the error…

It’s difficult to say. If you have the time make a repository with dummy content so that we can have a look.

I’ve setup a test repo, with code that works with readFile. But I cannot get it to work with Resources.Content.

Click on My Product on the home page to test it.

I also cannot get the layout/page/single.html structure to work, nor the layout/single.html structure - that’s why its now structured as layouts/_default/page.html and layout: page is set in the front matter.

I should probably add what I like to accomplish:

Use .Resource.Content instead of {{- $file := .Params.codefile }} {{ readFile $file }} in the code.html partial. The readFile method works fine, but requires me to define the path of the file in the front matter.

I’ll have a look later today because I have to go now.

I had a look at your test repository. The error you experienced was due to the fact that Hugo could not find the resource from within the partial you defined. To achieve what you want change your code.html partial to the following

<!-- Code -->
<pre class="pre-code">
{{ (.Page.Parent.Resources.GetMatch "code.txt").Content }}
</pre>
</div>

Note the addition of .Page.Parent This tells Hugo to look for a resource from within another resource that belong in the same Page Bundle.

Why do you need to do that? Because of the way you have structured your page.html template:

{{ define "main" }}
{{- with .Resources.Match "codeexample.md" }}
  {{- range . }}
    {{ .Render "codeexample" }}
  {{- end }}
{{- end }}
{{ end }}

In your template you are calling the codeexample.md resource and then from within its range you are rendering your codeexample.html template. Hence the context is lost when you’re trying to call the .Content of the resource code.txt from within your code.html partial.

Hope I made this clear for you.

2 Likes

Thank you so much for your detailed reply - it makes perfect sense the way you present it. I haven’t had that much time with Hugo yet, so I don’t know all the intricacies :slight_smile:

Thank you once again…!

2 Likes

I’ve just tested it, and it worked like a charm! Thanks again!!

Best regards,
Juri