Image processing inside content using shortcode


#1

I’m using headless bundles as image resource, in this case is content/uploads

what I need is to make Hugo processing the image inside the content by using shortcodes. There is 2 scenariom the first one is get the image from the front matter param and the other one is directly from the value inside the shortcode it self

so far i manage to make the first scenario working, here’s my workaround

shortcodes/recipe.html

{{ $hero := $.Page.Params.recipe.hero }}
<div class="recipe-hero">
		{{ with $hero }}
            {{ $imageResource := ($.Site.GetPage "/uploads").Resources.GetMatch (strings.TrimPrefix "/uploads/" . ) }}
            {{ $desktop := $imageResource.Fill "690x300 q50 Center"  }}
               <img src="{{ $desktop.RelPermalink }}">
        {{ end }}
	</div>

then call the image using {{< recipe >}}

the problem is i’m stuck in the second scenario where i have to define the image src inside my shortcode eg {{< image src="takoyaki.jpg" >}} my goal is to have responsive image using src-set

I’m using generic version from Hugo doc shortcode template

shortcodes/image.html

<figure class="image-caption">
        <img data-sizes="auto" class="lazyload"
        data-srcset="/uploads/{{ .Get "src" }}" />
    <figcaption>{{ if isset .Params "title" }}
        <h5>{{ .Get "title" }}</h5>{{ end }}
    </figcaption>
</figure>

the missing link is how to define $imageResource from .Get "src"?

{{ $imageResource := ($.Site.GetPage "/uploads").Resources.GetMatch (strings.TrimPrefix "/uploads/" . ) }}
{{ $desktop := $imageResource.Fill "1200x800 Center" }}
{{ $tablet := $imageResource.Fill "726x402 Center" }}
{{ $mobile := $imageResource.Fill "458x254 Center" }}

<figure class="image-caption">
<img data-sizes="auto" class="lazyload"
     data-srcset={{ ? }} 458w,
                 {{ ? }} 762w,
                 {{ ? }} 1200w />
<figcaption>{{ if isset .Params "title" }}
        <h5>{{ .Get "title" }}</h5>{{ end }}
    </figcaption>
</figure>

thank you


#2

You can use the parameter position (from zero up) or a named parameter.

{{< imag "param" >}}

$imageResource := (.Get 0).Resources.GetMatch 

If you want to use named params call it this way

{{< imag src="param" >}}

$imageResource := (.Get "src").Resources.GetMatch 

#3

I tried this

<figure class="image-caption">
    {{ with .Get "link"}}<a href="{{.}}">{{ end }}
        <img data-sizes="auto" class="lazyload" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}"{{ end }}
         <!-- image processsing -->
        {{ $imageResource := (.Get "src").Resources.GetMatch (strings.TrimPrefix "/uploads/" . ) }} 
        {{ $desktop := $imageResource.Fill "200x200 Center" }}
        data-srcset="{{ $desktop.RelPermalink }}" />
    {{ if .Get "link"}}</a>{{ end }}
    {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
    <figcaption>{{ if isset .Params "title" }}
        <h5>{{ .Get "title" }}</h5>{{ end }}
        {{ if or (.Get "caption") (.Get "attr")}}<p>
        {{ .Get "caption" }}
        {{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
            {{ .Get "attr" }}
        {{ if .Get "attrlink"}}</a> {{ end }}
        </p> {{ end }}
    </figcaption>
    {{ end }}
</figure>

then call the image inside content with {{< image src="takoyaki.jpg" title="Takoyaki" >}} and the errors still the same

ERROR 2018/12/04 17:58:03 "E:\YUDY\WEB PROJECT\TIAVI\sites\newdev\content\culinary\recipe\ini-loh-cara-membuat-takoyaki-yang-lezat-dan-praktis\index.md:64:1": failed to render shortcode "image": "E:\YUDY\WEB PROJECT\TIAVI\sites\newdev\themes\gogirl\layouts\shortcodes\image.html:4:35": execute of template failed: template: shortcodes/image.html:4:35: executing "shortcodes/image.html" at <"src">: can't evaluate field Resources in type string

#4

This gives you a string! .Resources is a Page function.
Build a string for GetMatch with your parameter

{{ printf "/uploads/%s" (.Get "src) }}
..  .Resources.GetMatch $file ...

(this is quick and dirty)

Sorry the error was in my text above


#5

Ok it seems more difficult than I thought :sweat_smile:

if you don’t mind can you give me more detail code, let me simplified the shortcode

<figure class="image-caption">
    {{ with .Get "link"}}<a href="{{.}}">{{ end }}
        <img data-sizes="auto" class="lazyload"
        data-srcset="/uploads/{{ .Get "src" }}" />
    <figcaption>{{ if isset .Params "title" }}
        <h5>{{ .Get "title" }}</h5>{{ end }}
    </figcaption>
</figure>

so how t implemented {{ printf "/uploads/%s" (.Get "src) }} .. .Resources.GetMatch $file ...

thanks for your patience


#6

looks good, little chages

<figure class="image-caption">
    {{ with .Get "link"}}<a href="{{.}}">{{ end }}
        <img data-sizes="auto" class="lazyload"
        src="/uploads/{{ .Get "src" }}" />
	{{with .Get "title" }}<figcaption><h5>{{.}}</h5></figcaption>{{ end }}
</figure>

I tryed this with this shortcode picture.html

{{< picture src="fl1.png"  link="/" title="title">}}

You have to put the pictures to /static/uploads !


#7

This topic is about image processing which does not work from /static.


#8

right, I only tryed to get the last shortcode working


#9

Sorry guys please excuse any mistakes, just to make a little bit more clear I edit the question


#10

another experiment borrow from Image processing

<figure class="image-caption">
        <img data-sizes="auto" class="lazyload"
        {{ $imageResource := .Page.Resources.GetMatch (printf "*/uploads/%s*" (.Get "src")) }}
        {{ $mobile := $imageResource.Fill "458x254 Center" }} <!-- i assume this part is the source of the error -->
        data-srcset="{{ .Get "src" }}" />
    <figcaption>{{ if isset .Params "title" }}
        <h5>{{ .Get "title" }}</h5>{{ end }}
    </figcaption>
</figure>

output error

"E:\YUDY\WEB PROJECT\TIAVI\sites\newdev\content\culinary\recipe\ini-loh-cara-membuat-takoyaki-yang-lezat-dan-praktis\index.md:64:1": failed to render shortcode "image": "E:\YUDY\WEB PROJECT\TIAVI\sites\newdev\themes\gogirl\layouts\shortcodes\image.html:5:36": execute of template failed: template: shortcodes/image.html:5:36: executing "shortcodes/image.html" at <$imageResource.Fill>: can't evaluate field Fill in type resource.Resource

#11

Hey, so:

  • You were never setting the src attribute for your <img>
  • The Forestry article you linked is cool, but they have one thing wrong. In order for content/uploads/_index.md to be headless, it must be a leaf bundle. So change _index.md to index.md
  • I’m also not sure how the .GetMatch example they gave is working

With all that said, give content structure like this:

content/
└── uploads
    ├── index.md
    └── some-img.png

And shortcode usage like this:

{{< recipe src="some-img" title="some title" >}}

Then this definition should work:

{{ $src := .Get "src" }}
{{ $title := .Get "title" }}

{{ $uploads := $.Site.GetPage "section" "uploads" }}
{{ $match := printf "*%s*" $src }}

{{ $imageResource := $uploads.Resources.GetMatch $match }}
{{ $mobile := $imageResource.Fill "458x254 Center" }}

<figure class="image-caption">
  <img 
  data-sizes="auto" 
  class="lazyload" 
  src="{{ $mobile.RelPermalink }}" 
  data-srcset="{{ $mobile }}" />
  
  <figcaption>
    {{ if isset .Params "title" }}
      <h5>{{ $title }}</h5>
    {{ end }}
  </figcaption>
</figure>

#12

Looks similar to my solution - the younger are faster :wink:

Please read


#13

You are right somehow I already change it to index.md

haha silly me, anyway I make a little change and this is my final shortcode

{{ $src := .Get "data-src" }}
{{ $title := .Get "title" }}
{{ $caption := .Get "caption" }}
{{ $link := .Get "link" }}
{{ $alt := .Get "alt" }}
{{ $rel := .Get "rel" }}
{{ $target := .Get "target" }}

{{ $uploads := $.Site.GetPage "section" "uploads" }}
{{ $match := printf "*%s*" $src }}


{{ $imageResource := $uploads.Resources.GetMatch $match }}
{{ $large := $imageResource.Resize "858x q50" }}
{{ $medium := $imageResource.Resize "720x q50" }}
{{ $small := $imageResource.Resize "520x q50" }}
{{ $extraSmall := $imageResource.Resize "320x q50" }}

<figure class="image-caption">
    {{ with $link }}<a href="{{.}}" rel="{{ $rel }}" target="{{ $target }}">{{ end }}
    <img
        {{ if $alt }}
            alt="{{ $alt }}"
        {{ end }} 
        data-sizes="auto" 
        class="lazyload" 
        data-src="{{ $large.RelPermalink }}" 
        data-srcset="
        {{ $large.RelPermalink }} 800w,
        {{ $medium.RelPermalink }} 700w,
        {{ $small.RelPermalink }} 500w,
        {{ $extraSmall.RelPermalink }} 400w,       
    ">
    {{ if $link }}</a>{{ end }}
  
  <figcaption>
    {{ if $caption }}
        {{ $caption }}
    {{ end }}
  </figcaption>
</figure>

thanks to all of you guys :+1::+1::+1::+1: