Resized images in "recent posts"

Hi,

thanks to @jmooring i got the risizing of images working ( Prevent Images in originalsize in public ) Thank you very much for your help!

But then a following problem occured. I use the hugo-universal-theme and this theme provides a way to show “recent posts” on the startpage. With the resizing and not publishing the original file, i have no clue how to put the “resized” image there.

First Try: Resize again. For that i changed the “recent_posts.html” in the theme but it somehow cant access the original path. Maybe because it works on the already processed images.

Second Thought: Put the filename of the resized image into the “banner” parameter at the top of a post, so that the template finds it. That works, but i dont have the name in the first place. So i had to run the resizing, find the name and have to put it there. Thats not very comfortable.

Third Thought: Rename the File after resizing to the original name or to the originalname with some suffix. Something like “example.jpg” to “example_minified.jpg”. But i dont get this working…

I hope you have a better idea or a solution for one of these ideas. Thanks!

The relevant code in recent_posts.htl is in lines 24-28

{{ if isset .Params "banner" }}
  <img src="{{ .Params.banner | relURL }}" class="img-responsive" alt="" />
{{ else }}
  <img src="{{ "img/placeholder.png" | relURL }}" class="img-responsive" alt="" />
{{ end }}

using Frontmatter parameter Banner would need a hardcode argument. But if this is not set
it will use the image in the page buldle names img/preview.png

If you don’t mind duplicating this image, the simplest would be to publish fe the first image you resized twice using that hardcoded path.

{{- if $r is first first image resource}}
  {{ with $r | resources.Copy "img/preview.png" }}
    {{- $noop := .RelPermalink }}
  {{ end }}
{{ end }}

Doing that you do not need to adjust the templates.

Thanks for your help. but unfortunatly i cant get this working.

My code is like this:

{{ $content := .Inner | strings.TrimSpace }}
{{ $lines := split $content "\n" }}

<div class="imagegrid">

  {{ range $index, $line := $lines }}
  {{ $imgBig := $line | strings.TrimSpace }}
  {{ if $imgBig }}

  {{ $imgFile := $.Page.Resources.GetMatch $imgBig }}
  {{ $img := $imgFile.Resize "1000x q80" }}


  {{ $id := printf "image_%d" (add $index 1) }}
  <div class="imagegrid__item imagegrid__item--large">
    <a id="{{ $id }}_anchor" class="imagegrid_anchor"></a>
    <a class="imagegrid__link" href="#{{ $id }}">
      <img
              src="{{ $img.RelPermalink }}"
              width="{{ $img.Width }}"
              height="{{ $img.Height }}"
              alt=""
              loading="lazy">
    </a>
  </div>

  <div id="{{ $id }}" class="image-lightbox" role="dialog" aria-modal="true">
    <a class="image-lightbox__close" href="#{{ $id }}_anchor" aria-label="Schließen">✕</a>
    <div class="image-lightbox__inner">
      <img
              src="{{ $img.RelPermalink }}"
              width="{{ $img.Width }}"
              height="{{ $img.Height }}"
              alt=""
              loading="lazy">
    </div>
  </div>




  {{ end }}
{{ end }}
</div>

I tried to integrate your code snippet to generate a preview image that is included in the export, but that does not work. I had some success getting the image to the static/img/ folder, but i think i need one in each post-folder. And i am not smart enough to get this working…

would you mind to share your repo. would save me from replicating your setup

Sorry, this is unfortunatly not possible. (big private repo…) but i can make a repo with only this issue. So you dont have to do this work! I will write here again if i have set it up. Thanks

Got it - used a standard hugo new theme :wink:

lines 14-18

resources.Copy seems to use the publishing root as base, (thought it was relative) but … so I had to add the published path of the page.

p.s. you should check if your GetMatch $img.Resize returns something - coding defensive is always a good idea. typos in the filenames in your gallery :wink:

{{ $content := .Inner | strings.TrimSpace }}
{{ $lines := split $content "\n" }}

<div class="imagegrid">

  {{ range $index, $line := $lines }}

  {{ $imgBig := $line | strings.TrimSpace }}
  {{ if $imgBig }}

  {{ $imgFile := $.Page.Resources.GetMatch $imgBig }}
  {{ $img := $imgFile.Resize "50x q80" }}

  {{ if not $index }}
    {{ with $img | resources.Copy (urls.JoinPath $.Page.RelPermalink "img/placeholder.png") }}
      {{ $noop := .Publish }}
      {{ end }}
  {{ end }}


  {{ $id := printf "image_%d" (add $index 1) }}
  <div class="imagegrid__item imagegrid__item--large">
    <a id="{{ $id }}_anchor" class="imagegrid_anchor"></a>
    <a class="imagegrid__link" href="#{{ $id }}">
      <img
              src="{{ $img.RelPermalink }}"
              width="{{ $img.Width }}"
              height="{{ $img.Height }}"
              alt=""
              loading="lazy">
    </a>
  </div>

  <div id="{{ $id }}" class="image-lightbox" role="dialog" aria-modal="true">
    <a class="image-lightbox__close" href="#{{ $id }}_anchor" aria-label="Schließen">✕</a>
    <div class="image-lightbox__inner">
      <img
              src="{{ $img.RelPermalink }}"
              width="{{ $img.Width }}"
              height="{{ $img.Height }}"
              alt=""
              loading="lazy">
    </div>
  </div>
  {{ end }}
{{ end }}
</div>

Updated as per recommendation from @jmooring. thx.

1 Like

Hi,

Thanks! That kind of worked.

Edit: This is not true: In the content folder under the post appears a new img-folder containing the correct preview image.

The public folder contains the same, so i assume, that the mechanism worked.

But unfortunatly the image is not shown on the mainpage or the blog-overview.

I have to add

banner = "aktuelles/title_of_post/img/preview.jpg"

to the top of the post/index.md to make it work.

My fault. there is no change in the content folder. that was my own change. sorry for that.

sry for the inconvenience, overseen the Relurl…updated my code:

the fixed fallback is img/placeholder.png not preview. and it has to be a png.

Both params.Banner and the fallback use relurl, so the given path has to be relative to the baseURL

so publishing to /img/ would be a possibility.

If it was mine, I would override that template and use a page resource there.

It ist this part in the themes revent_posts.html

                            <div class="image" style="overflow:hidden">
                                {{ if isset .Params "banner" }}
                                <img src="{{ .Params.banner | relURL }}" class="img-responsive" alt="" />
                                {{ else }}
                                <img src="{{ "img/placeholder.png" | relURL }}" class="img-responsive" alt="" />
                                {{ end }}
                            </div>

so you would change the “else” to use the path of the current post?
Ok, i try to figure this out.
Thanks!

i would do for both
may add the static placeholds as real fallback if there is no image found
just removing | relURL should do.

something like that:

just as a starter, not a golden image :wink:
Guess you get the logic.

you may want to handle missing stuff/fallback differently. or prefer if or …

  • params.banner is relative to the page
  • page banner has to be page_banner.png
  • fallback is in /static/img/page_banner_fallback.png
<div class="image" style="overflow:hidden">
  {{ $page := . }}
  {{ with $page.Params.banner }}
    {{ with $page.Resources.Get . }}
      {{ warnf "[%s] Page Params: loaded from %s " $page.Path .}}
      <img src="{{ .RelPermalink }}" class="img-responsive" alt="" />
    {{ else }}
      {{ warnf "[%s] params banner not found at : %s " $page.Path . }}
    {{ end }}
  {{ else with $page.Resources.Get "img/page_banner.png"}}
    {{ warnf "[%s] Page resource loaded from %s " $page.Path .}}
    <img src="{{ .RelPermalink }}" class="img-responsive" alt="" />
  {{ else }}
    {{ warnf "[%s] Global fallback loaded from page_banner_fallback.png" $page.Path}}
    <img src="{{ "img/page_banner_fallback.png" | relURL }}" class="img-responsive" alt="" />
  {{ end }}
</div>
1 Like

I think my project is somehow messed.
This solutions is not working sadly.
With “no banner set” i always end in the “Global fallback”.

And the banner images are never found. so its not working.

I will try to strip everything away to isolate the problem.
Thanks for all your help!

Sad to hear,

still the option to certae a reproducible small tst repo. pretty sure I can plug it in.

My setup was just a bare theme and plugin your gallery shortcode and the recent_posts partial.

likely that there’s something more around.

Hi,
i stripped everything away that was not necessary.

Maybe you can figure out what goes wrong.
Thanks!

Nothing wrong on your site - Sorry again

root cause: the resource copied to the target page img/preview.jpg is unfortunately not added as a page resource. that’s why it’s not found - seems to be standard for hugo.

I changed the code to:

  • save the .RelPermalink of the first resized image to a the page.Store instead of creating a copy

    imagegallery replaced lines 14-18 with this
    {{ if not $index }}
      {{ $.Page.Store.Set "banner" $img.RelPermalink }}
    {{ end }}
    
  • retrieve the page.Store while rendering the recent posts (and make sure Store is fixed)

    recent_posts - updated the div for image selection
    <div class="image" style="overflow:hidden">
        {{- /* make sure page is rendered to determinate Store */}}
        {{ $noop := .WordCount }}
        {{ $page := . }}
        {{ with $page.Params.banner }}
            {{ with $page.Resources.Get . }}
                {{ warnf "[%s] Page Params: loaded from %s " $page.Path . }}
                <img src="{{ .RelPermalink }}" class="img-responsive" alt="" />
            {{ else }}
                {{ warnf "[%s] params banner not found at : %s " $page.Path . }}
            {{ end }}
        {{ else with $page.Store.Get "banner"  }}
            {{ warnf "[%s] Page resource loaded from %s " $page.Path . }}
            <img src="{{ . }}" class="img-responsive" alt="" />
        {{ else }}
            {{ warnf "[%s] Global fallback loaded from img/placeholder.png" $page.Path}}
            <img src="{{ "img/placeholder.png" | relURL }}" class="img-responsive" alt="" />
        {{ end }}
    </div>
    

Benefit: no duplicate image published
Drawback: the implementation supports only ONE imagegallery per page! or we could say: the first image of the last imagegallery will be used. (could be changed though)

Frohes neues Jahr :wink:

1 Like

Thank you very very much!
If i could send you a coffee and cake i would do :slight_smile:
It works great!

I had to change also the “list.html” in the theme → _default folder to have the images in the blog-post overview. That worked great.
Thank you, i would have never come to this solution.

PS: Danke und ebenfalls einen guten Rutsch ins neue Jahr :slight_smile:

1 Like

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