Unmarshal fails when called from a partial template in a content adapter

I am working on a project where most of the content lives in a database behind a self-hosted CMS, and I would like to generate static pages from my CMS’ api through content adapters.

In order to reuse the logic for handling requests (building the requests & handling errors), I have tried setting up a partial template to be called from _content.gotmpl, but am encountering this error:

ERROR error building site: process: readAndProcessContent: "[...]/temp-hugo/content/_content.gotmpl:8:46": template: [...]/temp-hugo/content/_content.gotmpl:8:46: executing "[...]/temp-hugo/content/_content.gotmpl" at <partial "my-partial" .>: error calling partial: "[...]/temp-hugo/layouts/_partials/my-partial.html:3:23": execute of template failed: template: _partials/my-partial.html:3:23: executing "_partials/my-partial.html" at <transform.Unmarshal>: error calling Unmarshal: type *pagesfromdata.pagesFromDataTemplateContext not supported

Here’s a minimal setup that reproduces the error, with some logs to compare request made from _content.gotmpl with request made from the partial template:

content/_content.gotmpl
{{ warnf "[content] %s" site.Params.endpoint }}

{{ with resources.GetRemote site.Params.endpoint }}
    {{ warnf "[content] res: %v" (debug.Dump .) }}
    {{ warnf "[content] obj: %v" (debug.Dump ( transform.Unmarshal . )) }}
{{ end }}

{{ warnf "[content] result from partial: %v" (partial "my-partial" .) }}

The request + unmarshalling succeeds in the content adapter, but fails when called from the partial.

layouts/_partials/my-partial.html
{{ with resources.GetRemote site.Params.endpoint }}
    {{ warnf "[my-partial] res: %v" (debug.Dump .) }}
    {{ return transform.Unmarshal . }}
{{ end }}

The endpoint here is just a mockbin.io url that returns {"message": "Hello World"}.

I am probably doing something wrong, or perhaps this way of using content adapters is not currently supported?

No, that should be perfectly fine. I don’t see anything wrong with your setup, which suggests that there’s something I don’t see.

Oh right, if you want to look into it, here’s a repo with the full minimal setup: abrusle/sharing-hugo-issue - Codeberg.org

Just set the endpoint url in hugo.yaml and then build the site.

What Hugo version do you build with?

Thank you for taking the time to help, really appreciate :slight_smile:

I’m using hugo v0.162.1, the latest provided by my distro’s package manager.

Yea, OK, then I think I know what it is (even if the error you describe is mysterious):slight_smile:

  • Your demo site works with the latest Hugo.
  • We rewamped the return keyword in v0.166.0 (see Release v0.166.0 · gohugoio/hugo · GitHub)
  • In older Hugo versions, you could only use it in partials and it had to be the last statement.

So you can either upgrade to the latet Hugo ore rewrite the partial to:

{{ $res := ""
{{ with resources.GetRemote site.Params.endpoint }}
    {{ $res = transform.Unmarshal . }}
{{ end }}
{{ return $res }}

In any case I would make sure to always return something (e.g. a blank string when not found).

Okay, that makes sense.

I rewrote the partial like you suggested and it works!
I’ll apply that to my (larger) project tomorrow morning and post a final update here.

Thank you very much for your help! :smiley:

with error handling for GetRemote you might also need to modernize to the new error handling introduced with 141

Quick update: the fix does work in my main project :white_check_mark:

with error handling for GetRemote you might also need to modernize to the new error handling introduced with 141

@irkode Thank for the advice, I am in fact using the new error handling feature in my project. I simply removed it for the minimal reproduction code when trying to debug the issue :slight_smile: