Clone Section scripts
This topic describes the basic Clone Section script and explains how to enhance it.
Rather than starting from scratch, we recommend using the script generated by the Section Clone wizard as a starting point. (See: Cloning sections.) The same script is described in this topic. If the script created by the wizard doesn't do everything you need, it's still a good place to start.
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.
The Clone Section script
Here is an example of a Clone Section script created by the wizard.
var section = merge.template.contexts.PRINT.sections["Section 1"];
if (!section) {
fatalError("Section 'Section 1' not found");
}
var table = record.tables["products"];
if (table) {
for (let detail of table) {
let clone = section.clone();
clone.meta["detail-table"] = "products";
clone.meta["detail-table-record"] = detail.index;
clone.meta["detail-record-as-scope"] = true;
section.addAfter(clone);
}
section.enabled = false;
}
First, the script retrieves a section - in this case: Section 1 - from the merge object and stores it in a variable called 'section'.
If the section does not exist, an error is thrown. See: fatalError(message).
Then the script retrieves a detail table from the record, by name. In this example the name of the detail table is products.
If the detail table exists, the script loops over the records in the detail table with for ( .. of .. )
, creating a clone for each of them using the clone() function, and filling the meta
property of the clone with some data (see meta entries in section clones).
Then it adds the clone to the Print context using the addAfter()
function.
At the end of the loop it disables the original section.
Note: 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.
meta
entries in section clones
The Clone Section wizard inserts the following fields into the meta
property of each clone:
-
detail-table - Name of the detail table
-
detail-table-record - The index of the clone's record in the detail table (zero based)
-
detail-record-as-scope - The data scope for Handlebars expressions: the detail table (true) or main record (false)
meta
entries are accessible in Standard Scripts as well as in Handlebars expressions.
Writing and reading entries in the meta property
If many scripts need to have access to the same detail table field, it may be worth the effort to add that data field to the meta
property within the Clone Section script.
Like other meta
entries, these custom entries can be read in a Standard Script.
For example, assume the detail table that clones are based on has a data field called 'title'. With one additional line of code in the standard Clone Section script, this field can be written to the meta property of each clone, in a new entry 'title'.
Example: clone.meta["title"] = detail.title;
This line should go inside the loop in which clones are created.
The new meta entry 'title' is now available in Standard Scripts. For example, the following script, with a selector of h1
, replaces the text of h1 headings with the current value of the 'title' detail table field.
Example: let theTitle = merge.section.meta["title"]
results.text(theTitle)
Since meta
entries can have any type, it would even be possible to write an entire detail table record into the meta
property.
Tip: In section clones, detail table fields are most easily accessed through a Handlebars expression. See Handlebars expressions in section clones.
Assigning a background PDF to a section clone
Section clones automatically get the same background image as the original section. If each section clone needs a different background image, this is easily set in the section clone wizard.
However, the Clone Section wizard expects the path to a background PDF to be specified in the detail table record the clone is based on. If there is no such field in the data, you may click the Expand button in the wizard and modify the script to construct the URL in code.
The following script constructs the path to a PDF for each clone using the contents of a data field.
var section = merge.template.contexts.PRINT.sections["Policy"];
if (!section) {
fatalError("Section 'Invoice' not found");
}
var table = record.tables["policies"];
if (table) {
for (let detail of table) {
let resourceUrl = 'images/policy-' + detail.fields["Name"]; + '.pdf';
let clone = section.clone();
clone.meta["detail-table"] = "policies";
clone.meta["detail-table-record"] = detail.index;
clone.meta["detail-record-as-scope"] = true;
clone.background.source = BackgroundResource.RESOURCE_IMAGE;
clone.background.url = resourceUrl;
clone.background.position = MediaPosition.CENTERED;
section.addAfter(clone);
}
section.enabled = false;
}
For information about the properties used to set a section's background, see Control Script: Setting a Print section's background.
Renaming a clone
By default, clones have the same name as their source section with an index in round brackets.
Example: Source: "Section 1"
Clone names: "Section 1 (1)", "Section 1 (2)", "Section 1 (3)", ...
Use the name
property to assign another name to the cloned section, for example:
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 can 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.