Getting specific data in a range

Hello guys,

I’m running a website where we use affiliate partners to monetise. I would like to store reusable (description, logo++) information regarding these affiliates in data files (data/affiliates/“affiliateName”.yaml). Then when I want to list this affiliate partner as a store in my posts I would like to echo that information by calling the parameter affiliateName to get the reusable information, in addition I’d like to be able to supply a custom link to the affiliate partner to the specific product (affiliateLink).

I’m having troubles getting this up and running. This is what I have so far:
“affiliateName”.yaml-template:

name: "Affiliate Partner"
logo: "/images/logos/affiliatePartner.svg"

In an applicable post:

affiliates:
- affiliateName: "AffiliatePartner"
  affiliateLink: "#"
- affiliateName: "AffiliatePartner 2"
  affiliateLink: "#"

I’ve understood that I need to use .Site.Data.,index and range.

After trawling the docs and playing around I have tried this, but it’s not working as intended.

{{ range .Params.affiliates }}
{{ (index $.Site.Data.affiliates .Params.affiliates.affiliateName).name }}
{{ (index $.Site.Data.affiliates .Params.affiliates.affiliateName).logo }}
{{.affiliateLink}}
{{end}}

The below is not an answer specific to your example, but I recently worked on something like that …

See if this helps:

1 Like

Seems your range is misconstructed, see:

{{ range .Params.affiliates }}
   {{ (index $.Site.Data.affiliates .affiliateName).name }}
   {{ (index $.Site.Data.affiliates .affiliateName).logo }}
   {{.affiliateLink}}
{{end}}

Isn’t .affiliateName a child of .affiliates, and therefore I need to call it like I did in my code?

It is. However, range redefines the current . (context). Meaning that the dot that used to be your page (usually) now is the item you’re ranging over. See Introduction to hugo templating about iterations.

So in this case, inside your range, . designates a child of .Params.affiliates, and therefore the affiliateName key is accessed with .affiliateName. That’s also why you need to use $.Site.Data, because .Site.Data does not exist anymore in your range context.

You could also use a variable name as the affiliate, instead of the dot context:

{{ range $affiliate := .Params.affiliates }}
  {{ (index $.Site.Data.affiliates $affiliate.affiliateName).name }}
  ...
1 Like

I see.

Okay, I’m getting this error now though:
Building sites … ERROR 2018/04/22 17:23:55 Error while rendering "page" in "concursos/": template: /Users/olafg/Development/proximo-concurso/layouts/single.html:57:16: executing "main" at <.Params.affiliates>: range can't iterate over estrategia

estrategia is the name of the affiliate partner.

Trying to revive this. I’m wondering whether I can do this with leaf bundles and if someone can point me in the correct direction?

If what you mean is creating a Leaf Bundle for each of your affiliate containing a markdown file and a logo file and then assign them to your pages…

Then you should look into Related Content

If you go this path though, note that you should make your affiliates as headless bundles, otherwise Hugo will create HTML pages for them.

Related could work, but they should be specified for each post, not automatic and the link is usually unique per post (a so-called deep link).

I was just thinking whether headless bundles might be a better idea rather than data files. I still wasn’t able to solve with data files and the suggestions posted above, though.

I’m not sure I fully understand the goal here, as well as the architecture of your project, do you have an repo handy by any chance?

The repo is here:
https://bitbucket.org/olafghanizadeh/proximo-concurso/src/affiliate-listings/

It does require gulp/node.js/npm to run because of the asset compilation. I’m looking to move most of it over to the Hugo native asset processing though.

The case is explained above, but I’m thinking that headless pages might be a better option than Data files for what I am trying to achieve.

I would indeed use headless pages and then retrieve them using a Front Matter param and .GetPage. This way you can benefit from Page Resources, image processing etc…

Yes, that is why I started looking into headless pages for this.

But after reading more about it seems that I can’t iterate and display several headless pages attached on a single page?

Yeah so for now, there is no easy way to range on headless pages… But you it’s still possible.

I would use readDir on the directory your headless pages live in.

Then you can range on those file and use their .Path or maybe .Dir + .Basename, not sure) as parameter to .GetPage

This is the only way I can think of, as of today, to range over headless pages.

1 Like

Hm, this is slightly complicated yeah. :confused: