templates support
This commit is contained in:
897
template_syntax.md
Normal file
897
template_syntax.md
Normal file
@@ -0,0 +1,897 @@
|
||||
# Receipt Template Language (RTL) Syntax Documentation
|
||||
|
||||
This document describes the syntax for creating receipt templates used by the Epson thermal printer template engine.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Basic Text](#basic-text)
|
||||
3. [Data Bindings](#data-bindings)
|
||||
4. [Styled Text](#styled-text)
|
||||
5. [Separators](#separators)
|
||||
6. [Comments](#comments)
|
||||
7. [Conditionals](#conditionals)
|
||||
8. [Loops](#loops)
|
||||
9. [Rows and Columns](#rows-and-columns)
|
||||
10. [Complete Example](#complete-example)
|
||||
11. [Printer Profiles](#printer-profiles)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
RTL is a line-based template language designed for thermal receipt printers. Templates are plain text files with embedded directives, bindings, and style markers that get transformed into printer commands.
|
||||
|
||||
**File Extension:** `.template`
|
||||
|
||||
**Key Concepts:**
|
||||
- Templates are processed line by line
|
||||
- Data is provided as JSON and accessed via bindings `{path}`
|
||||
- Styles are applied using `#style# text #` syntax
|
||||
- Control flow uses `@directive` syntax
|
||||
|
||||
---
|
||||
|
||||
## Basic Text
|
||||
|
||||
Plain text is output directly to the printer.
|
||||
|
||||
```
|
||||
Hello World
|
||||
This is plain text
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Hello World
|
||||
This is plain text
|
||||
```
|
||||
|
||||
### Empty Lines
|
||||
|
||||
Empty lines in templates produce empty lines on the receipt.
|
||||
|
||||
```
|
||||
Line 1
|
||||
|
||||
Line 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Bindings
|
||||
|
||||
Bindings insert values from the JSON data into the output.
|
||||
|
||||
### Simple Binding
|
||||
|
||||
```
|
||||
{PropertyName}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"PropertyName": "Hello"}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Hello
|
||||
```
|
||||
|
||||
### Nested Properties
|
||||
|
||||
Use dot notation to access nested objects.
|
||||
|
||||
```
|
||||
{Customer.Name}
|
||||
{Order.Items.0.Name}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"Customer": {"Name": "John Doe"},
|
||||
"Order": {"Items": [{"Name": "Coffee"}]}
|
||||
}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
John Doe
|
||||
Coffee
|
||||
```
|
||||
|
||||
### Format Specifiers
|
||||
|
||||
Add a format string after a colon to format numbers and dates.
|
||||
|
||||
#### Numeric Formats
|
||||
|
||||
```
|
||||
Total: {Amount:F2}
|
||||
Order #: {OrderNumber:D4}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"Amount": 19.5, "OrderNumber": 42}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Total: 19.50
|
||||
Order #: 0042
|
||||
```
|
||||
|
||||
| Format | Description | Example Input | Output |
|
||||
|--------|-------------|---------------|--------|
|
||||
| `F2` | Fixed-point, 2 decimals | 19.5 | 19.50 |
|
||||
| `F0` | Fixed-point, no decimals | 19.5 | 20 |
|
||||
| `D4` | Decimal, padded to 4 digits | 42 | 0042 |
|
||||
| `N2` | Number with grouping | 1234.5 | 1,234.50 |
|
||||
|
||||
#### Date/Time Formats
|
||||
|
||||
```
|
||||
Date: {TransactionDateTime:dd-MMM-yy}
|
||||
Time: {TransactionDateTime:HH:mm}
|
||||
Full: {TransactionDateTime:yyyy-MM-dd HH:mm:ss}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"TransactionDateTime": "2024-03-15T14:30:00"}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Date: 15-Mar-24
|
||||
Time: 14:30
|
||||
Full: 2024-03-15 14:30:00
|
||||
```
|
||||
|
||||
| Format | Description | Example Output |
|
||||
|--------|-------------|----------------|
|
||||
| `dd-MMM-yy` | Day-Month-Year | 15-Mar-24 |
|
||||
| `dd/MM/yyyy` | European date | 15/03/2024 |
|
||||
| `MM/dd/yyyy` | US date | 03/15/2024 |
|
||||
| `HH:mm` | 24-hour time | 14:30 |
|
||||
| `hh:mm tt` | 12-hour time | 02:30 PM |
|
||||
|
||||
### Array Count
|
||||
|
||||
Access the count/length of an array.
|
||||
|
||||
```
|
||||
Items: {Items.count}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"Items": ["A", "B", "C"]}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Items: 3
|
||||
```
|
||||
|
||||
### Missing Values
|
||||
|
||||
If a binding path doesn't exist or is null, an empty string is output.
|
||||
|
||||
```
|
||||
Name: {MissingProperty}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Name:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Styled Text
|
||||
|
||||
Apply formatting styles to text using the `#styles# content #` syntax.
|
||||
|
||||
### Basic Syntax
|
||||
|
||||
```
|
||||
#style1,style2# text content #
|
||||
```
|
||||
|
||||
The styles are comma-separated and applied to all content between the markers.
|
||||
|
||||
### Available Styles
|
||||
|
||||
| Style | Description | PrintCommand Property |
|
||||
|-------|-------------|----------------------|
|
||||
| `bold` | Bold text | `IsBold = true` |
|
||||
| `big` | Double-width and double-height | `IsBig = true` |
|
||||
| `tall` | Double-height only | `IsTall = true` |
|
||||
| `red` | Red color (if printer supports) | `IsRed = true` |
|
||||
| `center` | Center-align text | Text padded with spaces |
|
||||
| `right` | Right-align text | Text padded with spaces |
|
||||
| `left` | Left-align text (default) | No padding |
|
||||
| `spacing:N` | Set line spacing to N | `SetLineSpacing = N` |
|
||||
|
||||
### Examples
|
||||
|
||||
#### Bold Text
|
||||
```
|
||||
#bold# Important Notice #
|
||||
```
|
||||
|
||||
#### Centered Title
|
||||
```
|
||||
#center# RECEIPT #
|
||||
```
|
||||
|
||||
#### Combined Styles
|
||||
```
|
||||
#bold,big,center# RESTAURANT NAME #
|
||||
```
|
||||
|
||||
#### Red Text (Impact Printers)
|
||||
```
|
||||
#red,bold# WARNING #
|
||||
```
|
||||
|
||||
#### With Bindings
|
||||
```
|
||||
#bold,center# {Title} #
|
||||
#big# Table: {TableNumber} #
|
||||
```
|
||||
|
||||
#### Line Spacing
|
||||
```
|
||||
#spacing:50# Spaced text #
|
||||
```
|
||||
|
||||
### Style Scope
|
||||
|
||||
Styles apply only to content within the markers on the same line.
|
||||
|
||||
```
|
||||
#bold# This is bold # but this is not
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Separators
|
||||
|
||||
Create horizontal lines using repeated characters.
|
||||
|
||||
### Dash Separator
|
||||
```
|
||||
---
|
||||
```
|
||||
Output: `------------------------------------------------` (full line width)
|
||||
|
||||
### Equals Separator
|
||||
```
|
||||
===
|
||||
```
|
||||
Output: `================================================`
|
||||
|
||||
### Star Separator
|
||||
```
|
||||
***
|
||||
```
|
||||
Output: `************************************************`
|
||||
|
||||
### Tilde Separator
|
||||
```
|
||||
~~~
|
||||
```
|
||||
Output: `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
|
||||
|
||||
**Note:** Separator width automatically matches the printer's line width (48 chars for TM-T30III, 33 chars for TM-U220II).
|
||||
|
||||
---
|
||||
|
||||
## Comments
|
||||
|
||||
Add comments to templates for documentation purposes. Comments are stripped during parsing and do not appear in the output.
|
||||
|
||||
### Single-Line Comment
|
||||
|
||||
Use `@*` at the start of a line to comment out the entire line.
|
||||
|
||||
```
|
||||
@* This is a single-line comment
|
||||
Regular text here
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Regular text here
|
||||
```
|
||||
|
||||
### Inline Comment
|
||||
|
||||
Use `@* ... *@` to create a comment that can have content after it on the same line.
|
||||
|
||||
```
|
||||
@* This is a comment *@
|
||||
@* Header section *@
|
||||
#bold,center# Title #
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
|
||||
Title
|
||||
```
|
||||
|
||||
### Multi-Line Comment
|
||||
|
||||
Use `@*` on its own line to start a multi-line comment block, and `*@` to close it.
|
||||
|
||||
```
|
||||
@*
|
||||
This is a multi-line comment.
|
||||
All these lines are ignored.
|
||||
Directives like @if are also ignored here.
|
||||
*@
|
||||
This text appears in output
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
This text appears in output
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
#### Document Template Sections
|
||||
```
|
||||
@* === HEADER SECTION === *@
|
||||
#bold,center# {Title} #
|
||||
---
|
||||
|
||||
@* === ITEMS SECTION === *@
|
||||
@foreach item in Items
|
||||
{item.Name}
|
||||
@end
|
||||
```
|
||||
|
||||
#### Temporarily Disable Code
|
||||
```
|
||||
@*
|
||||
@if DebugMode
|
||||
Debug info: {DebugData}
|
||||
@end
|
||||
*@
|
||||
```
|
||||
|
||||
#### Add Notes for Maintainers
|
||||
```
|
||||
@* Note: This section only shows for orders over $100 *@
|
||||
@if Total > 100
|
||||
#bold# Large Order #
|
||||
@end
|
||||
```
|
||||
|
||||
### Important Notes
|
||||
|
||||
- Comments must start at the beginning of a line (after optional whitespace)
|
||||
- `@*` mid-line in content is treated as regular text, not a comment
|
||||
- Star separators (`***`) are not confused with comments
|
||||
- Unclosed multi-line comments produce a lexer error
|
||||
|
||||
---
|
||||
|
||||
## Conditionals
|
||||
|
||||
Control which content is rendered based on data values.
|
||||
|
||||
### Basic If
|
||||
|
||||
```
|
||||
@if Condition
|
||||
Content shown when true
|
||||
@end
|
||||
```
|
||||
|
||||
### If-Else
|
||||
|
||||
```
|
||||
@if HasDiscount
|
||||
Discount Applied!
|
||||
@else
|
||||
No Discount
|
||||
@end
|
||||
```
|
||||
|
||||
### If-ElseIf-Else
|
||||
|
||||
```
|
||||
@if Status == "pending"
|
||||
Order Pending
|
||||
@elseif Status == "complete"
|
||||
Order Complete
|
||||
@else
|
||||
Unknown Status
|
||||
@end
|
||||
```
|
||||
|
||||
### Truthy/Falsy Values
|
||||
|
||||
The following are considered **falsy**:
|
||||
- `null` or missing property
|
||||
- `false`
|
||||
- Empty string `""`
|
||||
- Number `0`
|
||||
- Empty array `[]`
|
||||
|
||||
Everything else is **truthy**.
|
||||
|
||||
### Comparison Operators
|
||||
|
||||
| Operator | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `==` | Equal | `Status == "active"` |
|
||||
| `!=` | Not equal | `Type != "void"` |
|
||||
| `>` | Greater than | `Amount > 100` |
|
||||
| `<` | Less than | `Count < 5` |
|
||||
| `>=` | Greater or equal | `Total >= 50` |
|
||||
| `<=` | Less or equal | `Qty <= 10` |
|
||||
|
||||
### Negation
|
||||
|
||||
```
|
||||
@if !IsVoided
|
||||
Valid Order
|
||||
@end
|
||||
```
|
||||
|
||||
### String Literals
|
||||
|
||||
Use quotes for string comparisons.
|
||||
|
||||
```
|
||||
@if Status == "active"
|
||||
Active
|
||||
@end
|
||||
```
|
||||
|
||||
### Numeric Comparisons
|
||||
|
||||
```
|
||||
@if Amount > 100
|
||||
Large Order
|
||||
@end
|
||||
|
||||
@if Items.count > 0
|
||||
Has Items
|
||||
@end
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
#### Check for Optional Field
|
||||
```
|
||||
@if SpecialInstruction
|
||||
#bold# Note: {SpecialInstruction} #
|
||||
@end
|
||||
```
|
||||
|
||||
#### Check Array Has Items
|
||||
```
|
||||
@if Modifications.count > 0
|
||||
Modifications:
|
||||
@foreach mod in Modifications
|
||||
- {mod}
|
||||
@end
|
||||
@end
|
||||
```
|
||||
|
||||
#### Conditional Separator
|
||||
```
|
||||
@if Items.count > 0
|
||||
---
|
||||
@end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Loops
|
||||
|
||||
Iterate over arrays in the data.
|
||||
|
||||
### Basic Foreach
|
||||
|
||||
```
|
||||
@foreach item in Items
|
||||
{item}
|
||||
@end
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"Items": ["Apple", "Banana", "Cherry"]}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Apple
|
||||
Banana
|
||||
Cherry
|
||||
```
|
||||
|
||||
### Object Properties
|
||||
|
||||
```
|
||||
@foreach product in Products
|
||||
{product.Name} - {product.Price:F2}
|
||||
@end
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"Products": [
|
||||
{"Name": "Coffee", "Price": 3.50},
|
||||
{"Name": "Tea", "Price": 2.50}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Coffee - 3.50
|
||||
Tea - 2.50
|
||||
```
|
||||
|
||||
### Nested Loops
|
||||
|
||||
```
|
||||
@foreach category in Categories
|
||||
#bold# {category.Name} #
|
||||
@foreach item in category.Items
|
||||
{item.Name}
|
||||
@end
|
||||
@end
|
||||
```
|
||||
|
||||
### Loop Metadata Variables
|
||||
|
||||
Inside a loop, these special variables are available:
|
||||
|
||||
| Variable | Description | Example Value |
|
||||
|----------|-------------|---------------|
|
||||
| `_index` | Zero-based index | 0, 1, 2, ... |
|
||||
| `_number` | One-based number | 1, 2, 3, ... |
|
||||
| `_first` | True if first item | true/false |
|
||||
| `_last` | True if last item | true/false |
|
||||
| `_count` | Total items in collection | 5 |
|
||||
|
||||
#### Examples
|
||||
|
||||
```
|
||||
@foreach item in Items
|
||||
{_number}. {item.Name}
|
||||
@end
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
1. Apple
|
||||
2. Banana
|
||||
3. Cherry
|
||||
```
|
||||
|
||||
```
|
||||
@foreach item in Items
|
||||
{item}
|
||||
@if !_last
|
||||
---
|
||||
@end
|
||||
@end
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Apple
|
||||
---
|
||||
Banana
|
||||
---
|
||||
Cherry
|
||||
```
|
||||
|
||||
### Nested Path Collections
|
||||
|
||||
```
|
||||
@foreach dish in Order.Kitchen.Dishes
|
||||
{dish.Name}
|
||||
@end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rows and Columns
|
||||
|
||||
Create tabular layouts with fixed-width columns.
|
||||
|
||||
### Basic Row
|
||||
|
||||
```
|
||||
@row
|
||||
|width|content|width|content
|
||||
@endrow
|
||||
```
|
||||
|
||||
### Column Syntax
|
||||
|
||||
```
|
||||
|width|content
|
||||
|width,alignment|content
|
||||
```
|
||||
|
||||
- **width**: Number of characters for the column
|
||||
- **alignment**: `left` (default), `right`, or `center`
|
||||
|
||||
### Examples
|
||||
|
||||
#### Two Columns
|
||||
```
|
||||
@row
|
||||
|30|{Name}|10,right|{Price:F2}
|
||||
@endrow
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{"Name": "Coffee", "Price": 3.50}
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Coffee 3.50
|
||||
```
|
||||
|
||||
#### Three Columns
|
||||
```
|
||||
@row
|
||||
|5,right|{Qty}|25|{Name}|10,right|{Total:F2}
|
||||
@endrow
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
2 Espresso 7.00
|
||||
```
|
||||
|
||||
#### Header Row
|
||||
```
|
||||
@row
|
||||
|5|Qty|25|Item|10,right|Price
|
||||
@endrow
|
||||
===
|
||||
```
|
||||
|
||||
### Columns in Loops
|
||||
|
||||
```
|
||||
@foreach item in Items
|
||||
@row
|
||||
|5,right|{item.Quantity}|25|{item.Name}|10,right|{item.Price:F2}
|
||||
@endrow
|
||||
@end
|
||||
```
|
||||
|
||||
### Text Truncation
|
||||
|
||||
If content exceeds the column width, it is truncated.
|
||||
|
||||
```
|
||||
@row
|
||||
|10|VeryLongProductNameHere
|
||||
@endrow
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
VeryLongPr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
Here's a complete kitchen receipt template:
|
||||
|
||||
```
|
||||
#red,big,tall,center# {Title} #
|
||||
---
|
||||
|
||||
#center# {TransactionDateTime:dd-MMM-yy HH:mm} Nr.:{ReceiptNumber} #
|
||||
#center# {WaiterName} #
|
||||
#center# {WaiterId} #
|
||||
#big,bold,center# Tisch: {TableNumber} #
|
||||
|
||||
@if SpecialInstruction
|
||||
|
||||
#big,bold,center# {SpecialInstruction} #
|
||||
|
||||
@end
|
||||
---
|
||||
@foreach gang in Gangs
|
||||
#red,big,tall,center# {gang.Id}. {gang.Name} #
|
||||
@foreach dish in gang.Dishes
|
||||
#tall# {dish.Number}x {dish.Name} #
|
||||
@if dish.Modifications.Removed.count > 0
|
||||
@foreach removed in dish.Modifications.Removed
|
||||
#bold,tall# - {removed} #
|
||||
@end
|
||||
@end
|
||||
@if dish.Modifications.Added.count > 0
|
||||
@foreach added in dish.Modifications.Added
|
||||
#bold,tall# + {added} #
|
||||
@end
|
||||
@end
|
||||
@if dish.Comment
|
||||
#bold,tall# Comment: {dish.Comment} #
|
||||
@end
|
||||
@end
|
||||
@end
|
||||
@if Gangs.count > 0
|
||||
---
|
||||
@end
|
||||
@foreach dish in Dishes
|
||||
#tall# {dish.Number}x {dish.Name} #
|
||||
@if dish.Modifications.Removed.count > 0
|
||||
@foreach removed in dish.Modifications.Removed
|
||||
#bold,tall# - {removed} #
|
||||
@end
|
||||
@end
|
||||
@if dish.Modifications.Added.count > 0
|
||||
@foreach added in dish.Modifications.Added
|
||||
#bold,tall# + {added} #
|
||||
@end
|
||||
@end
|
||||
@if dish.Comment
|
||||
#bold,tall# Comment: {dish.Comment} #
|
||||
@end
|
||||
@end
|
||||
@if Dishes.count > 0
|
||||
|
||||
---
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
**Sample JSON:**
|
||||
```json
|
||||
{
|
||||
"Title": "Restaurant Kitchen",
|
||||
"TransactionDateTime": "2024-03-15T14:30:00",
|
||||
"ReceiptNumber": "12345",
|
||||
"WaiterName": "John Doe",
|
||||
"WaiterId": "W001",
|
||||
"TableNumber": "5",
|
||||
"SpecialInstruction": "Rush Order",
|
||||
"Gangs": [
|
||||
{
|
||||
"Id": 1,
|
||||
"Name": "Starters",
|
||||
"Dishes": [
|
||||
{
|
||||
"Number": 2,
|
||||
"Name": "Caesar Salad",
|
||||
"Modifications": {
|
||||
"Removed": ["Croutons"],
|
||||
"Added": ["Extra Dressing"]
|
||||
},
|
||||
"Comment": "No anchovies"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Dishes": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Printer Profiles
|
||||
|
||||
Templates adapt to different printer capabilities using profiles.
|
||||
|
||||
### Built-in Profiles
|
||||
|
||||
| Printer | Profile ID | Line Width | Big Width | Red Support |
|
||||
|---------|------------|------------|-----------|-------------|
|
||||
| TM-T30III | `tm-t30iii` | 48 | 24 | No |
|
||||
| TM-U220II | `tm-u220ii` | 33 | 20 | Yes |
|
||||
|
||||
### How Profiles Affect Output
|
||||
|
||||
1. **Line Width**: Separators and centered text use the profile's line width
|
||||
2. **Big Width**: When `big` style is applied, centering uses the reduced width
|
||||
3. **Red Support**: The `red` style only produces red output on supported printers
|
||||
|
||||
### Template Assignment
|
||||
|
||||
Templates are assigned to receipt types and printer profiles in `assignments.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"assignments": [
|
||||
{
|
||||
"receiptType": 1,
|
||||
"profileId": "tm-t30iii",
|
||||
"template": "kitchen-default.template"
|
||||
},
|
||||
{
|
||||
"receiptType": 1,
|
||||
"profileId": "tm-u220ii",
|
||||
"template": "kitchen-u220.template"
|
||||
},
|
||||
{
|
||||
"receiptType": 1,
|
||||
"profileId": null,
|
||||
"template": "kitchen-default.template"
|
||||
}
|
||||
],
|
||||
"fallbackTemplate": "fallback.template"
|
||||
}
|
||||
```
|
||||
|
||||
**Resolution Priority:**
|
||||
1. Exact match (receiptType + profileId)
|
||||
2. Type-only match (receiptType, no profileId)
|
||||
3. Fallback template
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Syntax Summary
|
||||
|
||||
| Syntax | Description |
|
||||
|--------|-------------|
|
||||
| `{path}` | Data binding |
|
||||
| `{path:format}` | Formatted binding |
|
||||
| `#style# text #` | Styled text |
|
||||
| `---` | Dash separator |
|
||||
| `===` | Equals separator |
|
||||
| `***` | Star separator |
|
||||
| `~~~` | Tilde separator |
|
||||
| `@* comment` | Single-line comment |
|
||||
| `@* comment *@` | Inline comment |
|
||||
| `@*` ... `*@` | Multi-line comment block |
|
||||
| `@if condition` | Start conditional |
|
||||
| `@elseif condition` | Else-if branch |
|
||||
| `@else` | Else branch |
|
||||
| `@end` | End block |
|
||||
| `@foreach var in collection` | Start loop |
|
||||
| `@row` | Start row |
|
||||
| `@endrow` | End row |
|
||||
| `\|width\|content` | Column definition |
|
||||
| `\|width,align\|content` | Column with alignment |
|
||||
|
||||
### Style Reference
|
||||
|
||||
| Style | Effect |
|
||||
|-------|--------|
|
||||
| `bold` | Bold text |
|
||||
| `big` | Double size |
|
||||
| `tall` | Double height |
|
||||
| `red` | Red color |
|
||||
| `center` | Center align |
|
||||
| `right` | Right align |
|
||||
| `spacing:N` | Line spacing |
|
||||
|
||||
### Loop Variables
|
||||
|
||||
| Variable | Value |
|
||||
|----------|-------|
|
||||
| `_index` | 0, 1, 2, ... |
|
||||
| `_number` | 1, 2, 3, ... |
|
||||
| `_first` | true/false |
|
||||
| `_last` | true/false |
|
||||
| `_count` | total count |
|
||||
Reference in New Issue
Block a user