Sharing global configuration and overriding it per template
Several letter templates share the block with enclosures and copies at the end of the letter: the Forms elements and the field for it live in the global configurations and each template only references them. One single template is to pre-fill «Copy to» with a default text, without changing anything in the global entries or in the other templates.
Result
- All letter templates show the fields «Enclosures» and «Copy to» in the Forms dialog and output them in the same block at the end of the letter.
- In one template, «Copy to» is pre-filled with a default text that the user can overwrite.
- The global entries remain unchanged and continue to apply to all other templates.
Global or local
A global entry is XML that is maintained in one place and referenced in the template through a Global… element with a Key. During document creation, primedocs puts the content of the entry in the place of the reference. For access in code and for the duplicate-id check, a globally included element then no longer differs from a locally defined one. Three rules follow from this:
- Code accesses elements by id, not by key.
$("Forms.CopyTo")looks for the Forms element with the idCopyTo, regardless of whether it comes from a global entry or is defined directly in the template. The key of a global entry (Forms.CopyTo= groupForms, entryCopyTo) is a separate name that only looks the same by convention. - Every id and every field name occurs only once in a template. If a template defines a Forms element with the same id as an included global element, validation reports a duplicate id, and in Fields a duplicate field name. Overriding therefore always means replacing or modifying the global reference, not defining the element locally in addition.
- A global entry has exactly one state. Global configurations are not versioned. A change affects every template that references the entry, published templates as well as drafts. No template retains an older state of the entry.
| Situation | Implementation |
|---|---|
| Several templates need the same configuration | global entry, referenced in every template |
| The configuration belongs to exactly one template | locally in the template |
| Several templates share the logic, one deviates in one element | global entry. The deviating template replaces the Forms element (step 4) or modifies the field (variant) |
| Same logic, but with different inputs per template | function as GlobalCode with parameters |
| User-visible texts in several languages | Global Translations |
Building blocks
| Building block | Task in this example | Reference |
|---|---|---|
Global entry Forms.Enclosures (type FormsGlobalElements) | input field «Enclosures», id Enclosures | Forms: GlobalElements |
Global entry Forms.CopyTo (type FormsGlobalElements) | input field «Copy to», id CopyTo | Forms: GlobalElements |
Global entry Fields.EnclosureBox (type FieldsGlobalFields) | Text field EnclosureBox assembles the block from both inputs | Fields: GlobalFields |
| Forms and Fields (content templates) | reference the global entries, and one template replaces Forms.CopyTo | Forms, Fields |
| Word content templates | bind EnclosureBox at the end of the letter | Accessing primedocs fields |
Data flow
Step 1: One global Forms entry per element
In the global configurations, create two entries of type FormsGlobalElements.
Key Forms.Enclosures:
<FormsGlobalElements>
<Text Id="Enclosures" Label="Enclosures" MultiLine="true" />
</FormsGlobalElements>
Key Forms.CopyTo:
<FormsGlobalElements>
<Text Id="CopyTo" Label="Copy to" MultiLine="true" />
</FormsGlobalElements>
Why two entries instead of one: A template can only replace a GlobalElements reference as a whole, not a single element within it. If both elements were in the same entry, the deviating template would also have to rebuild «Enclosures» locally and would no longer receive later changes to it. How finely the global entries are cut therefore determines what a template can override individually.
Step 2: Global field for the block
Create an entry of type FieldsGlobalFields with the key Fields.EnclosureBox:
<FieldsGlobalFields>
<!-- Expects the Forms elements with the ids Enclosures and CopyTo in the template -->
<Text Name="EnclosureBox">
<Code><![CDATA[
function main() {
const enclosures = $("Forms.Enclosures");
const copyTo = $("Forms.CopyTo");
return $.joinNonEmpty("\n\n",
enclosures ? "Enclosures:\n" + enclosures : "",
copyTo ? "Copy to:\n" + copyTo : "");
}
]]></Code>
</Text>
</FieldsGlobalFields>
- The field reads the inputs through the ids
EnclosuresandCopyTo. It requires every template that referencesFields.EnclosureBoxto contain Forms elements with these ids, whether included globally or defined locally. If one is missing, document creation stops with an error that namesEnclosureBoxand the missing reference. - This dependency is the contract between the global entries. The XML comment in the entry records it for everyone who edits the entry later.
$.joinNonEmpty(…)omits empty parts: without enclosures, only the copy part appears, and without either input, the block stays empty.
Step 3: Templates reference the global entries
In every letter template, activate the Forms document function:
<FormsConfiguration>
<Elements>
<GlobalElements Key="Forms.Enclosures" />
<GlobalElements Key="Forms.CopyTo" />
</Elements>
</FormsConfiguration>
The Fields document function:
<FieldsConfiguration>
<Fields>
<GlobalFields Key="Fields.EnclosureBox" />
</Fields>
</FieldsConfiguration>
In the Word content template, place the cursor at the end of the letter, click «Bind field» and select EnclosureBox. The field is inserted as a plain-text content control. The line breaks from \n produce the lines of the block.
Step 4: The deviating template replaces one element
In the one template that is to pre-fill «Copy to», replace the reference to Forms.CopyTo with a local element with the same id:
<FormsConfiguration>
<Elements>
<GlobalElements Key="Forms.Enclosures" />
<Text Id="CopyTo" Label="Copy to" MultiLine="true" Value="Accounting, for invoicing" />
</Elements>
</FormsConfiguration>
Id: exactlyCopyTo, withoutForms.in front. The prefix only comes into play when the element is accessed in code.Value: the default text that the user can overwrite in the dialog.LabelandMultiLine: take them over from the global element so that the dialog looks the same in all templates. For multilingual templates, usetranslate-Labelwith a global translation.- The reference
<GlobalElements Key="Forms.CopyTo" />must be removed. If both are in the configuration, validation reports the idCopyTotwice.
The Fields configuration and the Word template stay unchanged: Fields.EnclosureBox now finds the local element through the id CopyTo.
The local element is a copy. If the global Forms.CopyTo changes later, for example its label, the change does not reach this template. It has to be carried over here manually.
Testing
- Test a standard template in the template editor: «Enclosures» and «Copy to» are empty. Fill in both, and the block shows both parts. Fill in only «Copy to», and the block shows only the copy part.
- Test the deviating template: «Copy to» is pre-filled with the default text, and the block shows it.
- In the deviating template, temporarily add
<GlobalElements Key="Forms.CopyTo" />again: validation reports the duplicate idCopyTo. This confirms that the template really replaces the global element rather than adding to it.
Variants
Overriding a field with Modifications
If it is not the input that deviates but the output, Fields offers a mechanism of its own. Example: one template outputs only the copies on a single line, without enclosures. The Modifications element in GlobalFields replaces a field of the referenced entry for this template only:
<FieldsConfiguration>
<Fields>
<GlobalFields Key="Fields.EnclosureBox">
<Modifications>
<Text Name="EnclosureBox">
<Code><![CDATA[
function main() {
const copyTo = $("Forms.CopyTo");
return copyTo ? "Copy to: " + copyTo : "";
}
]]></Code>
</Text>
</Modifications>
</GlobalFields>
</Fields>
</FieldsConfiguration>
- The modification replaces the definition of the field completely, not individual attributes. It therefore contains the entire
Code. - Name and field type must match a field of the referenced entry, including one included through nesting. Otherwise, validation reports that the field to modify is missing or that the type does not match.
Text,FormattedText,WordContent,InlineWordContent,WordTableRows,Date,YesNoandPicturecan be modified.- Other fields that use
EnclosureBoxalso receive the modified value. Details: Modify Fields.
Forms has no such mechanism. There, replacing the reference as in step 4 remains the only way.
Changing a global entry without affecting all templates
Because global entries have no version state, every change affects all referencing templates. Renaming or removing an id is particularly delicate: every template and every global field that uses the id in code stops working afterwards. For such changes, create a new entry with a key of its own (e.g. Forms.CopyToV2), switch the templates over and test them one by one, and only remove the old entry once no template references it any more.
Pitfalls
| Symptom | Cause | Solution |
|---|---|---|
Validation reports a duplicate id CopyTo | The global reference and the local element are both in the template | Remove the reference <GlobalElements Key="Forms.CopyTo" /> |
| Validation reports several fields with the same name | A local field has the same name as a field from a referenced global entry | Override the global field with Modifications instead of redefining it locally |
Document creation stops with an error about EnclosureBox and a missing reference | The template references Fields.EnclosureBox but contains no Forms element with the id CopyTo or Enclosures | Include the element globally or define it locally |
Validation rejects the id Forms.CopyTo | The prefix Forms. is not part of the id, and dots are not allowed in Forms ids by default | Use the id CopyTo |
| Validation does not find the global entry | Key spelled differently, or the entry has a different type from the one the referencing element requires | Copy the key exactly, including upper and lower case, and check the type of the entry |
| A changed label is missing in one template | The template replaces the global element locally (step 4) | Update the local copy |