Design

Loop over array

Repeat any part of you document
COMMUNITY FEATURE Available for:
Carbone Cloud
Carbone On-premise
Embedded Carbone JS
  v2.0+ 

Overview

Carbone can repeat any part of a document (rows, titles, pages...).

Just write where the i-th and i-th+1 rows are and Carbone will automatically find the pattern to repeat, using the first row i-th as an example.

The second line (i+1) will be removed before rendering the result.

Only one [i+1] tag is enough to find the repetition pattern. It is not necessary to repeat the whole [i+1] part.

Simple array

In this example, we want to travel an array of cars.

data
{
  "cars" : [
    {"brand" : "Toyota" , "id" : 1 },
    {"brand" : "Hyundai", "id" : 2 },
    {"brand" : "BMW"    , "id" : 3 },
    {"brand" : "Peugeot", "id" : 4 }
  ]
}
template
Carsid{d.cars[i].brand}{d.cars[i].id}{d.cars[i+1].brand}
Carbone Merge Icon
result
CarsidToyota1Hyundai2BMW3Peugeot4

Nested arrays

Carbone manages nested arrays (unlimited depth). Here is an example where a whole portion of a document is repeated.

data
[
  {
    "brand": "Toyota",
    "models": [{ "size": "Prius 4", "power": 125 }, { "size": "Prius 5", "power": 139  }]
  },
  {
    "brand": "Kia",
    "models": [{ "size": "EV4", "power": 450  }, { "size": "EV6", "power": 500  }]
  }
]
template
{d[i].brand}Models{d[i].models[i].size} - {d[i].models[i].power}{d[i].models[i+1].size}{d[i+1].brand}
Carbone Merge Icon
result
ToyotaModelsPrius 4 - 125Prius 5 - 139KiaModelsEV4 - 450EV6 - 500

As you can see, it is useless to repeat the first paragraph twice in the template, only the title of the second paragraph is necessary to help Carbone recognize where the repetition pattern of the main array {d.cars[i+1].brand} ends.

Bi-directional loop

v4.8.0+

The bidirectional loop performs iterations in 2 directions, creating additional columns and rows.

There are a few restrictions:

Here is a real life example of a bidirectional loop.

data
{
  "titles" : [{ "name": "Kia" }, { "name": "Toyota" }, { "name": "Hopium" }],
  "cars"   : [
    { "models" : [ "EV3", "Prius 1", "Prototype" ] },
    { "models" : [ "EV4", "Prius 2", "" ]          },
    { "models" : [ "EV6", "Prius 3", "" ]          }
  ]
}
template
{d.titles[i].name}{d.titles[i+1].name}{d.cars[i].models[i]}{d.cars[i].models[i+1]}{d.cars[i+1].models[i]}
Carbone Merge Icon
result
KiaToyotaHopiumEV3Prius 1PrototypeEV4Prius 2EV6Prius 3

Access the loop iterator value

v4.0.0+

Access the iterator value when a list is printed in a document. For example: {d[i].cars[i].other.wheels[i].tire.subObject:add(.i):add(..i):add(...i)}

The number of dots corresponds to the position of the i in the hierarchy:

The number of dots is currently inverted. It should be ...i for d[i] and .i for wheels[i]. This is a known bug. However, many users rely on the current behavior, and fixing it would break some reports. We plan to address this issue in the future while ensuring backward compatibility.

Parallel loop

Iterate through two separate arrays at the same time using the same iterator variable.

As seen earlier, the iterator i can be used in formatters.
By combining it with relative path access, we can navigate back in the JSON hierarchy using two dots (..).
This allows us to print the content of another array, brands, using the same iterator as the cars array.

data
{
  "cars" : [
    { "id" : 1 },
    { "id" : 2 },
    { "id" : 3 },
    { "id" : 4 }
  ],
  "brands" : [
    { "name" : "Toyota" },
    { "name" : "Hyundai"},
    { "name" : "BMW"    }
  ]
}
template
Carsid{d.cars[i].id}{d.cars[i].id:print(..brands[.i].name)}{d.cars[i+1].id}
Carbone Merge Icon
result
Carsid1Toyota2Hyundai3BMW4