Mail Merge and Repeatable Syntax

Intro

We have built a templating engine in 3B Sign, 3B Forms and 3B Portals & Mobile Apps that allows developers/system admins to "mail merge" variables directly in the form, document or page.

Syntax

RecordId: {{record.Id}}     //This is the context record
User Id {{contactUser.Id}}  //This is the context user (only available in Portals)

//This example assumes Contact as the context record
//The top-level record is always the current record
//You can access the context record's fields using the following syntax

{{record.Name}} //Output: "Zak Effron"
{{record.Account.Name}} //Output: ACME Corp Ltd

//You can also access child records per context
//In this example, a Contact has multiple cases through the relationship "Cases"
//The syntax requires an open and close merge tags ({{#record.Relationship}} and {{/record.Relationship}})
Cases:
{{#record.Cases}}
    //You can access the current record's case fields like so:
    Case Subject: {{Subject}}       //Output: My Case Subject
    Case Desc: {{Description}}      //Output: I have a problem..
    Case Last Modified By: {{LastModifiedBy.Name}}  //Output: System Admin Name
    
    //You can even extract related records for the current context record
    //Below 
    Comments:
    {{#CaseComments}}
      Case Comment Body: {{CommentBody}}        // Output: Please log on to the portal...
    {{/CaseComments}}
{{/record.Cases}}

//You can add any number of child relationships to a document, form or page
{{#record.Opportunities}}
    Oppy Name: {{Name}}             //Output: Oppy Name
    Oppy Status: {{StageName}}      //Output: Prospecting
{{/record.Opportunities}}

The Context Record

The context record is recognised either as the Form context record (from recordId param), the Sign Document's context record (from recordId param) or in portals, it could be either the context user (Contact) or if the page is loaded with a recordId param, then we will use the record passed in the recordId to set the context.

Note: you can only have one context record per page

Child Records

You can add an unlimited number of child records

Grand Child Records

You can traverse down to an unlimited number of levels, so you can get the context record's child records and also the child records for each child record

Parent Record Fields

You can access fields at an unlimited depth (e.g. {{record.Account.ParentAccount.Owner.Name}})

Adding Invalid Child Scope

If you accidentally add an invalid child scope (e.g. the relationship name is mispeled or missing), this is what will happen:

Invalid Child Relationship:
{{#record.InvalidRelationship}}
{{/record.InvalidRelationship}}

Expected Output:
- Page renders
- Scope is blank

Console error (dev console): 
Message: Could not load child related object
Error: Invalid child relationship name InvalidRelationship

Adding Invalid Context Record Field

If you accidentally add an invalid record field, this is what will happen:

Invalid Context Record Field:
{{record.InvalidField}}

Expected Output:
- Page loads
- Blank section where the field was embedded
- No console error will be posted

Adding Invalid Child Scope Field

If you accidentally add an invalid child scope field, this is what will happen:

Invalid Child Record Field
{{#record.Cases}}
{{InvalidCaseField}}
{{/record.Cases}}

Expected Behaviour:
- Page loads
- Blank space where the field merge tag was added
- No console error will be posted

Conditional Rendering for Fields

{{^record.FirstName}}
  User doesn't have first name
{{/record.FirstName}}

Conditional Rendering for Child Records

{{#record.Opportunities.length}}
No Opportunities
{{/record.Opportunities}}

Bad Syntax (User Error)

//If you added a child repeatable start tag but forgot to add an end tag

{{#record.Opportunities}}
...

Expected output:
- Page FAILS to load
- Console Error logged:
Error: Unclosed section "record.Opportunities" at 6110

Repeating HTML Content

You can create dynamic components and repeat any HTML content

<table>
   <tr>
      <th>Case Name</th>
      <th>Case Subject</th>
      <th>Case Description</th>
      <th>Action</th>
   </tr>
   <!-- looping cases-->
   {{#record.Cases}}
   <tr>
      <td>{{Name}}</td>
      <td>{{Subject}}</td>
      <td>{{Description}}</td>
      <td>
          <!-- add button action -->
         <a href="/b3p__Page#CaseDetail?recordId={{Id}}" target="_blank"></a>
      </td>
   </tr>
   {{/record.Cases}}
   <!-- end looping cases-->
</table>