Range over the children of a Shortcode

The shortcode I am building is meant to display a component with two or four items.

For example:

{{< content-highlight >}}
    {{< item title="1" subtitle="" image="placekitten.com/300" >}}
    {{< item title="2" subtitle="" image="placekitten.com/300" >}} 
    {{< item title="3" subtitle="" image="placekitten.com/300" >}}
    {{< item title="4" subtitle="" image="placekitten.com/300" >}}
{{< /content-highlight >}}

Is there a way I can range over the items?

Hi @brunoamaral

Have a look at the Nested Shortcode: Image Gallery, example:

In that example, the nested shortcode is fetching a variable from the parent. Here, I need to know how many children exist and what variables they are passing.

No, you cannot range over the contents of .Inner out-of-the-box in Nested shortcodes .

Can you explain a bit more about what you’re trying to do?

There may be another way.

The end result will be the image below.

Another option wouls be to create a shortcode for each of the four sections, but I think the example I showed with nested shortcodes could be cleaner.

Right. There are two ways you can go about it:

  1. Inline Shorcode with Nested Partial in which you range over the .Page.Resources provided that you organize the content in Page Bundles.

  2. Splitting the rendered .Inner content of the Nested Shortcode that you already have based on its newlines and then ranging over the rendered images.

It’s up to you which approach you want to follow.

The first requires re-organizing the content, enabling Inline Shortcodes, but offers the possibility of the full template power from within the content file and it scales nicely.

The second respects your current project structure and shortcodes but I am not sure how it will scale.

Since this topic is about Ranging over the children of a Nested Shortcode (and that is why I added the word Nested in the topic title) I will offer a way to do just that:

In content-highlight.html

{{- with .Inner -}}{{- $inner := split . "\n" -}}{{- range $i, $e := $inner -}}{{ $img := . }}{{ if eq $i 5 }}<--- copy to be rendered after the 4th img -->{{- end -}}{{ $img | safeHTML -}}{{ end }}
{{- end -}}

In the above the .Inner contents are splitted by \n newline.
The rest is self explanatory.
In the shortcode template, everything needs to be in one line to avoid redundant newlines that will complicate things.

1 Like

This starting to look very much like plain HTML, so you are not getting much savings in time/effort when writing the content.
Just to offer an alternative, the shortcode could be designed to accept one argument like this:

{{< content-highlight  "img1.jpg img2.jpg img3.jpg" />}}

On the shortcode side, you can detect how many images where called with len ( split (.Get 0) " ") (I think, but untested).

I guess that if you need titles and subtitles you can add other optional parameters.

Sorry for not answering the question directly.

1 Like

clearly this was never a straightforward question given the limitations :slightly_smiling_face:

Thank you both for your help, I will be testing both approaches and see which works best for this case.