Dynamically adding sections (cloning)

This topic explains how to "clone" (copy) a section in a Control Script. Print sections can be cloned, so that a document can have a dynamic number of sections, based on data. This is particularly useful when the record set defines one or more PDFs (e.g. insurance policies) per recipient. Via a Control Script, for each PDF a section can be cloned and each clone can be given one of the PDFs as background (see Control Script: Setting a Print section's background). For each page in the PDF, a page will be added to the section.

For information about Control Scripts in general, see Control Scripts and Control Script API. If you don't know how to write scripts, see Writing your own scripts.

Note: Clones are only visible in the output, not on the Preview tab.

Cloning a section

To clone a section, first use the clone() function and then add the clone to the Print context before or after a specific section, using addAfter() or addBefore():

Copy
var printSections = merge.template.contexts.PRINT.sections;
var clone = printSections["Section 1"].clone();
printSections["Section 1"].addAfter(clone);

Cloned sections have the same properties as normal sections (see section), but they cannot call the section functions clone(), addBefore() and addAfter(), which means you cannot clone a clone, or use a clone as a starting point to insert other clones into a template.

Note that with multiple clones, the next clone is always added after the previous clone.
With addBefore(), the code original.addBefore(clone1); original.addBefore(clone2); will result in "clone1, clone2, original".

With addAfter() the code original.addAfter(clone1); original.addAfter(clone2); results in "original, clone1, clone2".

Renaming a clone

By default, clones receive the name of their source section with a "Clone {unique identifier}" suffix, for example:
Source: "Section 1"
Clone Name: "Section 1 Clone 71c3e414-fdf3-11e8-8eb2-f2801f1b9fd1"

Use the name property to assign another name to the cloned section, for example:

Copy
clone.name = "my_section_clone";

Just like section names, the clone's name should be unique - within the scope of a single record, that is; across records, the same name can be used.
When two clones get the same name in the same record, one of the clones may no longer be used. This is prevented by giving clones unique names. Unique names also ensure that CSS rules and scripts can target a specific clone.

Targeting elements in a cloned section

Clones that have a unique name can be further personalized with the use of CSS style sheets (see Styling and formatting) and personalization scripts (see Personalizing content and Writing your own scripts).
The selector to use is: [section="name of the clone"].

The following CSS style rules target the <h1> element in a number of clones and assign the respective text a different color:

Copy
[section="my_section_clone_0"] h1 { color: red; }
[section="my_section_clone_1"] h1 { color: green; }
[section="my_section_clone_2"] h1 { color: blue; }

The same selector could be used in personalization scripts:

Selector: [section="my_section_clone_0"] h1
Script: results.css('color','red');

Inside a Standard Script, cloned sections can be found using merge.section:

Copy
if (merge.section == "my_section_clone_0") {    
    results.html("Clone!");
} else {    
    results.html("Original.");
}

Note that in a Control Script, merge.section is only defined when the output channel is WEB; see merge.

Examples

Cloning a section based on the number of records in a detail table

This script creates as many clones of a section as there are records in a detail table. It assigns the new sections a unique name.

Copy
var printSections = merge.template.contexts.PRINT.sections;
var numClones = record.tables['detail'].length;
for( var i = 0; i < numClones; i++){
    var clone = printSections["Section 1"].clone();
    clone.name = "my_section_clone_" + i;
    printSections["Section 1"].addAfter(clone);
}

Cloning a section based on data and assigning a background PDF

This script clones a section based on data fields. It disables the source section first and then calls the addPolicy function. addPolicy clones the section, renames it and sets a PDF from the resources as its background. It explicitly enables the clone and then adds it to the Print context.

Copy
var printSections = merge.template.contexts.PRINT.sections;
merge.template.contexts.PRINT.sections["Policy"].enabled = false;
if(record.fields.policy_a == 1) {
    addPolicy('a');
}
if(record.fields.policy_b == 1) {
    addPolicy('b');
}
function addPolicy(policy){
    var resourceUrl = 'images/policy-' + policy + '.pdf';
    var clone = printSections["Policy"].clone();
    clone.name = "policy_" + policy;
    clone.background.url = resourceUrl;
    clone.enabled = true;
    printSections["Policy"].addAfter(clone);
}