Loop through images and append baseurl if no http

Hi - I am struggling with range and wondering if someone would kindly point me in the right direction.

I have frontmatter like this:

- /img/one.png
- http://othersite.com/images/some.jpg
- /img/two.jpg

And a partial like this:

<script type="application/ld+json">
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "image" : [ {{ range $i, $e := .Params.images }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} ]

This code works, but returns a list of images “as is”. I’d like to test to see if they don’t contain http, and if not, append the baseurl.

On @bep’s bepsays repo, there’s this technique:

{{ $baseurl := .Site.BaseURL }}
{{ with .Params.images }}{{ range first 6 . }}<meta property="og:image" content="{{ if in . "http" }}{{ . }}{{ else }}{{ $baseurl }}{{ . }}{{ end }}" />
{{ end }}

… but combining them is proving to be a challenge. I tried to include {{ if in $i "http" }}{{ $i }}{{ else }}{{ $baseurl }}{{ $i }}{{ end }} but it makes a mess, with index numbers flying all over.

Humble request for assistance… thanks.

I have the most elegant solution for you … after I get myself a cup of coffee …

  1. Pull and build the latest Hugo
  2. Use this construction:
<script type="application/ld+json">
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "image" : {{ apply .Params.images "absURL" "." }}

Wow, what is this magical absURL! It fills in the blank if there’s no http:// or https:// with the domain?

I’ll do this right away tomorrow; thanks @bjornerik!

There are 3 interesting things with the construction above:

  1. absURL uses the baseURL setting and makes the URL absolute if not already
  2. The apply func creates a new slice with absURL applied to all the items.
  3. The Go template parser JSON encodes all non-string object inside <script>

(the last one can be a major gotcha!)

Thanks again @bjornerik. I tried updating using brew, but, it did not work well, so, I took the previous advice of installing via go get, which I had not tried yet. Had to set a couple of variables in my .zshrc, but once I set the $GOPATH and put $GOPATH/bin in my system path, it ran just fine.

However, now I get many errors on the console like this one:

ERROR: 2015/05/11 template: partials/seo-schema.html:130:46: executing "partials/seo-schema.html" at <$.Site.Params.ISO860...>: invalid value; expected string in partials/seo-schema.html

It appears to be choking on these lines:

"datePublished": "{{ .PublishDate.Format $.Site.Params.ISO8601 }}",
"dateModified" : "{{ .Date.Format $.Site.Params.ISO8601 }}",

That’s in my config.toml as:

ISO8601 = "2006-01-02T15:04:05JST"

Is this a manifestation of the problem you mentioned, in number 3 above? I have not even got to your code example, yet, I’m afraid.

Is it going to be no longer possible to do this kind of technique?

Pretty late in Japan now so I will crash. But I appreciate your good help.


Hugo version:

 Hugo Static Site Generator v0.14-DEV BuildDate: 2015-05-11T21:59:26+09:00

There is nothing in the latest Hugo comits that should change any of this … but those date format constructions (my guess builtins), looks funky … Will have a look at it later. Norway is on early evening time …

Hmmm… mystery, looks like it doesn’t like ISO8601 as key (it works if you change it to foo or similar) … but that has worked before, and is in use by many…

Will check if the TOML package has changed.

Do a go get (maybe add a -u) and you should get a working version.

I rolled back a breaking commit. The commit was correct enough, but we have to figure a way to do it without mayhem.

Thanks for all this @bjornerik. Haha, before I saw your last post about the rollback, this AM I was experimenting around trying to document some observations and hopefully fix the problem.

I tried changing the config.toml variable name to ISOEIGHTSIXOHONE to see if having the numbers in it made a difference. It didn’t (with the original breaking commit). Then I switched the code in my templates to have the date format entered directly like "2006-01-02T15:04:05JST". That worked & no errors on the console. Then I tried the new function in "image" : {{ apply .Params.images "absURL" "." }}, and it worked, so long as I had the date formats in directly.

Then I saw your post about the rollback, so, I did a go get -u github.com/spf13/hugo, put the date formats back to using the variable from config.toml, and yes, I confirm it works.

Thanks for your work. It’s a really nice new feature that makes it easy to address the situation I had been trying to rectify.

I am sure you’re tired. :slight_smile:

@bep hi, I wonder if you could answer this. If I have a data file general.yaml that has:

 - /img/someimage.jpg
 - /img/anotherimage.jpg

And when I try something like:

"image" : {{ apply $.Site.Data.general.images "absURL" "." }}

… for a Node, I get an error.

ERROR: 2015/05/29 template: partials/seo-schema.html:22:17: executing "partials/seo-schema.html" at <apply $.Site.Data.ge...>: error calling apply: called apply using interface {} as type string in partials/seo-schema.html

This however works:

"image" : [ {{ range $i, $e := $.Site.Data.general.images }}{{ if $i }}, {{ end }}{{ $e | absURL }}{{ end }} ]

I’m just wondering why the original construction you taught me does not work for a data file. Just trying to wrap my head around it.

Have no idea … Probably a subtle YAML issue. Do you always have more than one image in that list?

I was trying to mimic the image array I had in posts, for a page like the home page, by supplying a generic list of images for the site, in a data file. I’ll try some other formats.