Generate proper URLs from an array of srcset in front matter

Drawing on Best way to add a space in a URL for use in srcset

I have the same question with the exception that I have my srcset values organised in an array:

 srcset:
    -  /images/mockups/apple-watch-white-mockup.png w200
    -  /images/mockups/apple-watch-white-mockup.png w400

While the accepted answer works fine for me if I delimt the values into a single string

<img class="img-fluid" src="{{.src}}" {{ with .srcset }}{{ printf "srcset=\"%s\"" $srcset | safeHTMLAttr }}{{ end }} alt="{{.alt}}">

I can’t figure out how to how to range through the srcset array without the escaping the spaces. And so yeah that’s where I’m stuck :confused:

Please provide a repo with the front matter values you are using, and a example output you are trying to generate. Also, please review requesting help for more tips on getting help in the forums. :slight_smile:

Hi, I appreciate the help so far!

I’ve created a repo over here: https://github.com/spookyUnknownUser/help/

Would appreciate any thoughts you have.

I work with srcset in my template like so:

layouts/partials/srcset.toml:

{{ if .Page.Params.pageImage.name }}
    {{ $pageimageurl := .Site.Params.imageURL }}
    {{ $pageimage := .Page.Params.pageImage }}

    <picture>
        {{ range .Site.Data.srcset.breakpoint }}
            {{/* NOTE: Inklusive Retina Images (2x) */}}
            <source
                srcset="
                    {{ $pageimageurl }}{{ $pageimage.name }}{{ .suffix }}.jpg,
                    {{ $pageimageurl }}{{ $pageimage.name }}{{ .suffix2 }}.jpg 2x"
                media="({{ .width }}: {{ .media }}em)">
        {{ end }}
        <img
            srcset="{{ $pageimageurl }}{{ $pageimage.name }}-large.jpg"
            alt="{{ $pageimage.alt }}">
    </picture>
{{ end }}

data/srcset.toml:

[[breakpoint]]
media   = 75
width   = "min-width"
suffix  = "-large"
suffix2 = "-large@2"

[[breakpoint]]
media   = 45
width   = "min-width"
suffix  = "-medium"
suffix2 = "-medium@2"

[[breakpoint]]
media   = 20
width   = "min-width"
suffix  = "-small"
suffix2 = "-small@2"

The respective images are generated by gulp with gulp-responsive (not gulp-responsive-images!):

gulp.task('img', ['clean:img'], () =>
  gulp.src(imagesSrc)
    .pipe(responsive({
      '*': [{
        width: small,
        rename: {
          suffix: '-small',
          extname: '.jpg'
        },
      }, {
        width: small * 2,
        rename: {
          suffix: '-small@2',
          extname: '.jpg'
        },
      }, {
        width: medium,
        rename: {
          suffix: '-medium',
          extname: '.jpg'
        },
      }, {
        width: medium * 2,
        rename: {
          suffix: '-medium@2',
          extname: '.jpg'
        },
      }, {
        width: large,
        rename: {
          suffix: '-large',
          extname: '.jpg'
        },
      }, {
        width: large * 2,
        rename: {
          suffix: '-large@2',
          extname: '.jpg'
        },
      }, {
        width: 100,
        rename: {
          suffix: '-thumbnail',
          extname: '.jpg'
        },
      }, {
        width: large,
        rename: {
          suffix: '',
          extname: '.jpg'
        },
      }],
    }, {
      // Global configuration for all images
      // The output quality for JPEG, WebP and TIFF output formats
      quality: 70,
      // Use progressive (interlace) scan for JPEG and PNG output
      progressive: true,
      // Zlib compression level of PNG output format
      compressionLevel: 6,
      // Strip all metadata
      withMetadata: false,
    }))
    .pipe(gulp.dest(imagesDest)
));

Hope this helps, Leo

1 Like

Thank you that’s really helpful, but my real issue is dealing with the space that comes from the filename and the width description, I noticed yours uses the pixel density descriptor so I’m not sure how I would go about doing this with width descriptors which require a space.

I think the most direct way is to create a map inside the array.

srcset:
  - 
    url: /images/mockups/apple-watch-white-mockup.png
    w: 200
    alt:
  - 
    url: /images/mockups/apple-watch-white-mockup.png 
    w: 400
    alt: 
{{ range .Params.srcset }}
<img class="img-fluid" src="{{ .url }}" {{ .w }} alt="{{.alt}}">
{{ end }}
2 Likes

Oh yeah that would be fine, i’ll try it out!

Thank you to everyone that helped in the thread :heart:

In the end I think I found a happy medium between the answers posted in this thread and the last one.

The reason I didn’t want to delimit my array into a string and then use this solution was because I also needed to use relURL
<img class="img-fluid" src="{{.src}}" {{ with .srcset }}{{ printf "srcset=\"%s\"" $srcset | safeHTMLAttr }}{{ end }} alt="{{.alt}}">

So what I ended up doing was instead of using delimit to turn the array into a string - I just stored them in a Scratch and then printed the combined string just like in the original answer. Together that looks like:

     <!--                Scratchpad               -->
    <h1 class="f3 moon-gray">Also working image</h1>
      {{range $srcset}}
        {{$.Page.Scratch.Add "srcset" (print ( . | relURL) "," ) }}
      {{end}}
      <img 
      src="/images/picture-1800.png" 
      {{ printf "srcset=\"%s\"" ($.Page.Scratch.Get "srcset") | safeHTMLAttr}}>

And this works fine. I’ve commited this to the repo so the whole site should build correctly now.

1 Like