Merge Blocks
How many line items an invoice lists depends on the order, and a template can't know that number in advance. A merge block solves this: it marks a part of the template, often a table row, that ReportingCloud repeats for each element of an array in the data. The sections below show how a block finds its data, how you insert one in the template editor, what happens to blocks without data and how to list the blocks of a stored template.
The samples merge the invoice data of Merge Data, saved as data.json, into sample_invoice.tx, the demo template of every trial account. Its line items are a block named item.
How Merge Blocks Work
A merge block is a named section of a template. During the merge, ReportingCloud looks up the array with the same name in the current record and repeats the block once for each element of that array:
- The name connects block and data. The block
itemof the demo template is filled from the array"item": [...]of each invoice. - Fields inside the block take their values from the current element. The fields
qty,item_descriptionanditem_totalshow the values of one line item in each copy of the block. - Fields outside the block are top-level fields and take their values from the record. In the demo template, the rows with
total_discount,total_sub,total_taxandtotalfollow the block and appear once. - A block is a table row or paragraphs. The template editor inserts a block as a table row, with or without a header row above it, or as plain paragraphs.
The template of Merge Data shows the block item as the highlighted table row between the header row and the totals.
A block can contain other blocks, such as the items of each sale in a sales report, which Nested Blocks describes. A block can also be bound to a single object instead of an array, so that it appears when the object has values and disappears when not, as Conditional Blocks shows.
Provide the Data for a Block
The array of a block holds one object per copy, and the names of the object are the names of the fields inside the block. The following record has three line items, so the item row of the demo template becomes three table rows:
[
{
"invoice_no": "778724",
"billto_name": "Joey Montana",
"item": [
{ "qty": "1", "item_no": "1", "item_description": "Item description 1", "item_total": "2130.40" },
{ "qty": "2", "item_no": "2", "item_description": "Item description 2", "item_total": "11086" },
{ "qty": "1", "item_no": "3", "item_description": "Item description 3", "item_total": "980" }
],
"total": "14196.40"
}
]
Each record of mergeData has its own array. With two invoice records, each invoice lists its own line items, whether the invoices are appended to one document or returned as separate documents.
Insert a Merge Block
You insert blocks in the template editor of the ReportingCloud portal, with a datasource excerpt: sample JSON data with the arrays of your real data, which fills the editor's lists of fields and blocks.
- Open the template in the editor with a datasource excerpt whose data contains the array, as Template Editor describes.
- Place the input position where the block goes and choose the name of the array, such as
item, from the Merge Block drop-down on the Reporting tab. - In the Insert Merge Block dialog, check the fields the block contains and confirm with OK.
Template Editor describes the options of the dialog and the preview of the result. Template Design follows these steps with screenshots for an invoice.
Remove or Keep Empty Blocks
When the array of a block is empty or missing in a record, the block is empty. The removeEmptyBlocks setting decides what happens to its content:
true, the default, removes the content of empty blocks, so an invoice without line items has no empty item row.falsekeeps the content of empty blocks in the document.
The following commands merge an invoice without line items and keep the block:
cat > empty.json <<'EOF'
{
"mergeData": [
{
"invoice_no": "778725",
"billto_name": "Joey Montana",
"item": []
}
],
"mergeSettings": {
"removeEmptyBlocks": false
}
}
EOF
curl POST "https://api.reporting.cloud/v1/document/merge?templateName=sample_invoice.tx&returnFormat=PDF&append=true" \
"Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
"Content-Type: application/json" \
@empty.json \
result.json
jq '.[0]' result.json | base64 > invoice.pdf
Because true is the default, removing a section by sending no values for it needs no setting at all. Conditional Blocks uses this to include sections of a document only when the data calls for them, and Merge Settings lists the other remove settings.
List the Blocks of a Template
The GET /v1/templates/info endpoint returns the blocks of a stored template in mergeBlocks. Each block has a name, its fields in mergeFields and the blocks nested in it in mergeBlocks. The following commands print the blocks of a template with their fields, nested blocks indented:
curl "https://api.reporting.cloud/v1/templates/info?templateName=sample_invoice.tx" \
"Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
info.json
jq 'def blocks($indent):
.mergeBlocks[]? | "\($indent)\(.name): \([.mergeFields[].name] | join(", "))", blocks($indent + " ");
blocks("")' info.json
The jq function blocks prints each block of a level and calls itself for the blocks inside it. For the demo template, it prints item with its fields. The names it prints are the names of the arrays your data needs. Managing Templates shows the complete response.
Next Steps
- Nested Blocks: put blocks inside blocks for data with several levels.
- Conditional Blocks: show or remove sections depending on the data.
- Template Design: insert fields and blocks in the template editor.
- Merge Settings: all settings of a merge with their defaults.