Lists
DocPayload supports ordered (numbered) and unordered (bulleted) lists. Each list item accepts any content node — paragraphs, headings, tables, columns, images, canvas, even nested lists — following HTML5 <li> flow-content semantics. Lists can also be populated dynamically from data.
Ordered lists
Use ol to create a numbered list.
{
"ol": {
"li": [
{ "p": "Verify package dimensions and weight." },
{ "p": "Print the shipping label." },
{ "p": "Drop off at the nearest collection point." }
]
}
}
Unordered lists
Use ul to create a bulleted list.
{
"ul": {
"li": [
{ "p": "Real-time shipment tracking" },
{ "p": "Multi-carrier rate comparison" },
{ "p": "Automated customs documentation" }
]
}
}
Properties
| Property | Type | Required | Description |
|---|---|---|---|
ol or ul | object | Yes | The list container |
li | array | Yes | Array of list item content elements |
symbol | string | No | Numbering style for ordered lists, or custom bullet for unordered lists |
style | string | No | Named style to apply to all list items |
Numbering styles
Control how ordered list items are numbered using the symbol property.
| Symbol | Output | Description |
|---|---|---|
"1" | 1. 2. 3. | Decimal numbers (default) |
"a" | a. b. c. | Lowercase letters |
"A" | A. B. C. | Uppercase letters |
"i" | i. ii. iii. | Lowercase Roman numerals |
"I" | I. II. III. | Uppercase Roman numerals |
"α" | α. β. γ. | Lowercase Greek |
"Α" | Α. Β. Γ. | Uppercase Greek |
{
"ol": {
"symbol": "A",
"li": [
{ "p": "First item" },
{ "p": "Second item" },
{ "p": "Third item" }
]
}
}
{
"ol": {
"symbol": "i",
"li": [
{ "p": "Section one" },
{ "p": "Section two" },
{ "p": "Section three" }
]
}
}
Custom bullet symbol
Override the default bullet character for unordered lists using the symbol property. Any string value is accepted.
{
"ul": {
"symbol": "-",
"li": [
{ "p": "Chicago hub" },
{ "p": "Denver hub" },
{ "p": "Dallas hub" }
]
}
}
Styling lists
Apply a named style to format all items in a list.
{
"ul": {
"li": [
{ "p": "Express delivery: 1-2 days" },
{ "p": "Standard delivery: 3-5 days" },
{ "p": "Economy delivery: 7-10 days" }
]
},
"style": "bodyText"
}
Individual list items can also reference their own styles:
{
"ul": {
"li": [
{ "p": "[b]Express delivery[/b]: 1-2 days", "style": "highlight" },
{ "p": "Standard delivery: 3-5 days" },
{ "p": "Economy delivery: 7-10 days" }
]
}
}
Nested lists
Place a list inside a list item to create multi-level nesting.
{
"ol": {
"li": [
{ "p": "Prepare shipment" },
{
"ul": {
"li": [
{ "p": "Verify dimensions" },
{ "p": "Weigh the package" },
{ "p": "Apply fragile stickers if needed" }
]
}
},
{ "p": "Generate shipping label" },
{ "p": "Schedule pickup" }
]
}
}
Lists inside table cells
Lists work inside table cells for structured layouts.
{
"table": {
"widths": [1, 2],
"rows": [
[
{ "p": "[b]Included Services[/b]" },
{
"ul": {
"li": [
{ "p": "Door-to-door delivery" },
{ "p": "Package insurance up to $5,000" },
{ "p": "SMS delivery notifications" }
]
}
}
],
[
{ "p": "[b]Setup Steps[/b]" },
{
"ol": {
"li": [
{ "p": "Create an account" },
{ "p": "Add your warehouse address" },
{ "p": "Configure carrier preferences" }
]
}
}
]
]
}
}
Data-driven lists
Lists can be populated from data arrays using source. The list's li array can be left empty — items are appended from the data.
Simple string arrays
When the data source is an array of strings, each string becomes a list item directly:
{
"ul": {
"source": "$data.notes"
}
}
With data { "notes": ["Payment due in 30 days", "Late fees apply", "Contact billing@acme.com"] }, this renders three bullet items.
For ordered lists:
{
"ol": {
"source": "$data.paymentTerms"
}
}
A list is either authored (you type its items via li) or data-driven (items come from source). The two are alternatives — you don't combine them:
- Authored — provide
liwith the items you want. - Data-driven — provide
source(and optionallymapto shape each item). Nolineeded.
symbol works the same way in both modes — set it on the list to pick the marker style (A, a, I, i, 1, custom bullet character, etc.). See Numbering styles for the full set.
$item.* templating in map
map is optional. Without it, a string-array source renders each string as an item directly. Use map when the source is an array of objects and you want to pick fields or compose templates from them:
{
"ul": {
"source": "$data.deliveries",
"map": "$item.date — $item.items ($item.warehouse)"
}
}
With data:
{
"deliveries": [
{ "date": "Jan 15", "items": "Electronics", "warehouse": "Chicago" },
{ "date": "Jan 18", "items": "Furniture", "warehouse": "Denver" }
]
}
This renders:
- Jan 15 — Electronics (Chicago)
- Jan 18 — Furniture (Denver)
Note: for lists, map is a single template string (not an array like tables) since each list item is one line.
Complete example: onboarding checklist
Template:
{
"document": {
"styles": {
"title": { "fontSize": 16, "bold": true, "marginBottom": 6 },
"section": { "fontSize": 12, "bold": true, "marginTop": 12, "marginBottom": 4 }
},
"content": [
{ "p": "Onboarding Checklist — $data.employee.name", "style": "title" },
{ "p": "Start date: $data.employee.startDate" },
{ "p": "Required Training", "style": "section" },
{
"ol": {
"source": "$data.training",
"map": "$item.course — Due by $item.deadline"
}
},
{ "p": "Equipment to Collect", "style": "section" },
{
"ul": { "source": "$data.equipment" }
},
{ "p": "Key Contacts", "style": "section" },
{
"ul": {
"source": "$data.contacts",
"map": "$item.name ($item.role) — $item.email"
}
}
]
}
}
Data:
{
"employee": { "name": "James Walker", "startDate": "March 3, 2026" },
"training": [
{ "course": "Security Awareness", "deadline": "Week 1" },
{ "course": "Code of Conduct", "deadline": "Week 1" },
{ "course": "Platform Overview", "deadline": "Week 2" }
],
"equipment": ["Laptop", "Monitor", "Security badge", "Parking pass"],
"contacts": [
{ "name": "Emily Chen", "role": "Manager", "email": "emily@acme.com" },
{ "name": "David Park", "role": "IT Support", "email": "david@acme.com" },
{ "name": "Rachel Torres", "role": "HR", "email": "rachel@acme.com" }
]
}
Expected result:
Required Training (ordered):
- Security Awareness — Due by Week 1
- Code of Conduct — Due by Week 1
- Platform Overview — Due by Week 2
Equipment to Collect (unordered, simple strings):
- Laptop
- Monitor
- Security badge
- Parking pass
Key Contacts (unordered, $item.* composed):
- Emily Chen (Manager) — emily@acme.com
- David Park (IT Support) — david@acme.com
- Rachel Torres (HR) — rachel@acme.com
See Data Source for more on data-driven content.
Inline formatting in list items
List items support the full range of inline formatting tags.
{
"ul": {
"li": [
{ "p": "[fontcolor, #27AE60][b]Active[/b][/fontcolor] -- Chicago Distribution Center" },
{ "p": "[fontcolor, #E74C3C][b]Offline[/b][/fontcolor] -- Seattle Warehouse" },
{ "p": "[fontcolor, #F39C12][b]Maintenance[/b][/fontcolor] -- Dallas Sorting Facility" }
]
}
}