Introduction
S-Docs provides many advanced features for merging data into your S-Doc Template. In most cases described in this document, they require editing of the template source code, which can be easily accessed by clicking on the Source button on the S-Docs Template Editor page.
The template source is based on HTML with specific tags that indicate the S-Docs engine will apply specific mergers or functions.
Merge Field Functions
You can apply multiple functions to merge field data by adding a space and a specific attribute (function) to the end of the field name, like the following:
Single Attribute: {{!Object.Field attribute="value"}} Multiple Attributes: {{!Object.Field attribute1="value1" attribute2="value2" attribute3="value3"}}
For example, {{!opportunity.amount}} will return an unformatted numeric value as it is stored in the Salesforce database; adding {{!opportunity.amount format-number="#,###.##"}} will return the same value, but formatted to include commas and two decimal places.
- All attributes require a space between the merge field name and the attribute.
- When using merge fields within other tags, you may need to escape the HTML in order for the merge to happen properly.
- Be careful when using the Graphical UI editor to change the appearance of the merge field tag. Care must be taken that styling changes do not interject the merged field syntax. E.g. {{!Opportunity.<style= You may need to click on Source to validate that merged fields do not contain any characters.
Rich Text in Merge Fields
S-Docs will interpret HTML code* in a Rich Text merge field (links, text styling and formatting) when the field is surrounded by 3 sets of curly braces instead of 2:
Numbered list: {{{!Object.Ordered_List__c}}}
* Images in Rich Text fields are only supported in PDF and DOCX format. For more, see the Dynamic Images article
Merge Field Attributes
format-number=" " #,###.## (Typical Currency with cents) #,### (Comma delimited whole number) #.### (EU formatting) #.###,## {{!Opportunity.amount format-number="#,###.##"}} 43222300.8 ➤ 4,222,300.80 {{!Opportunity.amount format-number="#,###"}} 43222300.8 ➤ 4,222,301 {{!Opportunity.amount format-number="#.###"}} 43222300.8 ➤ 4.222.301
- Larger numbers will still follow the pattern even if they exceed the 4 digits shown in the pattern. Rounding is applied when precision exceeds formatting.
- If you need to include a currency symbol, you can add it just before the merged field. E.g. ${{!Opportunity.amount format-number="#.###"}}
format-date=" " {{!opportunity.createdDate format-date="MM/dd/yyyy"}} 2018-10-28 ➤ 04/04/2017 {{!opportunity.createdDate format-date="MMMMM"}} 2018-10-28 ➤ October {{!opportunity.datetime__c format-date="MM/dd/yy hh:mm:ss TZ:America/New_York"}} 2018-10-28 ➤ 10/28/2018 12:56:32 EST
- Patterns are case sensitive. E.g. MM=month while mm=minutes. Reference to available patterns.
- Times are formatted per the database time (GMT).
- Time zones must be written using Java time codes.
- Only Salesforce-supported time zones are accepted.
- Long descriptions (e.g. Month, day of week) are in English. You can use formula fields if needed to meet a specific requirement.
{{!opportunity.checkbox__c checkbox="true"}} Displays a checkbox with a dotted white border; includes a black checkmark if checked. {{!opportunity.checkbox__c checkbox="black"}} Displays a checkbox with a solid black border; fills in with black and includes a white checkmark if checked. {{!opportunity.checkbox__c checkbox="radio"}} Displays a radio button.
- When this attribute is added, the merge field will display as the checkbox in its current state on the record once the document is generated.
- Currently not supported in DOCX file format
{{!Check__c.RoutingNumber__c MICR="11"}} To adjust spacing between MICR characters: {{!Opportunity.Description MICR="[FONTSIZE (REQUIRED)],[SPACING (OPTIONAL)]"}} e.g. {{!Opportunity.Description MICR="20"}} {{!Opportunity.Description MICR="20,-5"}} {{!Opportunity.Description MICR="20,5"}}
- The output is a series of images that can be used in PDF generation of checks. Only digits and ‘t,’ ’o,' ’a,’ ’d,’ are transformed. Other characters are ignored.
- The number following MICR represents the font width. E.g. MICR="16" will be larger than MICR="8".
- Spacing defaults to 0 if it is not specified. As shown, negative spacing values are allowed. The lower the spacing value, the closer together MICR characters.
{{!Opportunity.Description CR="[OCR-A/OCR-B],[FONT SIZE (REQUIRED),[SPACING (OPTIONAL)]"}} Example: {{!Opportunity.Description CR="OCR-A,20,5"}} {{!Opportunity.Description CR="OCR-B,20,5"}}
- The output is a series of images that can be used in PDF generation of checks. Only digits 0-9 are transformed. Other characters are ignored.
- Spacing defaults to 0 if it is not specified. Negative spacing values are allowed. The lower the spacing value, the closer together OCR characters.
{{!contact.billingStreet ToUpperCase="true"}} 123 Main Street, Apt 3 ➤ 123 MAIN ST, APT 3
{{!contact.billingStreet ToLowerCase="true"}} 123 MAIN ST, APT 3 ➤ 123 main street, apt 3
{{!account.greeting__c RTL="true"}} שלום➤ םולש
- Using the RTL merge field attribute will transform merge field data only, not static text.
- To apply RTL for both merge fields and static text, use the following style in the template source:
<rtl>reverse</rtl>
- When using <rtl> tags, there is no need to add the RTL attribute to your merge fields. You can wrap an entire template in <rtl> tags to transform both merge field data and static text.
- Note that <rtl> tags will not work properly with text that breaks across two lines in the generated document. You should use separate <rtl> tags for each line if text breaks across two lines.
{{!product2.color translate="true"}} BLUE ➤ BLEU
Translate can be used only on picklist fields, but can be used on all field labels.
Click here to learn more.
- This feature leverages Salesforce toLabel() function within a SOQL query. It is particularly useful for orgs that have Translation Workbench enabled. Translate keyword will cause an error if used on field types that do not support toLabel().
- For related list translations, or lookup fields, you should use direct SOQL query. If you set the class to "none" then only the data is returned – not in a table format. Here is an example usage from the S-Docs template source:
<!--{{! <LineItemsSOQL> <class>none</class> <soql>Select tolabel(color__c) From product2 where id='{!ObjectID15}' and toLabel(color__c) =’BLEU’</soql> <column>color__c</column> </LineItemsSOQL> }}-->
- Additionally, for fields merged within related lists, you may find the substitute column attribute feature useful.
{{!Opportunity.Name replaceAll="ReplaceThis1,ReplaceWithThis1,ReplaceThis2,ReplaceWithThis2"}}
{{!Opportunity.EncryptedField__c encrypt="true"}}
- This attribute is not supported for named query merge fields.
{{!Opportunity.PicklistField__c Display="true"}}
- In most cases, picklist field values are identical to their API names. This attribute covers instances when the two differ.
{{!Opportunity.Multi_Select_Picklist_Field__c msnl="true"}}
{{!Opportunity.Long_Field__c breakeverynchars="10"}} supercalifragilisticexpialidocious ➤ supercalif ragilistic expialidoc ious
- Negative, zero, or blank values will not insert any line breaks.
- If you are using this attribute with PDF-Upload templates, force the merged text to wrap by adding the following code to the Additional Style field:
white-space: normal!important;
{{!Object.Field toCells="Number of Cells to Generate,CSS class to apply to table cells"}} Example: {{!Opportunity.Three_Character_Code__c toCells="3,table873"}} 123 ➤ 1, 2, and 3 would be in separate table cells, which would each have the table873 CSS class applied to them.
- Specifying more cells than the field value will result in blank cells being created.
{{!Object.Field strip-html="True"}}
- For related lists, use the type="text" column attribute (explained in the Related List Column Attributes section of this article)
{{!Object.Field justifyNewlines="HTMLElement"}} Example: INPUT: <div style="text-align: justify;">{{!Opportunity.Long_Text_Area__c justifyNewlines="div"}}</div> OUTPUT: <div style="text-align: justify;">Paragraph One</div><div style="text-align: justify;">Paragraph Two</div>
- This attribute can only be used for style="text-align: justify"
- This attribute cannot be used with Microsoft templates
By default, S-Docs merges related lists into your template in the form of a table, where each record returned is generated as a row in the table. This means the table grows linearly with the number of records returned. In order to meet more specific formatting requirements, S-Docs has a variety of advanced attributes that can be leveraged.
-
DirectSOQL
Allows you to execute a custom SOQL query within your template and merge the resulting data into your document at runtime. DirectSOQL supports aggregates and subquery functions.
-
Render
Provides ability to show/hide sections of a template based on a condition.
Displaying Related Lists & SOQL Line Items Without Table Formatting
To remove the table formatting inAllows for replacing values with other values whenever a match is made. a related list or SOQL table, you can place <class>none</class> at the beginning of your related list / SOQL code. For example, the following code will display account team members as a comma-delimited list rather than as a table:
<!--<lineitemsSOQL> <prefix>The Account Team Members are: </prefix> <class>none</class> <soql> SELECT user.name FROM accountteammember WHERE accountid='{{!account.id}}' </soql> <column postfix=", ">user.name</column> <postfix>. Please see page 3 for their contact information.</postfix> </lineitemsSOQL>-->
In this example, <class>none</class> removes all the table formatting. The postfix attribute adds a comma and a space between each account team member, but if we did not have this postfix attribute here, the items returned by the SOQL query might look something like this: Jack JohnsonJohn JacksonSarah McCleanJohn Paulson. This is because using <class>none</class> will make your SOQL query or related list return raw data with no spaces or table formatting, all on the same line.
Alternatively, if you need to format your related list data in an entirely new way, you can also generate a template component that formats your data and then merges it into your final document. Click here to read more about this feature.
Related List Column Attributes
Related lists contain columns that can optionally include additional attributes (shown in bold below). These attributes provide a powerful way to dynamically manipulate data to meet your requirements.
Substitute functionality can be useful for translating values to different languages for a template. While you may be able to do the same using a Salesforce formula field, this can drastically reduce the number of formula fields you would need to create.
<column substitute="value1tomatch, value1ToSubstitute, value2ToMatch,Value2ToSubstitute, ..., OptionalCatchall-substitution">Field__c </column>
If the substitute list contains an odd number of values, then the last value will be the catch-all that is substituted when no matches are made.
- Substitute a checkbox for German language. values:substitute="true,Ja,false,nien"
- Matches are made ignoring case sensitivity and white spaces are trimmed, but the substitute values are exact.
- For checkbox fields use true and false as the value to match on.
- For organization purposes you can optionally use parenthesis to organize your list, e.g.:
substitute="(1,one),(2,two),(3,three)"
- If your value is null, you should not use the substitute attribute but rather use the nullprefix= attribute that will allow you to insert a value whenever null data is encountered for that field.
- If you are matching a numeric value, the precision needs to also match.
<column substitute="2.00,2">quantity</column>
- Example: Use Substitute feature to correctly display the full month Name of field that contains the month number:
<column substitute="1, Januar, 2, Februar, 3, März, 4, April, 5, Mai, 6, Juni, 7, Juli, 8, August, 9, September, 10,Oktober, 11,November, 12,December, unknown">MonthNumber__c</column>
1) substitute matches against (and replaces) the ENTIRE string, where as replaceall matches against (and replaces) all substring appearances of the specified string.
2) There is no "else" condition in replaceall (since we're replacing substrings, an "else" condition would be nonsensical)
This attribute supports regexs.
<column replaceall="replaceThis1,replaceWithThis1,replaceThis2,replaceWithThis2,...replaceThisN,replaceWithThisN">
Regex Syntax:
Start your replaceall string with [regex] (including brackets)
For example, say you want to replace all "a) This is a test", "b) This is a test", etc. with " a) This is a test", " b) This is a test" but NOT replace anything that looks like "1. This is a test", "2. This is a test", etc. (i.e. you want to indent a) b) c) but not 1. 2. 3. and the data structure / related list formatting prohibit simpler solutions like using <li></li>). To achieve this, you could use the following:
<column replaceall="[regex]([a-zA-Z]\)), $1">
If the data value is "Burlington Textiles Corp," but you want it to be "Boston Textiles Corp," use <column replaceall="Burlington,Boston">
<column showcolumn="{{!Object.Fieldname}} == 'FieldValueThatTriggersColumnShowing'">...</column>
Note that the column will be hidden if the syntax resolves to false.
If your table has a header row, you will need to apply the same condition to the header row as a RENDER statement:
<!--RENDER='{{!Object.Fieldname}}' == 'FieldValueThatTriggersColumnShowing'--><th>Column Name</th><!--ENDRENDER-->
You can conditionally show an entire column in your related list if the Opportunity record's StageName field has a value of 'Prospecting' or 'Closed', and hide it if the StageName field has any other value, by using the following: <column showcolumn="({{!Opportunity.StageName}} == 'Prospecting' || {{!Opportunity.StageName}} == 'Closed')">...</column>
<column type="rtf">Your content goes here. </column>
When using type ="checkbox" the checkbox images have a class called "sdcheckbox." If needed, you can modify the CSS treatment of the checkbox. E.g.
<style type="text/css">.sdcheckbox { width: 10px; height: 10px; border: 1px solid #73AD21; } </style>
- type="chackbox" Currently not supported in DOCX file format
<column header="YourHeaderHere">
Example: <column header="Grand Total">will place "Grand Total" over that column as a header.
<column format-number="#,###.##">
Format number supports these four types:#,### #,###.## #.### #.###,## For example, if a number in your column was stored as 123456 and you chose the 2nd type listed above, the number would appear as 1,234.56
<column format-date="MM/dd/yyyy">
To turn a date into just a day, month, or a year, you can use <column format-date="MMMMM"> (for days, use D, and for years, use Y)
<column mergenext="true">
If you have a currency symbol column and an amount column, like $ | 12$ | 4
- You can merge these two columns together and the resulting column will be
$12 $4
- Prefix and postfix are useful to put any spacing between cell values.
Note: mergenext is not supported when using group-by functionality.
<column colspan="4">
<column colspan="1"> has no effect; by default, a column already spans 1 column. <column colspan="4"> Will make this column span 4 columns total (i.e. this column will be 3 columns longer than it would normally be). This works the same as the HTML colspan attribute.
<column newrow ="4">
<column newrow="true"> Will create a new row for each record in this column. For example, instead of seeing cell 1 | cell 2 | cell 3 you will see cell 1 cell 2 cell 3----<column newrow="3"> Will create a new row after the 3rd record of each row, e.g. cell 1 | cell 2 | cell 3 cell 4 | cell 5 | cell 6 cell 7 | cell 8 | cell 9 This attribute is useful for creating documents such as mailing labels.
<column prefix="YourStringHere">
<column prefix="$"> would put a dollar sign at the beginning of each column like so:$ 12$ 4
<column nullprefix="YourStringHere">
<column nullprefix="N/A"> will make columns with "null" values appear as N/A.
<column postfix="YourStringHere">
<column postfix="dollars"> would put "dollars" at the end of each column like so:12 dollars 4 dollars
<column nullpostfix="YourStringHere">
<column nullprefix="N/A"> will make columns with "null" values appear as N/A.
<column allprefix="YourStringHere">
<column allprefix="$"> will put "$" at the beginning of each column regardless of if the value is null or not.
<column allpostfix="YourStringHere">
<column allpostfix="€"> will put "€" at the end of each column regardless of if the value is null or not.
<column abfprefixouter=",">
<!--{{! <lineitemsSOQL> <class>none</class> <soql>SELECT productcode FROM opportunitylineitem WHERE Opportunityid ='0061U0000078tEw' </soql> <column abfprefixouter=", ">productcode</column> <postfix>.</postfix> </lineitemsSOQL> }}-->
This example would create a list of products that looks like:product1, product2, product3.
<column startIndex="3">
Note that numbering starts at the number equal to the startIndex number + 1.
<lineitems> <class>table646</class> <listname>opportunitylineitems</listname> <column startIndex="3">rownum</column> <column>PricebookEntry.Product2.name</column> <column>PricebookEntry.Product2.description</column> <column>unitprice</column> <column>quantity</column> <column>totalprice</column> </lineitems>
<column render="CONDITION_1,output_value_1,CONDITION_2,output_value_2...DEFAULT OUTPUT VALUE IF ALL RENDERS EVALUATE TO FALSE">
- This feature is only supported with <lineitemsSOQL> statements
- You must use <soql>...</soql> tags and include any field specifed in your subsitute="..." attributes in your SOQL query
- You should not specify a field between the <column></column> tags. Doing this may cause issues
- You can use RECORD.Field_Name to use related list record data fields within the render="..." attribute
- Any tags inside of the column render (e.g. <span>) will need to have the <> characters escaped (lt#, gt#)
Examples:
<column render="RECORD.Product_Type__c STARTSWITH Vacuum && RECORD.Product_Type__c ENDSWITH Cleaner,RECORD.Vacuum_Name__c,Not a Vacuum"></column>
- If the Product's Type field starts with Vacuum and ends with Cleaner, the column will output the name of the vacuum, otherwise the column will output "Not a Vacuum."
<column render="RECORD.Title==null,No Title Available,RECORD.Title"></column>
- If the Contact's title field is blank, the column will output "No Title Available," otherwise it will output the Contact's title.
You can also use nested render statements:
<column render="RECORD.Country__c == usa,[RENDER1]RECORD.City__c == new york,S-Docs HQ,[RENDER2]RECORD.City__c == ann arbor,S-Docs Innovation Center,[ENDRENDER2][ENDRENDER1],Work From Home"></column>
- If the record's Country field is USA, and the city is New York, the column will output "S-Docs HQ." If the record's Country field is USA and the city is Ann Arbor, the column will output "S-Docs Innovation Center." If the record's Country field is not USA, the column will output "Work From Home."
<column type="rtf" render="RECORD.StageName == 'Closed', lt#span style='color:red;'gt# Closed lt#/spangt#,Open"></column>
- If the Opportunity is Closed, the column will output "Closed" in red. Otherwise, the column will output "Open" in the default font color.
<column breakeverynchars="10">
<column breakeverynchars="10">Long_Line__c</column> will insert a line break after every 10 characters.
<column addToEmail="To">
<column addToEmail="CC">CreatedBy.Email</column> will add the email addresses of every user who created a record in this related list as document email CC recipients