How can I build a filename from two variables?

My guess is you have either a missing or incorrectly spelled category on some page that uses the single.html layout.

To debug try the following and see what the warnings tell you:

{{ $category := .Page.Params.Category }}
{{ $filenameBeginning := $category }}
{{ $filenameEnding := "-breadcrumb-bg.jpg" }}
{{ $combinedFilename := printf "%s%s" $filenameBeginning $filenameEnding }}
{{ $directory := "img/"}}
{{ $bgimage := printf "%s%s" $directory $combinedFilename }}
{{ $assetImage := .Resources.GetMatch $bgimage}}
{{ with $assetImage }}
    <div class="breadcrumbs d-flex align-items-center" style="background-image:url('{{$assetImage.RelPermalink | safeURL }}');">
{{ else }}
   {{ warnf (printf "Page '%s', bgimage: %s" .TranslationKey $bgimage ) }}
{{ end }}

That'll spit out a warning for any pages where Hugo can't find `$bgimage`.

(You probably don’t need the printf or parenthesis but I know for sure that works, so I’ll stick with it until I remember to test warnf’s own formatting spec abilities)

Thank you!!
After working through a few errors I was able to get the site to serve and build.

However, my entire breadcrumb (top of page) and background image are not formatted now (or background image loading). But I am able to build the site and upload via FTP so I can view source on the generated files.

REALLY appreciate the kind assistance!

It’s been a long (10 hr) day here, so I will get back at it tomorrow.

1 Like

If you replace this

with this:

{{ else }}   
    <div class="breadcrumbs d-flex align-items-center">
    {{ warnf (printf "Page '%s', bgimage: %s" .TranslationKey $bgimage ) }}
{{ end }}

then you’ll at least have your breadcrumb / top bar back in the case Hugo can’t find the image. It obviously won’t have an image in that case, but it should unbreak the layout.

EDIT: Oh, and I guess you figured out the with should be if because it changes the context (.) and .TranslationKey would not work as I wrote above.

1 Like

Thanks again. You correctly anticipated the lack of the breadcrumbs div not being written in the ELSE. Also, I had NOT figured out that the with should be an if - so appreciate that catch also.

So with those changes everything looked right, except I was still not getting the background image inline style written (The ELSE was being written instead). So I went back and did a printf $variableName after each variable assignment. All was good up until I asked it to:

printf $assetImage

That returned this error message:



render of "page" failed: "D:\Hugo\HugoSites\01\themes\half-fast\layouts\machine\single.html:14:10": execute of template failed at <$assetImage>: wrong type for value; expected string; got resource.Resource render of "page" failed: wrong type for value; expected string; got resource.Resource  failed to render pages: wrong type for value; expected string; got resource.Resource 

That’s a new one for me so Googling that now, but happy to hear from anyone who knows the fix for this. If it makes a difference, the pages using this are ALL kind: "machine" (defined in Front Matter). THX!

EDIT: Googled and found this (which I am reading now): https://gohugo.io/hugo-pipes/resource-from-string/

What does the console show in terms of WARN using what I have? Since the ELSE it being written, it should be logging the problem pages on the console.

FYI what this is complaining about is the $assetImage is a ‘resource’ not a string.
You may get more using output with:

printf "%s" $assetImage

which should cast it to string.

Thanks for hanging in there with me on this!
I’m afraid I don’t know what you are referring to as the “console”. However, I removed the warnf and just made it printf on the visible page (since it is rendering with the else code).

So here is what my code looks like now. (Noob attempting to recast the string to a resource for the first time):

{{ $filenameBeginning := $category }}
{{ $filenameEnding := "-breadcrumbs-bg.jpg" }}
{{ $combinedFilename := printf "%s%s" $filenameBeginning $filenameEnding }}
{{ $directory := "img/"}}
{{ $recastString := $combinedFilename | resources.FromString $directory}}
{{ $assetImage := .Resources.GetMatch $recastString }}
{{ if $assetImage }}
    <div class="breadcrumbs d-flex align-items-center" style="background-image:url('{{$assetImage.RelPermalink | safeURL }}');">
{{ else }}   
    <div class="breadcrumbs d-flex align-items-center">
    {{ printf "Page '%s', bgimage: %s" .TranslationKey $assetImage }}
{{ end }}

The printf error says:

Page 'page/machine/stairboss_pro/index', bgimage: %!s(<nil>)

It should perhaps be noted that the index page in question is found at:
/content/machine/stairboss_pro/index.md (no directory named “page” if that is what it is saying).

Instead of

try

{{ printf "Page '%s', bgimage: %s" .TranslationKey $recastString }}

Also that initial ‘page’ in page/machine/stairboss_pro/index just means that it’s a page.

And the console is where you were seeing:

execute of template failed: template: machine/single.html:12:93: executing "main" at <$assetImage.RelPermalink>: nil pointer evaluating resource.Resource.RelPermalink

when you did hugo server way back at the top. Perhaps I should have said on command line or in the terminal.

And what this

%!s(<nil>)

tells us is that $assetImage has no value (is nil) but we already knew that because we are in the else which can only happen when there is no value for assetImage

OK thank you. But I only see the console if there is an error and the page cannot be served or rendered.
It IS serving and rendering… only with (as you noted) the {{else}} html.

My current code:

{{ $category := .Page.Params.Category }}
{{ $filenameBeginning := $category }}
{{ $filenameEnding := "-breadcrumbs-bg.jpg" }}
{{ $combinedFilename := printf "%s%s" $filenameBeginning $filenameEnding }}
{{ $directory := "img/"}}
{{ $fullPathAndFilenameRecast := (resources.FromString $combinedFilename $directory) }}
{{ $assetImage := .Resources.GetMatch $fullPathAndFilenameRecast }}
{{ if $assetImage }}
    <div class="breadcrumbs d-flex align-items-center" style="background-image:url('{{$assetImage.RelPermalink | safeURL }}');">
{{ else }}   
    <div class="breadcrumbs d-flex align-items-center">
    {{ printf "Page '%s', bgimage: %s" .TranslationKey $fullPathAndFilenameRecast }}
{{ end }}

Results in:

Page 'page/machine/stairboss_pro/index', bgimage: Stairs-breadcrumbs-bg.jpg

So we are making progress, but the directory in /assets/ is not being put on the front of the path.
The image resides at: themes/half-fast/assets/img/Stairs-breadcrumbs-bg.jpg

Is this a clue? (Screenshot of my VSCode):
https://imgur.com/a/p2rrnHy

How about replacing:

with

{{ $fullFileAndDir := printf "img/%s-breadcrumbs-bg.jpg" $category }}
{{ $assetImage := .Resources.GetMatch $fullFileAndDir }}
{{ if $assetImage }}
    <div class="breadcrumbs d-flex align-items-center" style="background-image:url('{{$assetImage.RelPermalink | safeURL }}');">
{{ else }}   
    <div class="breadcrumbs d-flex align-items-center">
    {{ printf "Page '%s', bgimage: %s" .TranslationKey $fullFileAndDir }}
{{ end }}
```
1 Like

That is telling you that resources is a keyword.

But, as an aside, I want to clarify resources.FromString.

That creates a ‘resource object’ (that does the same thing as .Resources.GetMatch) only it creates it from a the string you provide instead of from a file. So it’s actually not what you want. It also writes the resources to the build cache at the path your specify.

So what the docs say is:

resources.FromString which takes two arguments, the given string and the resource target path.

which mean that this:

resources.FromString $combinedFilename $directory

tells Hugo create a resource from the literal string (not the file at the location, but the actual characters in the filename) with the filename $directory (in /public of course, but only in cache unless you .Permalink it or similar). You were then assigning the resource (not a string with a path) to $fullPathAndFilenameRecast.

I don’t think that is quite what you were looking for.

That’s great (and the easier way that I suspected existed)!
We’re getting the full path now, so the problem seems to be in the .Resources.GetMatch

I may have a changed variable name in here (from before) but the page serves and renders (but still no background-image in the div) - getting the {{ else }} html:

{{ $category := .Page.Params.category }}
{{ $fullFilename := printf "img/%s-breadcrumbs-bg.jpg" $category }}
{{ $assetImage := .Resources.GetMatch $fullFilename }}
{{ if $assetImage }}
    <div class="breadcrumbs d-flex align-items-center" style="background-image:url('{{$assetImage.RelPermalink | safeURL }}');">
{{ else }}   
    <div class="breadcrumbs d-flex align-items-center">
    {{ printf "Page '%s', bgimage: %s" .TranslationKey $fullFilename }}
{{ end }}

This results in:

Page 'page/machine/stairboss_pro/index', bgimage: img/Stairs-breadcrumbs-bg.jpg

So THAT SHOULD work. But something is not working in the GetMatch. (I’ve also tried .Resources.Get and using.Page.Resources.GetMatch and .Page.Resources.Get). No joy on any of them (but page still renders and give me the proper bgimage in the debugging printf.
An image with that exact name DOES exist in /themes/themeName/assets/img

I missed this before; it should be resources.Get $fullFilename

Otherwise you trying to find the resource in a ‘page bundle’ instead of from assets.

IIRC you could also do .Site.Resources.Get $fullFilename but resources is safer because you don’t have to worry about the context (the .).

1 Like

That was it!
First I just tried changing the case of the “R” to .resources.Get (wasn’t reading your post carefully). But that gave me a different error message:

 <.resources.Get>: resources is an unexported field of struct type page.Page

Googling that led me to: https://discourse.gohugo.io/t/what-am-i-not-getting-about-resources-get/33517/5?u=cheekygeek and that’s when I realized you had ALSO left of the “.” before resources. Once i removed that, it WORKED.

I definitely need to study up on the resources methods and when to use capitals and when to use the period in the front. That is scrambling my brain.

THANKS SO MUCH FOR HELPING ME THROUGH THIS! (Did we set a record for number of posts in a thread? :slight_smile:

1 Like

I enjoyed helping; and I hoped there were some ‘learnings’ (to use a horrible modern slang) happening :grin:

One final thing: Do you run Hugo via the command line by typing (in a terminal):

hugo server

or do you use some VSCode extension? If the latter than that is why you are not seeing the ‘console’ or the WARNS from warnf.

I normally use the Terminal in VSCode (which is Powershell on my Windows 10 machine).
I do have some Hugo-related extensions installed.

What happens if you view the Terminal while the server is running? (Does the Terminal get hidden due to lack of screen space? Or are you just looking at a browser instead of VSCode, or is there something I haven’t thought of that you are doing?

AH. I see what you are saying.
I normally leave the terminal open in VSCode (below the code window). If I see a number pop up on the Problems tab I will switch from the terminal to that sometimes. But scrolling up through the Terminal window I DO see that ERRORs are written there. I’m assuming the warnf was also, but the buffer doesn’t allow me to scroll back that far. I’ll watch for it in the future. Thanks again!

1 Like

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