Shortcode to generate images with srcset

Hi, I’m trying to get a shortcode to work where it will create a responsive image with the srcset attribute.

So, the shortcode takes in the original image name “hello.jpg” and should output something like:

<img src="hello.jpg" srcset="hello-1080.jpg 1080w, hello-600.jpg 600w, hello-300.jpg 300w" alt=""/>

I would like it to work with other image extensions too, but for now just .jpg is ok.

Here’s what I have so far in image.html shortcode:

{{ $input := index .Params 0 }}
{{ $im := (print $.Page.URL "images/" $input)}}
{{ $image_path := (print "content" $im)}}
{{ with (imageConfig $image_path) }}
{{ $width := .Width }}

<p> {{$image_path}} {{.Width}}
    	{{$im}}
</p>

{{ if ge $width $.Site.Params.maxWidth }}
    	<img src={{$im}} alt=""/>

     		{{ range $index, $elem := $.Site.Params.imageWidths }}
        		{{ replace "hello.jpg" ".jpg" (printf "-%d.jpg %dw" $elem $elem) }}
        	{{end}}
{{ else }}
    	<img src={{$im}} alt=""/>
{{ end }}
{{ end }}

And call from markdown with {{ < image “hello.jpg” > }} where my directory structure is:
└───post
__├───test-post
_____└───images
________└───hello.jpg
__├───another-post
____└───images

In the range function it prints out: hello-1080.jpg 1080w hello-600.jpg 600w hello-300.jpg 300w
But I’m not sure how to get this into the srcset part with the commas, and stuff. I think something like making a slice, then doing delimit would work, but I don’t know how to get the output from range to pass into slice.

Basically I want to make an array where each element is what was printed in the range block, so I can then pass it to delimit to put into the image tag.

Also, just notice that printf “-%d.jpg %dw” replaces the space with %20 instead of an actual space… How do I get it to put a space instead?

Thanks!

Edit: I think I can get rid of the replace command by making a folder for each image size inside the images folder for that post. So each resized image would go into its corresponding folder like 1080, or 600. This would also make it work with other file extensions.

1 Like

Ok, I got something to work with this:

{{ $input := index .Params 0 }}{{ $img_folder := (print $.Page.URL "images/")}}{{ $img := (print $.Page.URL "images/"   $input)}}{{ $image_path := (print "content" $img)}}{{ with (imageConfig $image_path) }}{{ $width := .Width }}
{{ if ge $width $.Site.Params.maxWidth }}
 	<a href={{$img}}><img src={{$img}} srcset="{{$img_folder}}{{$.Site.Params.maxWidth}}/{{$input}} {{(printf "%dw"            $.Site.Params.maxWidth)}}
        	{{ range $index, $elem := $.Site.Params.imageWidths }},{{$img_folder}}{{$elem}}/{{$input}} {{(printf "%dw" $elem)}}
	        {{end}}" alt=""/></a>
{{ else }}<img src={{$img}} alt=""/>{{ end }}{{ end }}

Sorry for the weired formatting, but this way it takes out a bunch of whitespace from the generated html.

4 Likes

Pro tip: control whitespace with a hyphen inside an action delimiter.

2 Likes