Image Filter / Processing Methods issue with image resource

Only been coding with Hugo for just under 2 months and I’m enjoying it immensely but finding some things a little tricky. Usually I am able to figure it out but this has me stuck.

I’ve got a content type “project” and each project has two thumbnail images, one in colour and the same one in black and white. Ideally I’d like to create the black and white (Grayscale) using the Image Filter functions rather than having to manage multiple images.

Just inside my pages range loop I use the global resource to get the image resource for the purpose of applying a filter but everything I try results in an error. Before trying the grayscale I was trying a basic resize as well as other filters/processes just to see that I could do anything with the image but no success at all.
“nil pointer…” or “can’t evaluate field Resources in type string…”

<div class="flex px-6 pt-0 container mx-auto">
  <div class="grid grid-cols-1 xxs:grid-cols-1 xs:grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-5 gap-x-8 gap-y-12">
    {{- range where .Site.RegularPages "Type" "in" "project" }}
    {{- $image := resources.Get (strings.TrimPrefix "/uploads/" .Params.thumb ) -}}
    <article class="block project" data-categories="{{ delimit .Params.categories " " | lower }}">
      <a href="{{ .Permalink }}" class="block text-left">
        <div class="relative block w-full h-auto thumb bg-primary overflow-hidden" style="background-image:url({{ .Params.black_and_white_thumb }});">
          <div class="img opacity-0">
            <img class="border-none max-w-none w-full h-auto p-0" width="600" height="650" src="{{ .Params.thumb }}" alt="{{ .Title }}">
          </div>
        </div>
        <p class="font-extrabold text-primary leading-tight text-lg mt-4 mb-2">{{ .Title }}</p>
        <div class="font-regular text-grey-light mb-2">{{ .Params.excerpt }}</div>
        <p class="relative read-more text-primary font-extrabold">Read more</p>
      </a>
    </article>
    {{- end }}
  </div>
  {{ "<!-- / grid -->" | safeHTML }}
</div>

Any direction would be gratefully received, thanks.

Node v14.15.5
Hugo Static Site Generator v0.80.0

Please show front matter of one of your project.md pages. Also, in which directory are the images stored?

All “managed” images added to uploads. Images are fine its just I can’t even start with any kind of filter etc.

Thanks

Project page example:
content > project > numbers.md

+++
black_and_white_thumb = "/uploads/nmbrs-thumb-bw.jpg"
categories = ["Music"]
date = 2016-07-05T23:00:00Z
excerpt = "Website for Numbers, a Glasgow based record label."
project_images = ["/uploads/nmbrs-001.png", "/uploads/nmbrs-002.png"]
thumb = "/uploads/nmbrs-thumb.jpg"
title = "Numbers"
[project_information]
agency = "Studio Remote, London"
client = "Numbers"
platform_and_tech = "WordPress"
role = "Developer"
website_url = ""
+++

Website for Numbers, a Glasgow based record label.

A tailored tagging system was implemented so the content could be interconnected. The connections are visible via **SVG**lines mapped between the related content.

Global resources need to be in the /assets directory, or a directory mounted to /assets. In your case, leave the images where they are, in /uploads. Then do this…

config.toml

[[module.mounts]]
source = "uploads"
target = "assets"

template

{{ with .Params.thumb }}
  {{ $image := resources.Get (strings.TrimPrefix "/uploads/" . ) }}
  {{ $image = $image.Resize "200x" }}
  <img src="{{ $image.RelPermalink}}">
  {{ $image_gs := $image | images.Filter (images.Grayscale )}}
  <img src="{{ $image_gs.RelPermalink}}">
{{ end }}

See:

1 Like

And if you want have global resources in both /uploads and /assets, do this:

config.toml

[[module.mounts]]
source = "assets"
target = "assets"

[[module.mounts]]
source = "uploads"
target = "assets"
2 Likes

OK, I’ll need to focus my attention on the module config part as I could get the filters working as you demonstrated but only if I placed an image in assets. Still getting the “nil pointer…” when I try to use the .Params.thumb uploaded image even after adding this to config.toml:

[module]
  [[module.mounts]]
    source = "uploads"
    target = "assets"

Many thanks

Edit: I think I’ve got it now as I need to add an absolute path to the uploads dir.

Here’s the directory structure of my test site:

├── archetypes
│   └── default.md
├── content
│   ├── project
│   │   └── project-1.md
│   └── _index.md
├── layouts
│   ├── _default
│   │   ├── baseof.html
│   │   ├── list.html
│   │   └── single.html
│   └── project
│       └── list.html
├── uploads
│   └── a.jpg
└── config.toml

content/project/project-1.md

+++
title = "Project 1"
date = 2021-03-11T10:53:47-08:00
draft = false
thumb = "/uploads/a.jpg"
+++

Not sure what’s different about your setup. I’d be happy to take a look if you provide a link to the public repository for your project.

1 Like

Pretty sure I’ve got it now. The uploads directories were only established when I hooked it up to Forestry CMS. I’m sure these were the default settings.

UPLOAD DIRECTORY
The directory where media is stored inside of git
static/uploads

PUBLIC PATH
The path where media is served from
/uploads

So looks like I need:

[module]
  [[module.mounts]]
    source = "public/uploads"
    target = "assets"

Many thanks

All works locally but the build script fails on Netlify, “nil pointer evaluating resource.Resource.RelPermalink…” I’m not sure I’ll spend anymore time on it at this point but I very much appreciate the previous input as it really helped improve my understanding of certain parts of Hugo.

I’ll need to get a proper understanding of Module Config: mounts but at least I have the starting off point.

Thanks

Edit:
UPLOAD DIRECTORY
The directory where media is stored inside of git
/uploads

Changing this is in Forestry means it all works while following the guidance provided by @jmooring. Just thought I’d post this in case some else encounters this.

I ended up spending time looking at it as the curiosity was too much and its working fine the only thing I’d like to understand is how I can get the uploads to be organised in their own directory inside public after build the like the assets > css are inside in a directory public > css. The uploads are just added to the root of public. I thought specifying a path in the target would achieve this:

[module]
[[module.mounts]]
source = “uploads”
target = “assets/uploads”

target
Where it should be mounted into Hugo’s virtual filesystem. It must start with one of Hugo’s component folders: static, content, layouts, data, assets, i18n, or archetypes. E.g. content/blog.

I thought I could do something like the content/blog example but with assets. The build fails.

Edit: I had only been using an ‘assets’ directory in my theme. Adding an ‘assets’ directory to the project root (Note: assets directory is not created by default.) removing the module mounts configuration and having my uploads added to the assets directory specifically assets > uploads sorted all this. Images are now in public/uploads after build and can be retreived using resources.Get so filters can be applied.

├── archetypes
│   └── default.md
├── content
│   ├── project
│   │   └── project-1.md
│   └── _index.md
├── assets
│   └── uploads
│      └── project-1-img.jpg
└── config.toml

In case someone else encounters the same issue. I’ll attempt to detail it here in as simple terms as possible.

My original approach of adding uploaded images to static/uploads was fine but if there was any possibility of processing those images then it was problematic.

In order to process an asset with Hugo Pipes, it must be retrieved as a resource using resources.Get, which takes one argument: the filepath of the file relative to the asset directory.

As well as filters other tasks like getting the image dimension are much simpler when the file is a resource.

Therefore I change the settings in Forestry CMS to the following:

As well as the files now being retrieved as a resource they are now organised in a directory “uploads” in public after the build has been performed.

While @jmooring was 100% correct and the input helped me get a handle on the module mount config stuff I was overcomplicating it.

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