How to change an object inside 2 {{ ranges }}

[EDIT]
Change my original question to this:

How to change an array of objects inside 2 {{ range }} scopes:

$array:=
 -  title: title1
    url: url1
    class: class1
 -  title: title2
    url: url2
    class: class2

{{ range $range1 }}
    {{ range $array }}
    // Modify array of objects
    {{ end }}
{{ end }}

{{ $array }} // Get the modified array of objects

I’m not able to do this due to scope issues

PS: Need to be {{ range }}, because the size of both arrays are variable

Thanks!

[ORIGINAL QUESTION]

Hi!

I need to replace some text in all fields from .Params

First I tried loop in every variable, but due to scope issues it is impossible

Now I got the idea to transform .Params in a JSON and put in a variable (ex: {{ $json := .Params | jsonify }})

Now I want to do the reverse so I may access all the information again

(something like: {{ $object := $json | objectify }})

Is it possible?

Thanks for the help!

Last time I had a problem like that, I ended up using find-and-replace across my content files. Isn’t that an option?

Can you provide an example of what you are trying to do?

Opa temos outro brasileiro aqui :smile:

It’s quite simple actually:

There are 2 groups of files, all generated by my end user:

  1. Templates:

These files have “body” text for landing page, with placeholder for variables, like this:

hero-title: Won US$ {{money}} working on {{city}}!

  1. Value files:

These files are a library of key-values to populate the landing pages:

File 1
    variables:
      - key: city 
        value: "Atlanta"
      - key: money 
        value: 100.00

File 2
    variables:
      - key: city 
        value: "L.A."
      - key: money 
        value: 120.00

Every values file will render a different landing page, so my end user may create different landing pages, with different values, but with the same context.

This will only work If I iterate the template .Params values (all of them) and find and replace for value files arguments.

The problem that I have, is that in the template file, my user may create an array of objects, like this:

buttons:
 -  title: title1
    url: url1
    class: class1
 -  title: title2
    url: url2
    class: class2

And I’m having Scope issues to track all the buttons:

Here is my code

// I tried creating a Scratch for keep the context, but I can't ".Set" or ".Get" the values of the array

{{ $body := newScratch }}

// Everything is ok with the "predictable"part of the template

{{ $body.Set "title" .title }}
{{ $body.Set "description" .description }}

// Here is the problema, buttons is an array of objects

{{ $body.Set "buttons" .buttons }}

{{ range .args.variables }}

// For every key/value, I will replace in the text

    {{ $replaceText := delimit (slice "{{" .key "}}") "" }}

// For the predictable part, works all fine

    {{ $title := replace ($body.Get "title") $replaceText .value }}
    {{ $body.Set "title" $title }}

    {{ $description := replace ($body.Get "description") $replaceText .value }}
    {{ $body.Set "description" $description }}


// Here is the problem: there's a new scope when I enter range, and I can't create an array of objects with the values that I need

    {{ range $index, $button := $body.Get "buttons" }}

    ???? mysterious code enters here

    // What I need is the "for loop" to create a new array of objects, as the previous, but with the key/values replaced 
     
    {{ end }}

{{ end }}

<div class="hero">
    <div class="hero__content">

// This works fine

        <h1>{{ $body.Get "title" | safeHTML }}</h1>
        <p class="hero__description">
            {{ $body.Get "description" | safeHTML}}
        </p>
        <div class="hero__button-group">

// This don't

        {{ range $index, $button := $body.Get "buttons" }}

        I DON'T KNOW WHAT TO PUT HERE
        
        <a class='hero__button{{ $body.Get "buttonClass" }}' href='{{ $body.Get "buttonUrl" }}'>{{ $body.Get "buttonTitle" }}</a>

        {{ end }}

        </div>
    </div>
</div>

Since I’m having problem with the scope, I think that transforming everything into a giant json file, find/replace the keywords, and after that going back to a object would work

What you guys think?

Thanks!

Then if I understand correctly, as a user I can create a number of buttons in the page and each page is generated from a list of cities.

Your problem is then how to make sure the user doesn’t mess up the context of the buttons and the respective landing pages.

My suggestion, make the user responsible for assigning each button to each context. Like this for example:

buttons:
 -  title: title1
    url: url1
    class: class1
    city: "Lisbon"
 -  title: title2
    url: url2
    class: class2
    city: "São Paulo"

Does that help?

And also, I’m Portuguese :wink:

Actually, both of the informations are in different files, so this would be impossible

What would answer my question:

How to change an array of objects inside 2 {{ range }} scopes:

$array:=
 -  title: title1
    url: url1
    class: class1
 -  title: title2
    url: url2
    class: class2

{{ range $range1 }}
    {{ range $array }}
    // Modify array of objects
    {{ end }}
{{ end }}

{{ $array }} // Get the modified array of objects

I’m not able to do this due to scope issues

PS: Need to be {{ range }}, because the size of both arrays are variable

Thanks!

Also see apply | Hugo