# Template Attribute Reference

### Merge Field Attributes

#### format-number

**Purpose:** Format numeric values with thousands separators and decimal places

**Syntax:** `{{!Object.NumericField format-number="pattern"}}`

**Supported Patterns:**

| Pattern    | Description                        | Input     | Output       |
| ---------- | ---------------------------------- | --------- | ------------ |
| `#,###.##` | US/UK currency format              | 4222300.8 | 4,222,300.80 |
| `#,###`    | Whole numbers with commas          | 4222300.8 | 4,222,301    |
| `#.###`    | European format (period separator) | 4222300.8 | 4.222.301    |
| `#.###,##` | European format with decimals      | 4222300.8 | 4.222.300,80 |

**Examples:**

```
{{!Opportunity.Amount format-number="#,###.##"}}
${{!Opportunity.Amount format-number="#,###.##"}}
€{{!Opportunity.Amount format-number="#.###,##"}}
```

**Notes:**

* Patterns work with numbers of any size beyond the 4 digits shown
* Rounding is applied when precision exceeds the format specification
* Currency symbols must be added separately (outside the merge field)
* Works with standard numeric, currency, and formula field types

***

#### format-date

**Purpose:** Format Salesforce date and datetime fields using Java SimpleDateFormat patterns

**Syntax:** `{{!Object.DateField format-date="pattern"}}`

**Common Patterns:**

| Pattern               | Description           | Example Output           |
| --------------------- | --------------------- | ------------------------ |
| `MM/dd/yyyy`          | US short format       | 04/04/2017               |
| `dd/MM/yyyy`          | European short format | 04/04/2017               |
| `dd.MM.yyyy`          | European dot format   | 04.04.2017               |
| `MMMM dd, yyyy`       | Long format           | October 28, 2018         |
| `EEEE, MMMM dd, yyyy` | Full format           | Monday, October 28, 2018 |
| `MMMM`                | Month name only       | October                  |
| `yyyy`                | Year only             | 2018                     |
| `MMM dd`              | Short month and day   | Oct 28                   |

**Pattern Components:**

| Symbol | Meaning                 | Example |
| ------ | ----------------------- | ------- |
| `yyyy` | 4-digit year            | 2024    |
| `yy`   | 2-digit year            | 24      |
| `MMMM` | Full month name         | January |
| `MMM`  | Abbreviated month       | Jan     |
| `MM`   | Month as number (01-12) | 01      |
| `M`    | Month as number (1-12)  | 1       |
| `dd`   | Day of month (01-31)    | 05      |
| `d`    | Day of month (1-31)     | 5       |
| `EEEE` | Full day name           | Monday  |
| `EEE`  | Abbreviated day         | Mon     |
| `HH`   | Hour (00-23)            | 14      |
| `hh`   | Hour (01-12)            | 02      |
| `mm`   | Minutes (00-59)         | 30      |
| `ss`   | Seconds (00-59)         | 45      |
| `a`    | AM/PM marker            | PM      |

**Timezone Support:**

```
{{!Opportunity.DateTime__c format-date="MM/dd/yy hh:mm:ss TZ:America/New_York"}}
```

**Common Timezones:**

* `America/New_York`
* `America/Chicago`
* `America/Denver`
* `America/Los_Angeles`
* `Europe/London`
* `Europe/Paris`
* `Asia/Tokyo`
* `Australia/Sydney`

**Examples:**

```
{{!Opportunity.CloseDate format-date="MM/dd/yyyy"}}
{{!Opportunity.CloseDate format-date="MMMM"}}
{{!Opportunity.CreatedDate format-date="MM/dd/yy hh:mm:ss TZ:America/New_York"}}
```

**Notes:**

* Patterns are **case sensitive** (MM=month, mm=minutes)
* Times are stored in GMT and must be converted using TZ parameter
* Only Salesforce-supported timezones are accepted
* Month and day names are always in English
* Use Salesforce formula fields for non-English date formatting
* [Full Java pattern reference](https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html)

***

#### checkbox

**Purpose:** Display boolean fields as checkbox or radio button images

**Syntax:** `{{!Object.BooleanField checkbox="style"}}`

**Supported Styles:**

| Value   | Description       | Appearance                                                       |
| ------- | ----------------- | ---------------------------------------------------------------- |
| `true`  | Standard checkbox | Dotted white border, black checkmark when checked                |
| `black` | Filled checkbox   | Solid black border, black fill with white checkmark when checked |
| `radio` | Radio button      | Circle, filled when checked                                      |

**Examples:**

```
{{!Opportunity.Payment_by_Check__c checkbox="true"}}
{{!Opportunity.Terms_Accepted__c checkbox="black"}}
{{!Opportunity.Shipping_Ground__c checkbox="radio"}}
```

**Custom Styling:**

```
<style type="text/css">
.sdcheckbox {
  width: 15px;
  height: 15px;
  border: 2px solid #000000;
}
</style>
```

**Notes:**

* Displays the current state of the boolean field on the record
* Not supported in DOCX file format (PDF only)
* Checkbox images have the CSS class `sdcheckbox`
* Checked state shows filled/marked, unchecked shows empty

***

#### MICR

**Purpose:** Output text in MICR E-13B font for check printing and bank processing

**Syntax:**

```
{{!Object.Field MICR="fontSize"}}
{{!Object.Field MICR="fontSize,spacing"}}
```

**Parameters:**

* **fontSize** (required): Controls character width (recommended: 11)
* **spacing** (optional): Controls space between characters (default: 0)

**Examples:**

```
{{!Check__c.RoutingNumber__c MICR="11"}}
{{!Check__c.AccountNumber__c MICR="11,0"}}
{{!Check__c.CheckNumber__c MICR="11,-5"}}
{{!Check__c.Amount__c MICR="20,5"}}
```

**MICR Special Characters:**

| Character | Symbol | Meaning           |
| --------- | ------ | ----------------- |
| t         | ⑆      | Transit (routing) |
| o         | ⑈      | On-us (account)   |
| a         | ⑉      | Amount            |
| d         | ⑊      | Dash              |

**Notes:**

* Outputs series of images suitable for PDF check generation
* Only digits (0-9) and characters `t`, `o`, `a`, `d` are transformed
* Other characters are ignored
* Higher fontSize values create larger characters
* Negative spacing values bring characters closer together
* Requires magnetic ink toner for actual bank processing
* Standard check printing uses fontSize="11" with spacing="0"

***

#### CR (Character Recognition)

**Purpose:** Output text in OCR-A or OCR-B fonts for machine-readable documents

**Syntax:**

```
{{!Object.Field CR="fontType,fontSize,spacing"}}
```

**Parameters:**

* **fontType** (required): `OCR-A` or `OCR-B`
* **fontSize** (required): Character size (recommended: 20)
* **spacing** (optional): Space between characters (default: 0)

**Examples:**

```
{{!Check__c.CheckNumber__c CR="OCR-A,20,0"}}
{{!Document__c.SerialNumber__c CR="OCR-B,20,5"}}
{{!Account__c.Code__c CR="OCR-A,16,-2"}}
```

**Notes:**

* Outputs series of images for PDF generation
* Only digits 0-9 are transformed
* Other characters are ignored
* Spacing defaults to 0; negative values allowed
* Lower spacing values bring characters closer together
* Useful for checks and computer-readable forms
* Does not require special toner for printing

***

#### ToUpperCase

**Purpose:** Transform text to all uppercase letters

**Syntax:** `{{!Object.TextField ToUpperCase="true"}}`

**Examples:**

```
{{!Contact.BillingStreet ToUpperCase="true"}}
{{!Account.Name ToUpperCase="true"}}
{{!Opportunity.Description ToUpperCase="true"}}
```

**Input/Output:**

```
Input:  123 Main Street, Apt 3
Output: 123 MAIN STREET, APT 3
```

**Common Use Cases:**

* Mailing labels
* Legal document headers
* Formal addresses
* Standardized text sections

***

#### ToLowerCase

**Purpose:** Transform text to all lowercase letters

**Syntax:** `{{!Object.TextField ToLowerCase="true"}}`

**Examples:**

```
{{!Contact.Email ToLowerCase="true"}}
{{!Account.Website ToLowerCase="true"}}
{{!Contact.BillingStreet ToLowerCase="true"}}
```

**Input/Output:**

```
Input:  123 MAIN ST, APT 3
Output: 123 main st, apt 3
```

**Common Use Cases:**

* Email addresses
* Website URLs
* Standardizing case for technical fields

***

#### RTL (Right to Left)

**Purpose:** Reverse character strings for right-to-left languages (Hebrew, Arabic)

**Syntax for Merge Fields:**

```
{{!Object.Field RTL="true"}}
```

**Syntax for Template Sections:**

```
<rtl>reverse</rtl>
```

**Examples:**

```
<!-- Single field -->
{{!Account.Greeting__c RTL="true"}}

<!-- Entire section -->
<rtl>reverse</rtl>
<p>Welcome {{!Account.Name}}, your account number is {{!Account.AccountNumber}}</p>
```

**Input/Output:**

```
Input:  שלום
Output: םולש
```

**Notes:**

* RTL attribute transforms **merge field data only**
* `<rtl>` tags transform **both merge fields and static text**
* Do not combine RTL attribute with `<rtl>` tags
* `<rtl>` tags don't work with text breaking across two lines
* Use separate `<rtl>` tags for each line if text wraps
* Primarily used for PDF generation in RTL languages

***

#### translate

**Purpose:** Return translated picklist values using Salesforce Translation Workbench

**Syntax:** `{{!Object.PicklistField translate="true"}}`

**Requirements:**

* Translation Workbench enabled in Salesforce
* Picklist values translated in Translation Workbench
* User language preferences set

**Examples:**

```
{{!Product2.Color__c translate="true"}}
{{!Opportunity.StageName translate="true"}}
{{!Case.Status translate="true"}}
```

**Input/Output (French locale):**

```
Input:  BLUE
Output: BLEU
```

**SOQL Usage:**

```
<!--{{!
<LineItemsSOQL>
<class>none</class>
<soql>
SELECT toLabel(Color__c) 
FROM Product2 
WHERE Id = '{{!Product2.Id}}'
</soql>
<column>Color__c</column>
</LineItemsSOQL>
}}-->
```

**Notes:**

* Works **only with picklist fields**
* Can also be used on field labels
* Leverages Salesforce `toLabel()` function
* Causes errors if used on non-picklist field types
* Respects user's language/locale settings
* For related lists, use SOQL with `toLabel()`

***

#### replaceAll

**Purpose:** Replace all occurrences of specified substrings

**Syntax:** `{{!Object.Field replaceAll="find1,replace1,find2,replace2,..."}}`

**Examples:**

```
{{!Opportunity.Name replaceAll="Inc,Incorporated,Ltd,Limited"}}
{{!Account.Name replaceAll="Corp,Corporation,LLC,Limited Liability Company"}}
{{!Contact.Title replaceAll="VP,Vice President,SVP,Senior Vice President"}}
```

**Input/Output:**

```
Input:  ABC Corp - Q1 Project
Output: ABC Corporation - Q1 Project
```

**Notes:**

* Matches and replaces **all occurrences** of substrings
* Different from `substitute` which matches entire values
* Case sensitive matching
* Can chain multiple replacements
* No catch-all value

***

#### encrypt

**Purpose:** Display classically encrypted fields in decrypted form

**Syntax:** `{{!Object.EncryptedField encrypt="true"}}`

**Examples:**

```
{{!Opportunity.Encrypted_SSN__c encrypt="true"}}
{{!Account.Encrypted_Account_Number__c encrypt="true"}}
```

**Notes:**

* Works with Salesforce Classic Encryption
* User must have permission to view encrypted data
* Not supported for named query merge fields
* Different from Platform Encryption

***

#### Display

**Purpose:** Render picklist field values as display labels instead of API names

**Syntax:** `{{!Object.PicklistField Display="true"}}`

**Examples:**

```
{{!Opportunity.StageName Display="true"}}
{{!Product2.Status__c Display="true"}}
```

**When to Use:**

* Picklist API name: `stage_prospecting`
* Display label: `Prospecting`
* Without attribute: Shows `stage_prospecting`
* With attribute: Shows `Prospecting`

**Notes:**

* Most picklists have identical labels and API names
* Only necessary when they differ
* Common in managed packages or older orgs

***

#### msnl

**Purpose:** Replace semicolons in multi-select picklists with line breaks

**Syntax:** `{{!Object.MultiSelectPicklistField msnl="true"}}`

**Examples:**

```
{{!Opportunity.Products_Interested__c msnl="true"}}
{{!Contact.Communication_Preferences__c msnl="true"}}
```

**Input/Output:**

```
Input:  Product A;Product B;Product C
Output: Product A
        Product B
        Product C
```

**Notes:**

* Converts semicolon-separated values to new lines
* Makes multi-select values more readable
* Particularly useful for forms and reports

***

#### breakeverynchars

**Purpose:** Insert spaces at specified character intervals to enable line breaks

**Syntax:** `{{!Object.Field breakeverynchars="number"}}`

**Examples:**

```
{{!Opportunity.Long_Code__c breakeverynchars="10"}}
{{!Account.Serial_Number__c breakeverynchars="5"}}
```

**Input/Output:**

```
Input:  supercalifragilisticexpialidocious
Output: supercalif ragilistic expialidoc ious
```

**PDF-Upload Template Styling:**

```
white-space: normal!important;
```

Add to Additional Style field to force text wrapping.

**Notes:**

* Negative, zero, or blank values have no effect
* Inserted spaces allow text to wrap naturally
* Useful for long unbroken strings (URLs, codes, hashes)

***

#### toCells

**Purpose:** Split field value into individual letter cells in a table

**Syntax:** `{{!Object.Field toCells="cellCount,cssClass"}}`

**Requirements:**

* Must be used within `<td>` tags
* Part of a table structure

**Examples:**

```
<td>{{!Opportunity.Product_Code__c toCells="5,codeCell"}}</td>
<td>{{!Account.ZIP_Code__c toCells="5,zipCell"}}</td>
```

**Input/Output:**

```
Input:  ABC123
Output: |A|B|C|1|2|3|
```

**With Custom Styling:**

```
<style>
.codeCell {
  border: 1px solid #000;
  padding: 5px;
  text-align: center;
  width: 30px;
}
</style>

<table>
  <tr>
    <td>{{!Opportunity.Code__c toCells="6,codeCell"}}</td>
  </tr>
</table>
```

**Notes:**

* Each character becomes a separate table cell
* Specifying more cells than characters creates blank cells
* CSS class applies to all generated cells
* Useful for forms requiring individual character entry boxes

***

#### strip-html

**Purpose:** Remove all HTML tags from rich text fields

**Syntax:** `{{!Object.RichTextField strip-html="true"}}`

**Examples:**

```
{{!Opportunity.Description__c strip-html="true"}}
{{!Account.Notes__c strip-html="true"}}
```

**Input/Output:**

```
Input:  <p>This is <b>bold</b> text with <a href="#">links</a></p>
Output: This is bold text with links
```

**For Related Lists:** Use `type="text"` column attribute instead:

```
<column type="text">Description__c</column>
```

**Notes:**

* Removes all HTML markup
* Leaves only plain text content
* Alternative to `type="text"` for merge fields
* Useful when HTML formatting would cause issues

***

#### justifyNewLines

**Purpose:** Prevent irregular spacing when merging justified multi-paragraph text

**Syntax:** `{{!Object.LongTextField justifyNewlines="HTMLElement"}}`

**Examples:**

```
<div style="text-align: justify;">
  {{!Opportunity.Terms__c justifyNewlines="div"}}
</div>

<p style="text-align: justify;">
  {{!Contract.Body__c justifyNewlines="p"}}
</p>
```

**Input:**

```
Paragraph one text here.

Paragraph two text here.
```

**Output:**

```
<div style="text-align: justify;">Paragraph one text here.</div>
<div style="text-align: justify;">Paragraph two text here.</div>
```

**Notes:**

* Only works with `style="text-align: justify"`
* Cannot be used with Microsoft Word templates
* Each paragraph becomes its own HTML element
* Prevents justification from affecting line breaks

***

#### blobToString

**Purpose:** Convert HTML-based blob data to strings

**Syntax:** `{{!Object.BlobField blobToString="true"}}`

**Examples:**

```
{{!Attachment.Body blobToString="true"}}
{{!ContentVersion.VersionData blobToString="true"}}
```

**Notes:**

* Blob content must be convertible to string or well-formed HTML
* Also available as related list column attribute
* Useful for merging file content into documents
* Will fail if blob contains binary data

***

#### Rich Text Rendering

**Purpose:** Preserve HTML formatting in rich text fields

**Syntax:** `{{{!Object.RichTextField}}}`

**Note the Triple Braces:** Three `{` instead of two

**Examples:**

```
{{{!Opportunity.Description__c}}}
{{{!Account.Rich_Notes__c}}}
{{{!Product2.Features__c}}}
```

**Preserved Formatting:**

* Bold, italic, underline
* Font colors and sizes
* Bullet and numbered lists
* Hyperlinks
* Tables
* Paragraph spacing

**Notes:**

* Use **three** curly braces: `{{{!Field}}}`
* Images in rich text only supported in PDF and DOCX formats
* Alternative: Use `type="rtf"` column attribute in related lists
* HTML is rendered as-is without escaping

***

### Related List Column Attributes

#### substitute

**Purpose:** Replace entire field values with alternative text based on matching

**Syntax:**

```
<column substitute="match1,replace1,match2,replace2,...,catchAll">FieldName</column>
```

**Basic Examples:**

```
<!-- Boolean values -->
<column substitute="true,Yes,false,No">IsActive__c</column>

<!-- Status codes -->
<column substitute="1,Pending,2,Approved,3,Rejected,Unknown">Status_Code__c</column>

<!-- With catch-all -->
<column substitute="Hot,High Priority,Warm,Medium,Cold,Low,Not Rated">Rating</column>
```

**Translation Example:**

```
<!-- German translation -->
<column substitute="true,Ja,false,Nein">checkbox__c</column>

<!-- Month numbers to names -->
<column substitute="1,January,2,February,3,March,4,April,5,May,6,June,7,July,8,August,9,September,10,October,11,November,12,December,Unknown">Month_Number__c</column>
```

**Organized with Parentheses:**

```
<column substitute="(1,one),(2,two),(3,three),(catchall)">Number__c</column>
```

**Notes:**

* Matches **entire field value** (not substrings)
* Matching is case-insensitive
* Whitespace is trimmed before matching
* Replacement values are exact (preserve case)
* Odd number of values: last value is catch-all
* Use `true`/`false` for checkbox/boolean fields
* For null values, use `nullprefix` instead
* Numeric values must match precision exactly

***

#### replaceall (column-level)

**Purpose:** Replace substrings within field values (not entire values)

**Syntax:**

```
<column replaceall="find1,replace1,find2,replace2,...">FieldName</column>
```

**Basic Examples:**

```
<!-- Replace company abbreviations -->
<column replaceall="Burlington,Boston">AccountName</column>

<!-- Replace multiple terms -->
<column replaceall="Inc,Incorporated,Ltd,Limited,Corp,Corporation">Company_Name__c</column>
```

**Regex Examples:**

```
<!-- Indent lettered lists -->
<column replaceall="[regex]([a-zA-Z]\)),&nbsp;&nbsp;&nbsp;&nbsp;$1">Description</column>

<!-- Remove all digits -->
<column replaceall="[regex]\d,">ProductCode</column>
```

**Regex Syntax:**

* Start with `[regex]` (including brackets)
* Use standard regex patterns
* Capture groups with `( )`
* Reference with `$1`, `$2`, etc.

**Difference from Substitute:**

| Feature          | substitute       | replaceall  |
| ---------------- | ---------------- | ----------- |
| Matches          | Entire value     | Substrings  |
| Multiple matches | First match only | All matches |
| Catch-all        | Yes              | No          |
| Regex support    | No               | Yes         |

**Notes:**

* Replaces **all occurrences** of substring
* No catch-all/"else" condition
* Supports regular expressions
* Useful for text cleanup and formatting

***

#### showcolumn

**Purpose:** Conditionally show or hide entire table columns

**Syntax:**

```
<column showcolumn="condition">FieldName</column>
```

**Basic Examples:**

```
<!-- Show only for specific stage -->
<column showcolumn="{{!Opportunity.StageName}} == 'Prospecting'">Next_Steps__c</column>

<!-- Hide for closed opportunities -->
<column showcolumn="{{!Opportunity.StageName}} != 'Closed Won'">Expected_Close_Date__c</column>
```

**Multiple Conditions:**

```
<!-- OR condition -->
<column showcolumn="({{!Opportunity.StageName}} == 'Prospecting' || {{!Opportunity.StageName}} == 'Qualification')">Probability__c</column>

<!-- AND condition -->
<column showcolumn="({{!Opportunity.Amount}} > 10000 && {{!Opportunity.Type}} == 'New Business')">Discount__c</column>
```

**With Header Row:**

```
<thead>
  <tr>
    <th>Product</th>
    <th>Price</th>
    <!--RENDER='{{!Opportunity.Type}}' == 'New Business'-->
    <th>Discount</th>
    <!--ENDRENDER-->
  </tr>
</thead>
<tbody>
<!--{{!
<lineitems>
<listname>opportunitylineitems</listname>
<column>PricebookEntry.Product2.name</column>
<column>unitprice</column>
<column showcolumn="{{!Opportunity.Type}} == 'New Business'">Discount</column>
</lineitems>
}}-->
</tbody>
```

**Supported Operators:**

| Operator | Meaning          | Example                 |
| -------- | ---------------- | ----------------------- |
| `==`     | Equals           | `{{!Field}} == 'Value'` |
| `!=`     | Not equals       | `{{!Field}} != 'Value'` |
| `>`      | Greater than     | `{{!Field}} > 100`      |
| `<`      | Less than        | `{{!Field}} < 100`      |
| `>=`     | Greater or equal | `{{!Field}} >= 100`     |
| `<=`     | Less or equal    | `{{!Field}} <= 100`     |
| `\|`     | OR               | `(cond1 \| cond2)`      |
| `&&`     | AND              | `(cond1 && cond2)`      |

**Notes:**

* Column is hidden when condition evaluates to false
* Apply same condition to header using `<!--RENDER=...-->`
* Wrap OR/AND conditions in parentheses
* Conditions reference the parent object, not list records

***

#### type

**Purpose:** Control how field content renders in columns

**Supported Values:** `rtf`, `text`, `checkbox`, `radio`

**Syntax:**

```
<column type="value">FieldName</column>
```

**RTF (Rich Text Format):**

```
<column type="rtf">Description__c</column>
```

* Preserves HTML markup and formatting
* Shows bold, italic, links, lists

**Text:**

```
<column type="text">Rich_Notes__c</column>
```

* Strips all HTML tags
* Shows only plain text

**Checkbox:**

```
<column type="checkbox">IsActive__c</column>
```

* Displays checkbox image instead of true/false
* Checked: ☑
* Unchecked: ☐
* Not supported in DOCX format

**Radio:**

```
<column type="radio">IsSelected__c</column>
```

* Displays radio button instead of true/false
* Selected: ⦿
* Unselected: ○
* Not supported in DOCX format

**Custom Checkbox Styling:**

```
<style type="text/css">
.sdcheckbox {
  width: 12px;
  height: 12px;
  border: 2px solid #73AD21;
}
</style>
```

**Notes:**

* `type="checkbox"` and `type="radio"` work in PDF only
* Checkbox/radio images have CSS class `sdcheckbox`
* Use `type="text"` to strip HTML from rich text fields
* Use `type="rtf"` to preserve formatting

***

#### header

**Purpose:** Specify custom column header text

**Syntax:**

```
<column header="Header Text">FieldName</column>
```

**Examples:**

```
<column header="Product Name">PricebookEntry.Product2.name</column>
<column header="Qty">quantity</column>
<column header="Price Each">unitprice</column>
<column header="Line Total">totalprice</column>
<column header="Grand Total">SUM_totalprice</column>
```

**Notes:**

* Overrides default field name headers
* Use for user-friendly column names
* Accepts any text string
* Can include special characters and spaces

***

#### format-number (column-level)

**Purpose:** Format numeric columns with thousands separators and decimals

**Syntax:**

```
<column format-number="pattern">NumericField</column>
```

**Supported Patterns:**

| Pattern    | Description            | Input  | Output   |
| ---------- | ---------------------- | ------ | -------- |
| `#,###`    | Thousands separator    | 123456 | 123,456  |
| `#,###.##` | Thousands + decimals   | 123456 | 1,234.56 |
| `#.###`    | European thousands     | 123456 | 123.456  |
| `#.###,##` | European with decimals | 123456 | 1.234,56 |

**Examples:**

```
<column format-number="#,###.##">unitprice</column>
<column format-number="#,###">quantity</column>
<column format-number="#.###,##">Amount__c</column>
```

**With Prefix:**

```
<column prefix="$" format-number="#,###.##">totalprice</column>
```

**Notes:**

* Works with all numeric field types
* Applies to every row in the column
* Combine with `prefix`/`postfix` for currency symbols
* Rounding occurs when precision exceeds format

***

#### format-date (column-level)

**Purpose:** Format date columns using Java patterns

**Syntax:**

```
<column format-date="pattern">DateField</column>
```

**Common Patterns:**

| Pattern         | Output           |
| --------------- | ---------------- |
| `MM/dd/yyyy`    | 04/04/2017       |
| `dd/MM/yyyy`    | 04/04/2017       |
| `MMMM dd, yyyy` | October 28, 2018 |
| `MMMM`          | October          |
| `yyyy`          | 2018             |

**Examples:**

```
<column format-date="MM/dd/yyyy">CreatedDate</column>
<column format-date="MMMM">CloseDate</column>
<column format-date="dd.MM.yyyy">LastModifiedDate</column>
```

**Notes:**

* Follows same patterns as merge field `format-date`
* Patterns are case-sensitive
* Month/day names in English only
* Extract month, day, or year individually

***

#### mergenext

**Purpose:** Merge a column cell with the cell immediately to its right

**Syntax:**

```
<column mergenext="true">FieldName</column>
```

**Examples:**

```
<!-- Currency symbol + amount -->
<column prefix="$" mergenext="true"></column>
<column format-number="#,###.##">Amount</column>
<!-- Result: $12.99 in single cell -->

<!-- Label + value -->
<column postfix=": " mergenext="true">Label__c</column>
<column>Value__c</column>
<!-- Result: "Label: Value" in single cell -->
```

**Notes:**

* Combines current cell with next cell horizontally
* Use `prefix`/`postfix` for spacing between merged content
* Not supported with group-by functionality
* Useful for combining related data points

***

#### colspan

**Purpose:** Make a column span multiple columns horizontally

**Syntax:**

```
<column colspan="number">FieldName</column>
```

**Examples:**

```
<!-- Span 3 columns -->
<column colspan="3">Description__c</column>

<!-- Span entire row (if 5 columns total) -->
<column colspan="5">Header_Text__c</column>
```

**With Headers:**

```
<thead>
  <tr>
    <th colspan="3">Product Information</th>
    <th colspan="2">Pricing</th>
  </tr>
  <tr>
    <th>Name</th>
    <th>Code</th>
    <th>Desc</th>
    <th>Unit Price</th>
    <th>Total</th>
  </tr>
</thead>
```

**Notes:**

* `colspan="1"` has no effect (default)
* Works like HTML colspan attribute
* Useful for section headers and grouping
* Column spans specified number of columns total

***

#### newrow

**Purpose:** Create new table rows at specified intervals

**Syntax:**

```
<column newrow="value">FieldName</column>
```

**Values:**

* `true` - New row for each record
* `number` - New row after every N records

**Examples:**

```
<!-- Mailing labels: 3 per row -->
<column newrow="3">
  Name<br>
  MailingStreet<br>
  MailingCity, MailingState MailingPostalCode
</column>

<!-- Each record on new row -->
<column newrow="true">ProductName</column>
<column>Description</column>
<column>Price</column>
```

**Mailing Label Example:**

```
<table>
<!--{{!
<lineitems>
<listname>contacts</listname>
<column newrow="3">
  Name<br>
  MailingStreet<br>
  MailingCity, MailingState MailingPostalCode
</column>
</lineitems>
}}-->
</table>
```

**Output:**

```
| Label 1 | Label 2 | Label 3 |
| Label 4 | Label 5 | Label 6 |
```

**Notes:**

* `newrow="true"` creates vertical layout
* `newrow="3"` creates 3-column grid
* Useful for labels, badges, cards
* Affects table row structure

***

#### prefix

**Purpose:** Add text before each non-null column value

**Syntax:**

```
<column prefix="text">FieldName</column>
```

**Examples:**

```
<column prefix="$">Amount</column>
<!-- Result: $12.99 -->

<column prefix="Item #">ProductCode</column>
<!-- Result: Item #ABC123 -->

<column prefix="Email: ">Email__c</column>
<!-- Result: Email: user@example.com -->
```

**Notes:**

* Only appears for non-null values
* For null values, use `nullprefix`
* For all values regardless, use `allprefix`
* Can include spaces and special characters

***

#### nullprefix

**Purpose:** Add text before null column values

**Syntax:**

```
<column nullprefix="text">FieldName</column>
```

**Examples:**

```
<column nullprefix="N/A">OptionalField__c</column>
<!-- Shows "N/A" when field is null -->

<column nullprefix="TBD" format-date="MM/dd/yyyy">ExpectedDate__c</column>
<!-- Shows "TBD" when date is null -->

<column nullprefix="Not specified">Description__c</column>
<!-- Shows "Not specified" when field is null -->
```

**Notes:**

* Only appears for null values
* For non-null values, use `prefix`
* For all values, use `allprefix`
* Useful for providing defaults

***

#### postfix

**Purpose:** Add text after each non-null column value

**Syntax:**

```
<column postfix="text">FieldName</column>
```

**Examples:**

```
<column postfix=" units">Quantity</column>
<!-- Result: 5 units -->

<column postfix="%">Discount</column>
<!-- Result: 15% -->

<column postfix=", ">ProductName</column>
<!-- Result: Widget, (creates list) -->
```

**Notes:**

* Only appears for non-null values
* For null values, use `nullpostfix`
* For all values, use `allpostfix`
* Useful for units, separators, formatting

***

#### nullpostfix

**Purpose:** Add text after null column values

**Syntax:**

```
<column nullpostfix="text">FieldName</column>
```

**Examples:**

```
<column nullpostfix=" (not set)">OptionalField__c</column>
<!-- Shows "(not set)" when field is null -->

<column nullpostfix="N/A">Amount__c</column>
<!-- Shows "N/A" when amount is null -->
```

***

#### allprefix

**Purpose:** Add text before all column values (null and non-null)

**Syntax:**

```
<column allprefix="text">FieldName</column>
```

**Examples:**

```
<column allprefix="$">Amount__c</column>
<!-- Shows "$" even if amount is null -->

<column allprefix="Code: ">ProductCode__c</column>
<!-- Shows "Code: " even if code is null -->
```

**Notes:**

* Replaces need for both `prefix` and `nullprefix` when identical
* Always displays regardless of field value
* Simpler than using two separate attributes

***

#### allpostfix

**Purpose:** Add text after all column values (null and non-null)

**Syntax:**

```
<column allpostfix="text">FieldName</column>
```

**Examples:**

```
<column allpostfix="€">Price__c</column>
<!-- Shows "€" even if price is null -->

<column allpostfix=" items">Quantity__c</column>
<!-- Shows " items" even if quantity is null -->
```

**Notes:**

* Replaces need for both `postfix` and `nullpostfix` when identical
* Always displays regardless of field value

***

#### abfprefixouter

**Purpose:** Add text before all columns except the first one

**Syntax:**

```
<column abfprefixouter="text">FieldName</column>
```

**Use Case:** Creating comma-separated lists without leading comma

**Examples:**

```
<!--{{!
<lineitemsSOQL>
<class>none</class>
<soql>SELECT Name FROM Contact WHERE AccountId = '{{!Account.Id}}'</soql>
<column abfprefixouter=", ">Name</column>
</lineitemsSOQL>
}}-->
<!-- Result: John Smith, Jane Doe, Bob Johnson -->

<!--{{!
<lineitemsSOQL>
<prefix>Products: </prefix>
<class>none</class>
<soql>SELECT ProductCode FROM OpportunityLineItem WHERE OpportunityId = '{{!Opportunity.Id}}'</soql>
<column abfprefixouter=", ">ProductCode</column>
<postfix>.</postfix>
</lineitemsSOQL>
}}-->
<!-- Result: Products: ABC, DEF, GHI. -->
```

**Notes:**

* Prefix appears on all items except first
* Prevents leading separator in lists
* String appears **outside** of any `prefix` attribute
* Use with `<class>none</class>` for custom formatting

***

#### startIndex

**Purpose:** Offset row numbering when using `rownum` column

**Syntax:**

```
<column startIndex="number">rownum</column>
```

**Examples:**

```
<!-- Start numbering at 1 (default) -->
<column>rownum</column>
<!-- Result: 1, 2, 3, 4... -->

<!-- Start numbering at 10 -->
<column startIndex="9">rownum</column>
<!-- Result: 10, 11, 12, 13... -->

<!-- Start numbering at 100 -->
<column startIndex="99">rownum</column>
<!-- Result: 100, 101, 102, 103... -->
```

**Complete Example:**

```
<!--{{!
<lineitems>
<listname>opportunitylineitems</listname>
<column startIndex="9" header="Item #">rownum</column>
<column header="Product">PricebookEntry.Product2.name</column>
<column header="Price" prefix="$" format-number="#,###.##">unitprice</column>
</lineitems>
}}-->
```

**Notes:**

* Numbering starts at `startIndex + 1`
* `startIndex="0"` starts at 1
* `startIndex="5"` starts at 6
* Use with `rownum` special column
* Useful for continuing numbering across sections

***

#### render

**Purpose:** Conditionally render different values based on multiple conditions

**Syntax:**

```
<column render="CONDITION_1,output1,CONDITION_2,output2,...,defaultOutput"></column>
```

**Requirements:**

* Only works with `<lineitemsSOQL>` (not `<lineitems>`)
* Must use `<soql>...</soql>` tags
* Include all referenced fields in SOQL query
* Don't specify field between `<column></column>` tags
* Use `RECORD.FieldName` to reference row data
* Escape HTML tags: `lt#` for `<`, `gt#` for `>`

**Basic Examples:**

```
<!-- Null handling -->
<column render="RECORD.Title==null,No Title,RECORD.Title"></column>

<!-- Status display -->
<column render="RECORD.Status__c == 'Active',✓ Active,RECORD.Status__c == 'Inactive',✗ Inactive,Pending"></column>

<!-- Conditional formatting -->
<column type="rtf" render="RECORD.Amount__c > 10000,lt#span style='color:green;'gt#High Valuelt#/spangt#,lt#span style='color:red;'gt#Low Valuelt#/spangt#"></column>
```

**String Matching:**

```
<!-- STARTSWITH -->
<column render="RECORD.Name STARTSWITH 'Pro',Professional,Standard"></column>

<!-- ENDSWITH -->
<column render="RECORD.Email ENDSWITH '@company.com',Internal,External"></column>

<!-- Combined conditions -->
<column render="RECORD.Type__c STARTSWITH 'A' && RECORD.Status__c == 'Active',Category A Active,Other"></column>
```

**Nested Renders:**

```
<column render="RECORD.Country__c == 'USA',[RENDER1]RECORD.State__c == 'CA',California,[RENDER2]RECORD.State__c == 'NY',New York,[ENDRENDER2][ENDRENDER1],International"></column>
```

**With Formatting:**

```
<!--{{!
<lineitemsSOQL>
<soql>SELECT Name, StageName, Amount FROM Opportunity WHERE AccountId = '{{!Account.Id}}'</soql>
<column>Name</column>
<column type="rtf" render="RECORD.StageName == 'Closed Won',lt#span style='color:green; font-weight:bold;'gt#✓ Wonlt#/spangt#,RECORD.StageName == 'Closed Lost',lt#span style='color:red;'gt#✗ Lostlt#/spangt#,In Progress"></column>
<column prefix="$" format-number="#,###.##">Amount</column>
</lineitemsSOQL>
}}-->
```

**Supported Operators:**

| Operator     | Meaning       | Example                        |
| ------------ | ------------- | ------------------------------ |
| `==`         | Equals        | `RECORD.Status == 'Active'`    |
| `!=`         | Not equals    | `RECORD.Type != 'Closed'`      |
| `>`          | Greater than  | `RECORD.Amount > 1000`         |
| `<`          | Less than     | `RECORD.Amount < 100`          |
| `>=`         | Greater/equal | `RECORD.Amount >= 1000`        |
| `<=`         | Less/equal    | `RECORD.Amount <= 100`         |
| `&&`         | AND           | `(cond1 && cond2)`             |
| `\|`         | OR            | `(cond1 \| cond2)`             |
| `STARTSWITH` | Begins with   | `RECORD.Name STARTSWITH 'Pro'` |
| `ENDSWITH`   | Ends with     | `RECORD.Email ENDSWITH '.com'` |

**HTML Escaping:**

| Character | Escape Code |
| --------- | ----------- |
| `<`       | `lt#`       |
| `>`       | `gt#`       |
| `"`       | `quot#`     |
| `'`       | `apos#`     |
| `&`       | `amp#`      |

**Notes:**

* Evaluates conditions left to right
* First matching condition wins
* Last value is default (when no conditions match)
* Can nest up to 3 levels deep
* Use for complex conditional logic in tables

***

#### breakeverynchars (column-level)

**Purpose:** Insert line breaks in column text after specified character count

**Syntax:**

```
<column breakeverynchars="number">FieldName</column>
```

**Examples:**

```
<column breakeverynchars="10">Long_Code__c</column>
<column breakeverynchars="20">URL__c</column>
<column breakeverynchars="50">Description__c</column>
```

**Input/Output:**

```
Input:  ABCDEFGHIJKLMNOPQRSTUVWXYZ
Output: ABCDEFGHIJ KLMNOPQRST UVWXYZ
```

**Notes:**

* Inserts space after every N characters
* Allows text to wrap naturally
* Useful for long URLs, codes, serial numbers
* Works in both PDF and DOCX formats

***

#### addToEmail

**Purpose:** Add email addresses from column as document recipients

**Syntax:**

```
<column addToEmail="To|CC|BCC">EmailField</column>
```

**Values:**

* `To` - Primary recipients
* `CC` - Carbon copy
* `BCC` - Blind carbon copy

**Examples:**

```
<!-- Add creators as CC -->
<column addToEmail="CC">CreatedBy.Email</column>

<!-- Add contacts as primary recipients -->
<column addToEmail="To">Email</column>

<!-- Add account team as BCC -->
<column addToEmail="BCC">User.Email</column>
```

**Complete Example:**

```
<!--{{!
<lineitemsSOQL>
<class>none</class>
<soql>SELECT Email FROM Contact WHERE AccountId = '{{!Account.Id}}' AND Email != null</soql>
<column addToEmail="To">Email</column>
</lineitemsSOQL>
}}-->
```

**Notes:**

* Must also add as apex parameter to S-Docs button URL
* Only includes non-null email addresses
* Can use with any object that has email fields
* Multiple rows can add multiple recipients

***

#### blobToString (column-level)

**Purpose:** Convert HTML-based blob content to strings in columns

**Syntax:**

```
<column blobToString="true">BlobField</column>
```

**Examples:**

```
<column blobToString="true">ContentVersion.VersionData</column>
<column blobToString="true">Attachment.Body</column>
```

**Notes:**

* Blob content must be convertible to string or well-formed HTML
* Also available as merge field attribute
* Will fail on binary data (images, PDFs, etc.)
* Useful for merging text file contents

***

### Special Column Keywords

#### rownum

**Purpose:** Display row numbers in related lists

**Syntax:**

```
<column>rownum</column>
<column startIndex="number">rownum</column>
```

**Examples:**

```
<!-- Basic row numbering -->
<column header="#">rownum</column>

<!-- Start at 10 -->
<column startIndex="9" header="Item #">rownum</column>

<!-- With formatting -->
<column prefix="Item " postfix=":" header="Line">rownum</column>
```

**Notes:**

* `rownum` is a reserved keyword, not a field name
* Numbering starts at 1 by default
* Use `startIndex` to offset
* Automatically increments for each row

***

### Removing Table Formatting

#### class="none"

**Purpose:** Remove default table formatting from related lists

**Syntax:**

```
<!--{{!
<lineitems>
<class>none</class>
...
</lineitems>
}}-->
```

**Example - Comma-Separated List:**

```
<!--{{!
<lineitemsSOQL>
<prefix>Team members: </prefix>
<class>none</class>
<soql>SELECT Name FROM Contact WHERE AccountId = '{{!Account.Id}}'</soql>
<column abfprefixouter=", ">Name</column>
<postfix>.</postfix>
</lineitemsSOQL>
}}-->
```

**Result:**

```
Team members: John Smith, Jane Doe, Bob Johnson.
```

**Example - Line Breaks:**

```
<!--{{!
<lineitemsSOQL>
<class>none</class>
<soql>SELECT Name, Title FROM Contact WHERE AccountId = '{{!Account.Id}}'</soql>
<column postfix=" - ">Name</column>
<column postfix="<br>">Title</column>
</lineitemsSOQL>
}}-->
```

**Result:**

```
John Smith - CEO
Jane Doe - CFO
```

**Notes:**

* Removes all table HTML (rows, cells, borders)
* Returns raw data on same line
* No spaces between values unless added with prefix/postfix
* Use `abfprefixouter` to create clean lists
* Combine with HTML formatting for custom layouts

***

### Attribute Compatibility

#### Format Support

| Attribute       | PDF | DOCX | HTML |
| --------------- | --- | ---- | ---- |
| format-number   | ✓   | ✓    | ✓    |
| format-date     | ✓   | ✓    | ✓    |
| checkbox        | ✓   | ✗    | ✓    |
| MICR            | ✓   | ✗    | ✗    |
| CR              | ✓   | ✗    | ✗    |
| RTL             | ✓   | ✓    | ✓    |
| translate       | ✓   | ✓    | ✓    |
| justifyNewLines | ✓   | ✗    | ✓    |

#### Field Type Compatibility

| Attribute               | Compatible Field Types                        |
| ----------------------- | --------------------------------------------- |
| format-number           | Number, Currency, Percent, Formula (Number)   |
| format-date             | Date, DateTime, Formula (Date/DateTime)       |
| checkbox                | Boolean, Checkbox                             |
| translate               | Picklist, Multi-Select Picklist               |
| ToUpperCase/ToLowerCase | Text, Text Area, Long Text, Email, Phone, URL |
| MICR/CR                 | Text, Text Area, Number                       |
| encrypt                 | Encrypted Text, Encrypted Text Area           |
| Display                 | Picklist, Multi-Select Picklist               |

***

### Quick Reference Tables

#### Number Formatting

| Need              | Pattern    | Example      |
| ----------------- | ---------- | ------------ |
| US Currency       | `#,###.##` | 4,222,300.80 |
| European Currency | `#.###,##` | 4.222.300,80 |
| Whole Number      | `#,###`    | 4,222,301    |
| European Whole    | `#.###`    | 4.222.301    |

#### Date Formatting

| Need           | Pattern               | Example                  |
| -------------- | --------------------- | ------------------------ |
| US Short       | `MM/dd/yyyy`          | 01/15/2024               |
| European Short | `dd.MM.yyyy`          | 15.01.2024               |
| Long           | `MMMM dd, yyyy`       | January 15, 2024         |
| Full           | `EEEE, MMMM dd, yyyy` | Monday, January 15, 2024 |
| Month Only     | `MMMM`                | January                  |
| Year Only      | `yyyy`                | 2024                     |

#### Checkbox Styles

| Style              | Appearance           | Use Case                   |
| ------------------ | -------------------- | -------------------------- |
| `checkbox="true"`  | Dotted border        | General forms              |
| `checkbox="black"` | Solid border, filled | Formal documents           |
| `checkbox="radio"` | Circle               | Mutually exclusive options |

#### Text Transformations

| Need          | Attribute            | Example         |
| ------------- | -------------------- | --------------- |
| Uppercase     | `ToUpperCase="true"` | MAIN STREET     |
| Lowercase     | `ToLowerCase="true"` | main street     |
| Right-to-Left | `RTL="true"`         | Reversed text   |
| Strip HTML    | `strip-html="true"`  | Plain text only |

#### Value Replacement

| Need           | Attribute    | Matches         |
| -------------- | ------------ | --------------- |
| Entire Value   | `substitute` | Whole field     |
| Substrings     | `replaceAll` | All occurrences |
| Translated     | `translate`  | Picklist values |
| Display Labels | `Display`    | API vs Label    |

***

This complete reference documents S-Docs template attributes for merge fields and related-list columns. Use alongside tutorials and how-to guides for applied examples.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.sdocs.com/developer-hub/template-configuration-and-styling/template-attributes-complete-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
