diff --git a/docs/TurboDocx Templating/Advanced Templating Engine.md b/docs/TurboDocx Templating/Advanced Templating Engine.md new file mode 100644 index 0000000..80c17d6 --- /dev/null +++ b/docs/TurboDocx Templating/Advanced Templating Engine.md @@ -0,0 +1,2321 @@ +--- +title: Advanced Templating Engine +sidebar_position: 2 +description: Complete guide to TurboDocx's Advanced Templating Engine - support for nested properties, arithmetic expressions, conditional logic, and loops in your document templates. +keywords: + - advanced templating + - nested variables + - dynamic templates + - conditional logic + - arithmetic expressions + - template loops + - angular expressions + - json variables + - complex templates + - variable nesting + - document automation + - template engine + - expression parser + - turbodocx advanced features +--- + +# Advanced Templating Engine + + +## What's New? + +The Advanced Templating Engine extends TurboDocx's capabilities with powerful features that enable sophisticated document automation: + +
+ +### 🎯 Nested Property Access +Access deeply nested object properties using dot notation +``` +{customer.contact.email} +{order.shipping.address.city} +``` + +### 🧮 Arithmetic Expressions +Perform calculations directly in templates +``` +{price * quantity} +{subtotal + tax + shipping} +``` + +### ⚡ Conditional Logic +Show/hide content based on conditions +``` +{#price >= 1000} +This is expensive stuff +{/} +``` + +### 🔄 Loops & Iterations +Generate repeated content from arrays +``` +{#products} +- {name}: ${price} +{/} +``` + +
+ +## Why Use Advanced Templating? + +### Before: Simple Variables +❌ **More variables to manage** +```json +{ + "variables": [ + {"placeholder": "{firstName}", "value": "John"}, + {"placeholder": "{lastName}", "value": "Doe"}, + {"placeholder": "{email}", "value": "john@example.com"}, + {"placeholder": "{phone}", "value": "+1-555-0123"}, + {"placeholder": "{street}", "value": "123 Main St"}, + {"placeholder": "{city}", "value": "San Francisco"}, + {"placeholder": "{state}", "value": "CA"}, + {"placeholder": "{zip}", "value": "94102"} + ] +} +``` + +### After: Advanced Templating +✅ **Clean, structured data** +```json +{ + "variables": [ + { + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "firstName": "John", + "lastName": "Doe", + "contact": { + "email": "john@example.com", + "phone": "+1-555-0123" + }, + "address": { + "street": "123 Main St", + "city": "San Francisco", + "state": "CA", + "zip": "94102" + } + } + } + ] +} +``` + +### Key Benefits + +- **🎯 Less Mapping**: Reduce variable count by 60-80% using nested structures +- **💡 Smarter Templates**: Calculations, conditions, and logic in your documents +- **🚀 Faster Development**: Mirror your application's data structure +- **🔧 Easier Maintenance**: Update one object instead of many variables +- **📊 Better Organization**: Logical grouping of related data +- **🎨 More Flexibility**: Dynamic content without backend preprocessing + +--- + +## Quick Start + +Let's transform a simple template into an advanced one in 5 minutes. + +### Step 1: Traditional Approach + +**Template:** +``` +Hello {firstName} {lastName}! + +Your account balance is ${balance}. +Thank you for being a {membershipLevel} member. +``` + +**Payload (8 variables):** +```json +{ + "variables": [ + {"placeholder": "{firstName}", "mimeType": "text", "value": "Jane"}, + {"placeholder": "{lastName}", "mimeType": "text", "value": "Smith"}, + {"placeholder": "{balance}", "mimeType": "text", "value": "1500.00"}, + {"placeholder": "{membershipLevel}", "mimeType": "text", "value": "Premium"} + ] +} +``` + +### Step 2: Advanced Approach + +**Template:** +``` +Hello {user.firstName} {user.lastName}! + +Your account balance is ${user.account.balance}. +{#user.account.isPremium} +Thank you for being a Premium member! You've saved ${user.account.savings} this year. +{/} +``` + +**Payload (1 variable):** +```json +{ + "variables": [ + { + "placeholder": "{user}", + "mimeType": "json", + "value": { + "firstName": "Jane", + "lastName": "Smith", + "account": { + "balance": 1500.00, + "isPremium": true, + "savings": 250.00 + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Hello Jane Smith! + +Your account balance is $1500.00. +Thank you for being a Premium member! You've saved $250.00 this year. +``` + +:::tip Key Takeaway +One structured JSON variable replaces 4+ simple text variables, and you get conditional rendering for free! +::: + +--- + +## Core Concepts + +### Expression Types + +The Advanced Templating Engine automatically detects and evaluates different expression types: + +| Type | Syntax | Example | Use Case | +|------|--------|---------|----------| +| **Simple** | `{variable}` | `{firstName}` | Basic text replacement | +| **Nested** | `{object.property}` | `{user.email}` | Accessing nested data | +| **Arithmetic** | `{a + b}` | `{price * qty}` | Mathematical calculations | +| **Conditional** | `{#condition}...{/}` | `{#isPremium}...{/}` | Show/hide content | +| **Loop** | `{#array}...{/}` | `{#items}...{/}` | Repeat content | + +### Important Flags + +:::info Required for Advanced Features +To enable advanced templating features, use **either or both**: + +1. **`mimeType: "json"`** - Enables advanced features automatically for that variable + - Required for: nested objects, arrays, loops + - Also enables: arithmetic expressions, conditionals on that data + +2. **`usesAdvancedTemplatingEngine: true`** - Explicitly enables advanced features + - Required when: using `mimeType: "text"` with arithmetic expressions + - Optional when: using `mimeType: "json"` (already enabled) + +**You can use both together** - `mimeType: "json"` with `usesAdvancedTemplatingEngine: true` +::: + +:::warning Rich Text Not Supported +Advanced templating features **do not support rich text data** at this time. If your variable values contain rich text formatting in html string, it will be rendered as html string and no conversion will be done. + +**Limitation:** Variables with `usesAdvancedTemplatingEngine: true` or `mimeType: "json"` will render as plain text only. + +**Workaround:** For rich text content, use simple variables without advanced templating features. +::: + +#### `usesAdvancedTemplatingEngine` +Explicitly marks variables using advanced features. + +**When to use:** +- **Required**: When using arithmetic with `mimeType: "text"` + ```json + { + "placeholder": "{price}", + "mimeType": "text", + "value": 100, + "usesAdvancedTemplatingEngine": true // Required for arithmetic with text + } + ``` + +- **Optional**: When using `mimeType: "json"` (advanced features already enabled) + ```json + { + "placeholder": "{customer}", + "mimeType": "json", // Advanced features enabled automatically + "value": {"name": "John"}, + "usesAdvancedTemplatingEngine": true // Optional, but recommended + } + ``` + +#### `mimeType: "json"` +Enables advanced templating features automatically for structured data. + +**Automatically enables:** +- Nested object access: `{customer.contact.email}` +- Arithmetic expressions: `{order.items[0].price * 2}` +- Arrays/Loops: `{#items}...{/}` +- Conditionals: `{#isPremium}...{/}` + +**Examples:** +```json +// Nested object with arithmetic +{ + "placeholder": "{order}", + "mimeType": "json", // Enables all advanced features + "value": { + "subtotal": 100, + "tax": 10, + "items": [ + {"name": "Product A", "price": 50, "quantity": 2} + ] + } +} + +// Template can use: {order.subtotal + order.tax} and {#order.items}...{/} +``` + +### Operating Modes + +#### Production Mode (Default) +✅ All advanced features work +✅ Expressions evaluated normally +✅ Full JSON object support +✅ Use for actual document generation + +#### Preview Mode (`isPreview: true`) +⚠️ Only simple variables supported +⚠️ Advanced features show error messages +⚠️ Used for UI-based template preview + +:::warning Preview Mode Limitations +Preview mode is designed for rendering variables in TurboDocx UI while populating them. Advanced features like nested objects, expressions, and loops require programmatic JSON data structures that can't be easily input through a UI form. +::: + +--- + +## Feature Deep Dive + +### 1. Nested Property Access + +Access properties within nested objects using dot notation. Perfect for structured data from databases, APIs, or application state. + +#### Use Cases + +- Customer profiles with multiple sections +- Address information (street, city, state, zip) +- Product catalogs with specifications +- Organization hierarchies +- User settings and preferences +- Order details with line items + +#### Basic Nested Access + +**Template:** +``` +Customer Information +------------------- +Name: {customer.firstName} {customer.lastName} +Email: {customer.contact.email} +Phone: {customer.contact.phone} + +Shipping Address: +{customer.address.street} +{customer.address.city}, {customer.address.state} {customer.address.zip} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "firstName": "Jane", + "lastName": "Smith", + "contact": { + "email": "jane.smith@example.com", + "phone": "+1-555-0123" + }, + "address": { + "street": "123 Main Street", + "city": "San Francisco", + "state": "CA", + "zip": "94102" + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Customer Information +------------------- +Name: Jane Smith +Email: jane.smith@example.com +Phone: +1-555-0123 + +Shipping Address: +123 Main Street +San Francisco, CA 94102 +``` + +#### Deep Nesting + +**Template:** +``` +Organization: {company.name} +Department: {company.divisions.engineering.teams.backend.name} +Team Lead: {company.divisions.engineering.teams.backend.lead.name} +Contact: {company.divisions.engineering.teams.backend.lead.contact.email} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{company}", + "mimeType": "json", + "value": { + "name": "Acme Corporation", + "divisions": { + "engineering": { + "teams": { + "backend": { + "name": "Backend Infrastructure", + "lead": { + "name": "Alex Johnson", + "contact": { + "email": "alex.johnson@acme.com", + "phone": "+1-555-0199" + } + } + } + } + } + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +#### Combining Nested Access with Arithmetic + +**Template:** +``` +Student Grade Report +------------------- +Name: {student.name.first} {student.name.last} +Student ID: {student.id} + +Grades: +Physics: {student.grades.physics} +Chemistry: {student.grades.chemistry} +Mathematics: {student.grades.mathematics} + +Average: {(student.grades.physics + student.grades.chemistry + student.grades.mathematics) / 3} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{student}", + "mimeType": "json", + "value": { + "id": "STU-12345", + "name": { + "first": "Emma", + "last": "Wilson" + }, + "grades": { + "physics": 92, + "chemistry": 88, + "mathematics": 95 + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Student Grade Report +------------------- +Name: Emma Wilson +Student ID: STU-12345 + +Grades: +Physics: 92 +Chemistry: 88 +Mathematics: 95 + +Average: 91.67 +``` + +#### Built-in Property Filtering + +The templating engine automatically provides access to JavaScript built-in properties and methods. You only need to provide the data structure in your payload—built-in properties like `.length` work automatically without needing separate variables. + +**Automatically Available Properties:** +- **Array:** `length`, `indexOf`, `includes`, `join`, `slice`, `concat`, `map`, `filter`, `reduce`, `find`, `sort` +- **String:** `length`, `charAt`, `substring`, `toUpperCase`, `toLowerCase`, `trim`, `split`, `replace` +- **Object:** `keys`, `values`, `entries`, `toString`, `hasOwnProperty` + +**Template:** +``` +User Management Dashboard +======================== + +Total Active Users: {users.length} +First User Email: {users[0].email} +Last User Name: {users[users.length - 1].name} + +Team Name: {teamName} +Team Code: {teamName.toUpperCase()} +Name Length: {teamName.length} characters +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{users}", + "mimeType": "json", + "value": [ + {"name": "Alice Johnson", "email": "alice@example.com"}, + {"name": "Bob Smith", "email": "bob@example.com"}, + {"name": "Carol White", "email": "carol@example.com"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{teamName}", + "mimeType": "text", + "value": "Engineering", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +User Management Dashboard +======================== + +Total Active Users: 3 +First User Email: alice@example.com +Last User Name: Carol White + +Team Name: Engineering +Team Code: ENGINEERING +Name Length: 11 characters +``` + +:::tip Key Insight +You **do not** need to create separate variables like `{userCount}` or `{teamNameUpper}`. The engine automatically provides `.length` on arrays and strings, `.toUpperCase()` on strings, and array indexing like `[0]` or `[users.length - 1]`. +::: + +### 2. Arithmetic Expressions + +Perform mathematical calculations directly in your templates without preprocessing data. + +:::warning String vs Number Values +When performing arithmetic operations, always use **numeric values** (not strings) in your payload. Using string values instead of numbers may produce unexpected or incorrect results. + +**Example:** +- ✅ `"value": 10` (number) - Works correctly +- ❌ `"value": "10"` (string) - May produce wrong results + +See the [String vs Number Example](#string-vs-number-behavior) below for a detailed comparison. +::: + +#### Supported Operators + +- **Addition:** `+` +- **Subtraction:** `-` +- **Multiplication:** `*` +- **Division:** `/` +- **Parentheses:** `()` for order of operations +- **Modulo:** `%` (remainder) + +#### Invoice Example + +**Template:** +``` +INVOICE #INV-{invoiceNumber} +======================== + +Item Qty Price Total +-------------------------------------------------- +{#lineItems} +{description} {qty} ${price} ${qty * price} +{/} +-------------------------------------------------- + +Subtotal: ${subtotal} +Tax (10%): ${subtotal * 0.10} +Shipping: ${shipping} +-------------------------------------------------- +TOTAL: ${subtotal + (subtotal * 0.10) + shipping} + +{#discount > 0} +Discount Applied: -${discount} +FINAL AMOUNT: ${subtotal + (subtotal * 0.10) + shipping - discount} +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{invoiceNumber}", + "mimeType": "text", + "value": "2024-001" + }, + { + "placeholder": "{lineItems}", + "mimeType": "json", + "value": [ + {"description": "Widget A", "qty": 5, "price": 25.00}, + {"description": "Widget B", "qty": 3, "price": 40.00}, + {"description": "Widget C", "qty": 2, "price": 15.00} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{subtotal}", + "mimeType": "text", + "value": 275.00, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{shipping}", + "mimeType": "text", + "value": 15.00, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{discount}", + "mimeType": "text", + "value": 25.00, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +INVOICE #INV-2024-001 +======================== + +Item Qty Price Total +-------------------------------------------------- +Widget A 5 $25.00 $125.00 +Widget B 3 $40.00 $120.00 +Widget C 2 $15.00 $30.00 +-------------------------------------------------- + +Subtotal: $275.00 +Tax (10%): $27.50 +Shipping: $15.00 +-------------------------------------------------- +TOTAL: $317.50 + +Discount Applied: -$25.00 +FINAL AMOUNT: $292.50 +``` + +#### Pricing Calculator + +**Template:** +``` +Subscription Pricing +------------------- +Base Price: ${basePrice}/month +Users: {userCount} × ${pricePerUser} = ${userCount * pricePerUser} +Storage: {storageGB}GB × ${pricePerGB} = ${storageGB * pricePerGB} + +Subtotal: ${basePrice + (userCount * pricePerUser) + (storageGB * pricePerGB)} + +{#annualBilling} +Annual Discount (20%): -${(basePrice + (userCount * pricePerUser) + (storageGB * pricePerGB)) * 0.20} +Annual Total: ${(basePrice + (userCount * pricePerUser) + (storageGB * pricePerGB)) * 0.80 * 12} +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{basePrice}", + "mimeType": "text", + "value": 29.99, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{userCount}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{pricePerUser}", + "mimeType": "text", + "value": 5.00, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{storageGB}", + "mimeType": "text", + "value": 100, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{pricePerGB}", + "mimeType": "text", + "value": 0.10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{annualBilling}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Subscription Pricing +------------------- +Base Price: $29.99/month +Users: 10 × $5.00 = $50.00 +Storage: 100GB × $0.10 = $10.00 + +Subtotal: $89.99 + +Annual Discount (20%): -$17.998 +Annual Total: $863.904 +``` + +#### Complex Calculations + +**Template:** +``` +Mortgage Calculator +------------------ +Loan Amount: ${loanAmount} +Interest Rate: {interestRate}% +Loan Term: {years} years + +Monthly Interest Rate: {interestRate / 100 / 12} +Number of Payments: {years * 12} + +Monthly Payment: ${(loanAmount * (interestRate / 100 / 12)) / (1 - (1 + (interestRate / 100 / 12)) ** (-(years * 12)))} +Total Payment: ${((loanAmount * (interestRate / 100 / 12)) / (1 - (1 + (interestRate / 100 / 12)) ** (-(years * 12)))) * (years * 12)} +Total Interest: ${(((loanAmount * (interestRate / 100 / 12)) / (1 - (1 + (interestRate / 100 / 12)) ** (-(years * 12)))) * (years * 12)) - loanAmount} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{loanAmount}", + "mimeType": "text", + "value": 300000, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{interestRate}", + "mimeType": "text", + "value": 4.5, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{years}", + "mimeType": "text", + "value": 30, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Mortgage Calculator +------------------ +Loan Amount: $300000 +Interest Rate: 4.5% +Loan Term: 30 years + +Monthly Interest Rate: 0.00375 +Number of Payments: 360 + +Monthly Payment: $1520.06 +Total Payment: $547221.60 +Total Interest: $247221.60 +``` + +#### String vs Number Behavior + +This example demonstrates why you should always use numeric values instead of strings for arithmetic operations. + +**Template:** +``` +All Operators: + - Addition: {a} + {b} = {a + b} + - Subtraction: {a} - {b} = {a - b} + - Multiplication: {a} * {b} = {a * b} + - Division: {a} / {b} = {a / b} + - Modulo: {a} % {b} = {a % b} +``` + +**Payload with Numbers (Correct):** +```json +{ + "variables": [ + { + "placeholder": "{a}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{b}", + "mimeType": "text", + "value": 3, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output with Numbers:** +``` +All Operators: + - Addition: 10 + 3 = 13 + - Subtraction: 10 - 3 = 7 + - Multiplication: 10 * 3 = 30 + - Division: 10 / 3 = 3.333333333333333 + - Modulo: 10 % 3 = 1 +``` + +**Payload with Strings (Incorrect):** +```json +{ + "variables": [ + { + "placeholder": "{a}", + "mimeType": "text", + "value": "10", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{b}", + "mimeType": "text", + "value": "3", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output with Strings (Wrong Results):** +``` +All Operators: + - Addition: 10 + 3 = 103 + - Subtraction: 10 - 3 = 7 + - Multiplication: 10 * 3 = 30 + - Division: 10 / 3 = 3.333333333333333 + - Modulo: 10 % 3 = 1 +``` + +:::caution Key Takeaway +Notice how **addition with strings** produces `"103"` (string concatenation) instead of `13` (mathematical addition). While other operators may still work due to JavaScript's type coercion, this behavior is unreliable and can lead to bugs. Always use numeric values for arithmetic operations. +::: + +#### Division and Modulo by Zero + +Special care must be taken when dividing or using modulo operations with zero values. + +**Template:** +``` +Division and Modulo with Zero: + - 10 / 0 = {a / 0} + - 10 % 0 = {a % 0} + - 0 * 5 = {0 * b} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{a}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{b}", + "mimeType": "text", + "value": 5, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Division and Modulo with Zero: + - 10 / 0 = Infinity + - 10 % 0 = NaN + - 0 * 5 = 0 +``` + +:::danger Zero Division Warnings +- **Division by zero** (`x / 0`) returns `Infinity` +- **Modulo by zero** (`x % 0`) returns `NaN` (Not a Number) +- **Multiplication by zero** (`x * 0` or `0 * x`) returns `0` (works normally) + +**Best Practice:** Use conditional logic to check for zero before performing division or modulo operations: +``` +{#divisor != 0} +Result: {dividend / divisor} +{/} +{#divisor == 0} +Error: Cannot divide by zero +{/} +``` +::: + +:::warning Important Notes +- Division by zero returns `Infinity` - handle with conditionals if needed +- Modulo by zero returns `NaN` - validate divisor before using modulo +- Use parentheses to control order of operations +- **Always use numeric values** (not strings) for arithmetic operations to avoid incorrect results +::: + +--- + +### 3. Conditional Logic + +Show or hide content sections based on conditions. Perfect for personalized documents, access control, and dynamic content display. + +#### Supported Operators + +- **Equality:** `==`, `!=` +- **Comparison:** `>`, `<`, `>=`, `<=` +- **Logical:** `&&` (and), `||` (or), `!` (not) +- **Existence:** Check if variable is truthy/falsy + +#### Simple Boolean Conditionals + +**Template:** +``` +Account Status: {#isActive}✓ ACTIVE{/}{#!isActive}✗ INACTIVE{/} + +{#isPremium} +PREMIUM MEMBER BENEFITS: +✓ Free shipping on all orders +✓ 24/7 Priority support +✓ Early access to new features +✓ 20% discount on all purchases +{/} + +{#!isPremium} +Upgrade to Premium to unlock exclusive benefits! +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{isActive}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{isPremium}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Account Status: ✓ ACTIVE + +PREMIUM MEMBER BENEFITS: +✓ Free shipping on all orders +✓ 24/7 Priority support +✓ Early access to new features +✓ 20% discount on all purchases +``` + +#### Numeric Comparisons + +**Template:** +``` +Membership Tier Assessment +------------------------- + +{#score >= 1000} +✓ PLATINUM MEMBER +Access to all premium features and exclusive events +{/} + +{#score >= 500 && score < 1000} +⭐ GOLD MEMBER +Access to premium features and priority support +{/} + +{#score < 500} +SILVER MEMBER +Access to standard features +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{score}", + "mimeType": "text", + "value": 1250, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Membership Tier Assessment +------------------------- + +✓ PLATINUM MEMBER +Access to all premium features and exclusive events +``` + +#### String Comparisons + +**Template:** +``` +{#status == "approved"} +✓ Your application has been APPROVED +Next steps: Complete onboarding process +{/} + +{#status == "pending"} +⏳ Your application is UNDER REVIEW +Estimated time: 2-3 business days +{/} + +{#status == "rejected"} +✗ Your application was NOT APPROVED +Reason: {rejectionReason} +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{status}", + "mimeType": "text", + "value": "approved", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +✓ Your application has been APPROVED +Next steps: Complete onboarding process +``` + +#### Complex Logical Conditions + +**Template:** +``` +Loan Eligibility Assessment +--------------------------- + +{#creditScore >= 700 && annualIncome >= 50000 && employmentYears >= 2} +✓ PRE-APPROVED for loan up to ${loanAmount} +Excellent credit profile +{/} + +{#(creditScore >= 650 && creditScore < 700) && annualIncome >= 40000} +⚠ CONDITIONAL APPROVAL +Additional documentation required +{/} + +{#creditScore < 650 || annualIncome < 40000 || employmentYears < 1} +✗ APPLICATION DECLINED +Current eligibility criteria not met +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{creditScore}", + "mimeType": "text", + "value": 720, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{annualIncome}", + "mimeType": "text", + "value": 75000, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{employmentYears}", + "mimeType": "text", + "value": 5, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{loanAmount}", + "mimeType": "text", + "value": "250000" + } + ] +} +``` + +**Output:** +``` +Loan Eligibility Assessment +--------------------------- + +✓ PRE-APPROVED for loan up to $250000 +Excellent credit profile +``` + +#### Nested Conditionals + +**Template:** +``` +{#isLoggedIn} +Welcome back, {username}! + +{#hasActiveSubscription} + {#subscriptionType == "enterprise"} + Enterprise Features: + - Unlimited users + - Custom branding + - Dedicated support + - SSO integration + {/} + + {#subscriptionType == "professional"} + Professional Features: + - Up to 50 users + - Advanced analytics + - Priority support + {/} +{/} + +{#!hasActiveSubscription} +Your subscription has expired. Renew now to continue access. +{/} +{/} + +{#!isLoggedIn} +Please log in to access your account. +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{isLoggedIn}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{username}", + "mimeType": "text", + "value": "John Doe", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{hasActiveSubscription}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{subscriptionType}", + "mimeType": "text", + "value": "enterprise", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Welcome back, John Doe! + + Enterprise Features: + - Unlimited users + - Custom branding + - Dedicated support + - SSO integration +``` + +#### Edge Case: Array Length Conditionals + +**Template:** +``` +Shopping Cart +------------ + +{#items.length > 0} +You have {items.length} items in your cart. + +{#items.length > 5} +🎁 Bonus: You qualify for bulk discount! +{/} + +{#items.length >= 3 && items.length <= 5} +💡 Add {6 - items.length} more items for bulk discount! +{/} +{/} + +{#items.length == 0} +Your cart is empty. Start shopping! +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{items}", + "mimeType": "json", + "value": [ + {"name": "Product 1"}, + {"name": "Product 2"}, + {"name": "Product 3"}, + {"name": "Product 4"} + ], + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Shopping Cart +------------ + +You have 4 items in your cart. + +💡 Add 2 more items for bulk discount! +``` + +--- + +### 4. Loops & Iterations + +Iterate over arrays and collections to generate repeated content. Essential for invoices, product lists, reports, tables, and any repeating data. + +#### Simple Array Loop + +**Template:** +``` +SHOPPING CART +============= + +{#items} +• {name} + Price: ${price} + Quantity: {quantity} + Total: ${price * quantity} + --- +{/} + +Cart Total: ${cartTotal} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{items}", + "mimeType": "json", + "value": [ + {"name": "Wireless Mouse", "price": 29.99, "quantity": 2}, + {"name": "USB-C Cable", "price": 12.99, "quantity": 3}, + {"name": "Laptop Stand", "price": 45.00, "quantity": 1} + ] + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cartTotal}", + "mimeType": "text", + "value": "143.95" + } + ] +} +``` + +**Output:** +``` +SHOPPING CART +============= + +• Wireless Mouse + Price: $29.99 + Quantity: 2 + Total: $59.98 + --- +• USB-C Cable + Price: $12.99 + Quantity: 3 + Total: $38.97 + --- +• Laptop Stand + Price: $45.00 + Quantity: 1 + Total: $45.00 + --- + +Cart Total: $143.95 +``` + +#### Nested Loops + +**Template:** +``` +DEPARTMENTS AND EMPLOYEES +======================== + +{#departments} +Department: {name} +Manager: {manager} +Budget: ${budget} + +Team Members: +{#employees} + - {employees.name} ({employees.role}) + Email: {employees.email} + Salary: ${employees.salary} +{/} +--- +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{departments}", + "mimeType": "json", + "value": [ + { + "name": "Engineering", + "manager": "Sarah Johnson", + "budget": 500000, + "employees": [ + { + "name": "John Smith", + "role": "Senior Developer", + "email": "john@company.com", + "salary": 120000 + }, + { + "name": "Emily Chen", + "role": "DevOps Engineer", + "email": "emily@company.com", + "salary": 110000 + } + ] + }, + { + "name": "Marketing", + "manager": "Michael Brown", + "budget": 300000, + "employees": [ + { + "name": "Lisa Anderson", + "role": "Marketing Manager", + "email": "lisa@company.com", + "salary": 95000 + } + ] + } + ] + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +DEPARTMENTS AND EMPLOYEES +======================== + +Department: Engineering +Manager: Sarah Johnson +Budget: $500000 + +Team Members: + - John Smith (Senior Developer) + Email: john@company.com + Salary: $120000 + - Emily Chen (DevOps Engineer) + Email: emily@company.com + Salary: $110000 +--- +Department: Marketing +Manager: Michael Brown +Budget: $300000 + +Team Members: + - Lisa Anderson (Marketing Manager) + Email: lisa@company.com + Salary: $95000 +--- +``` + +#### Loops with Conditionals + +**Template:** +``` +ORDER PROCESSING REPORT +====================== + +{#orders} +Order #{id} - {date} +Customer: {customer.name} +Status: {status} + +Items: +{#items} + • {items.product} - Qty: {items.quantity} - ${items.price} +{/} + +Order Total: ${total} + +{#isPaid} +✓ Payment received on {paymentDate} +{/} + +{#!isPaid} +⚠ PAYMENT PENDING - Follow up required +{/} + +{#total > 1000} +🎁 Qualifies for free premium shipping! +{/} + +Shipping: FREE (if total > 100) +--- +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{orders}", + "mimeType": "json", + "value": [ + { + "id": "ORD-001", + "date": "2024-01-15", + "customer": {"name": "Jane Smith"}, + "status": "Completed", + "isPaid": true, + "paymentDate": "2024-01-15", + "total": 1250.00, + "items": [ + {"product": "Product A", "quantity": 5, "price": 150.00}, + {"product": "Product B", "quantity": 2, "price": 275.00} + ] + }, + { + "id": "ORD-002", + "date": "2024-01-16", + "customer": {"name": "Bob Johnson"}, + "status": "Pending", + "isPaid": false, + "total": 85.00, + "items": [ + {"product": "Product C", "quantity": 1, "price": 85.00} + ] + } + ] + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +ORDER PROCESSING REPORT +====================== + +Order #ORD-001 - 2024-01-15 +Customer: Jane Smith +Status: Completed + +Items: + • Product A - Qty: 5 - $150.00 + • Product B - Qty: 2 - $275.00 + +Order Total: $1250.00 + +✓ Payment received on 2024-01-15 + +🎁 Qualifies for free premium shipping! + +Shipping: FREE (if total > 100) +--- +Order #ORD-002 - 2024-01-16 +Customer: Bob Johnson +Status: Pending + +Items: + • Product C - Qty: 1 - $85.00 + +Order Total: $85.00 + +⚠ PAYMENT PENDING - Follow up required + +Shipping: FREE (if total > 100) +--- +``` + +#### Empty Array Handling + +**Template:** +``` +Notifications +------------ + +{#notifications.length > 0} +You have {notifications.length} new notifications: + +{#notifications} + [{notifications.type}] {notifications.message} + {notifications.timestamp} +{/} +{/} + +{#notifications.length == 0} +No new notifications. You're all caught up! +{/} +``` + +**Payload (empty array):** +```json +{ + "variables": [ + { + "placeholder": "{notifications}", + "mimeType": "json", + "value": [] + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Notifications +------------ + +No new notifications. You're all caught up! +``` + +:::tip Loop Best Practices +1. **Check array length** before looping to handle empty arrays +2. **Limit large arrays** - Performance degrades with 1000+ items +3. **Use conditionals inside loops** for dynamic content +4. **Access nested properties** with dot notation +5. **Combine with arithmetic** for calculations within loops +6. **Test with edge cases** - empty arrays, single items, large datasets +::: + +--- + +## Complete Payload Reference + +### Variable Object Structure + +```typescript +interface IVariable { + // Required fields + placeholder: string; // Variable placeholder, e.g., "{user}" + mimeType: "text" | "html" | "json" | "image"; + + // Content + value: string | number | boolean | object | any[]; // For text, html, json types + + // Advanced templating flags + usesAdvancedTemplatingEngine?: boolean; // Uses advanced features + + // Optional metadata + name?: string; // Variable name without braces +} +``` + + + + +### MIME Types Explained + +| MIME Type | Usage | Example | +|-----------|-------|---------| +| `text` | Plain text values | Simple variables, numbers | +| `html` | Rich text with HTML | Formatted descriptions | +| `json` | Objects or arrays | Nested data, loops | +| `image` | Image data | Base64 or URLs | + +--- + +## Edge Cases & Variations + +### 1. Mixed Data Types in Loops + +**Scenario:** Loop array contains different value types + +**Template:** +``` +{#items} +{#items.nestedloop} +- {items.nestedloop.title} +{/} +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{items}", + "mimeType": "json", + "value": [ + { + "nestedloop": [ + {"title": "Item 1.1"}, + {"title": "Item 1.2"} + ] + }, + { + "nestedloop": true, + "title": "Item 2 (boolean true)" + }, + { + "nestedloop": {"title": "Item 3 (single object)"} + }, + { + "nestedloop": false + }, + {} + ], + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +- Item 1.1 +- Item 1.2 +- Item 2 (boolean true) +- Item 3 (single object) +``` + +### 2. Deeply Nested Access + +**Template:** +``` +{company.divisions.departments.teams.members.contact.primaryEmail} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{company}", + "mimeType": "json", + "value": { + "divisions": { + "departments": { + "teams": { + "members": { + "contact": { + "primaryEmail": "deep@example.com" + } + } + } + } + } + }, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +deep@example.com +``` + +### 3. Null/Undefined Handling + +**Template:** +``` +Name: {user.name} +Email: {user.email} +Optional: {user.optional} +``` + +**Payload (missing properties):** +```json +{ + "variables": [ + { + "placeholder": "{user}", + "mimeType": "json", + "value": { + "name": null + }, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +Name: +Email: +Optional: +``` + +### 5. Array Index Access + +**Template:** +``` +First item: {items[0].name} +Second item: {items[1].name} +Last item: {items[items.length - 1].name} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{items}", + "mimeType": "json", + "value": [ + {"name": "First"}, + {"name": "Second"}, + {"name": "Third"}, + {"name": "Last"} + ], + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +First item: First +Second item: Second +Last item: Last +``` + +### 6. Boolean String Conversion + +**Template:** +``` +{#stringBoolean == "true"} +String is "true" +{/} + +{#booleanValue} +Boolean is true +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{stringBoolean}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{booleanValue}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +String is "true" + +Boolean is true +``` + +### 7. Empty String vs Null vs Undefined + +**Template:** +``` +Empty string: "{emptyString}" +Undefined: "{undefinedValue}" +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{emptyString}", + "mimeType": "text", + "value": "" + } + ] +} +``` + +**Output:** +``` +Empty string: +Undefined: undefined +``` + +--- + +## Error Handling & Debugging + +### Common Errors + +#### 1. Missing Variable + +**Error:** Variable comes as undefined in output + +**Cause:** Variable not provided in payload + +**Solution:** Check placeholder spelling and ensure variable is in payload + +#### 2. Type Mismatch + +**Error:** Unexpected rendering or empty content + +**Cause:** Not providing `usesAdvancedTemplatingEngine:true` with `mimeType: "text"` or `mimeType: "json" ` is not given. + +**Solution:** Use `mimeType: "json"`, or `mimeType: "text"` and `usesAdvancedTemplatingEngine: true` + +#### 3. Preview Mode Error + +**Error:** `"{expression} is not supported in the TurboDocx UI"` + +**Cause:** Using advanced features in preview mode in TurboDocx UI + +### Debugging Strategies + +#### 1. Start Simple +```json +// Test with minimal payload first +{ + "variables": [ + { + "placeholder": "{test}", + "mimeType": "text", + "value": "Hello World" + } + ] +} +``` + +#### 2. Validate JSON Structure +```javascript +// Use JSON validator before sending +const isValid = JSON.stringify(payload); +``` + +#### 3. Test Expressions Individually +``` +Template: {price} +Then: {price * 2} +Then: {price * quantity} +``` + +#### 4. Check Nested Paths +```json +// Verify each level exists +{ + "user": { + "profile": { + "name": "test" // Accessible as {user.profile.name} + } + } +} +``` + +## Best Practices + +### 1. Payload Structure + +✅ **DO:** +```json +{ + "variables": [ + { + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "name": "John", + "email": "john@example.com" + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +❌ **DON'T:** +```json +{ + "variables": [ + { + "placeholder": "{customer}", + "mimeType": "text", // Wrong type for nested data + "value": "John" // Should be false for JSON + } + ] +} +``` + +### 2. Template Design + +- **Use meaningful variable names:** `{customer.email}` not `{ce}` +- **Group related data:** Keep address fields together in one object +- **Use appropriate MIME types** to get best results +- **Check data payload** to ensure desired outputs. + +## Migration Guide + +### From Simple to Advanced Variables + +#### Step 1: Identify Related Variables + +**Before:** +``` +{firstName} +{lastName} +{email} +{phone} +{street} +{city} +{state} +{zip} +``` + +#### Step 2: Group into Logical Structure + +**After:** +``` +{customer.firstName} +{customer.lastName} +{customer.contact.email} +{customer.contact.phone} +{customer.address.street} +{customer.address.city} +{customer.address.state} +{customer.address.zip} +``` + +#### Step 3: Update Payload + +**Before (8 variables):** +```json +{ + "variables": [ + {"placeholder": "{firstName}", "mimeType": "text", "value": "John"}, + {"placeholder": "{lastName}", "mimeType": "text", "value": "Doe"}, + // ... 6 more variables + ] +} +``` + +**After (1 variable):** +```json +{ + "variables": [ + { + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "firstName": "John", + "lastName": "Doe", + "contact": { + "email": "john@example.com", + "phone": "+1-555-0123" + }, + "address": { + "street": "123 Main St", + "city": "San Francisco", + "state": "CA", + "zip": "94102" + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +### Backward Compatibility + +- ✅ **Simple variables continue to work** - No breaking changes +- ✅ **Mix simple and advanced** - Use both approaches in same template +- ✅ **Gradual migration** - Update templates one at a time +- ✅ **No API changes** - Same endpoints, just enhanced payloads + +--- + +## Real-World Examples + +### Example 1: Employee Contract + +
+Click to expand full example + +**Template:** +``` +EMPLOYMENT CONTRACT + +This Employment Agreement is entered into on {contract.date} between: + +Employer: {company.name} +Address: {company.address.street}, {company.address.city}, {company.address.state} {company.address.zip} + +Employee: {employee.name.first} {employee.name.last} +Address: {employee.address.street}, {employee.address.city}, {employee.address.state} {employee.address.zip} +Email: {employee.contact.email} +Phone: {employee.contact.phone} + +POSITION AND DUTIES +The Employee is hired for the position of {employee.position} in the {employee.department} department. + +COMPENSATION +Base Salary: ${employee.compensation.baseSalary} per year +Payment Schedule: {employee.compensation.paymentSchedule} + +{#employee.compensation.bonus > 0} +Performance Bonus: Up to ${employee.compensation.bonus} annually +{/} + +BENEFITS +{#benefits} +- {benefits.name}: {benefits.description} +{/} + +{#employee.isRemote} +REMOTE WORK +This is a remote position. The Employee may work from their home office. +Equipment Budget: ${employee.equipmentBudget} +{/} + +{#!employee.isRemote} +OFFICE LOCATION +The Employee will work at: {company.address.street}, {company.address.city}, {company.address.state} +{/} + +START DATE +Employment begins on {employee.startDate} + +_________________________________ +{company.signatory.name} +{company.signatory.title} + +_________________________________ +{employee.name.first} {employee.name.last} +Employee +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{contract}", + "mimeType": "json", + "value": { + "date": "January 15, 2024" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{company}", + "mimeType": "json", + "value": { + "name": "Acme Corporation", + "address": { + "street": "100 Technology Drive", + "city": "San Francisco", + "state": "CA", + "zip": "94105" + }, + "signatory": { + "name": "Sarah Johnson", + "title": "Chief People Officer" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{employee}", + "mimeType": "json", + "value": { + "name": { + "first": "Alex", + "last": "Chen" + }, + "address": { + "street": "456 Residential St", + "city": "Oakland", + "state": "CA", + "zip": "94612" + }, + "contact": { + "email": "alex.chen@email.com", + "phone": "+1-555-0199" + }, + "position": "Senior Software Engineer", + "department": "Engineering", + "compensation": { + "baseSalary": 150000, + "paymentSchedule": "Bi-weekly", + "bonus": 20000 + }, + "isRemote": true, + "equipmentBudget": 2000, + "startDate": "February 1, 2024" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{benefits}", + "mimeType": "json", + "value": [ + { + "name": "Health Insurance", + "description": "Comprehensive medical, dental, and vision coverage" + }, + { + "name": "401(k) Matching", + "description": "Company matches up to 6% of salary" + }, + { + "name": "Paid Time Off", + "description": "20 days PTO plus 10 holidays" + }, + { + "name": "Professional Development", + "description": "$5,000 annual budget for courses and conferences" + } + ], + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +
+ +### Example 2: Monthly Sales Report + +
+Click to expand full example + +**Template:** +``` +MONTHLY SALES REPORT +{report.month} {report.year} +Generated: {report.generatedDate} + +EXECUTIVE SUMMARY +Total Revenue: ${report.totalRevenue} +Total Orders: {report.totalOrders} +Average Order Value: ${report.totalRevenue / report.totalOrders} +Growth vs Last Month: {report.growthPercent}% + +{#report.growthPercent > 0} +📈 Revenue increased by {report.growthPercent}% compared to last month! +{/} + +{#report.growthPercent < 0} +📉 Revenue decreased by {report.growthPercent * -1}% compared to last month. +{/} + +TOP PERFORMING PRODUCTS +{#topProducts} + {topProducts.name} + Units Sold: {topProducts.unitsSold} + Revenue: ${topProducts.revenue} +{/} + +SALES BY REGION +{#regions} +{regions.name}: + Revenue: ${regions.revenue} + Orders: {regions.orders} + Market Share: {(regions.revenue / report.totalRevenue) * 100}% + + Top Sales Rep: {regions.topRep.name} + Rep Sales: ${regions.topRep.sales} + +{/} + +PERFORMANCE ALERTS +{#regions} +{#regions.revenue < regions.target} +⚠ {regions.name} is below target + Target: ${regions.target} + Actual: ${regions.revenue} + Gap: ${regions.target - regions.revenue} +{/} +{/} +``` + +**Payload:** See [complete payload in documentation repo] + +
+ +--- + +## API Integration Example + +For a **complete, working cURL example** that demonstrates all advanced templating features in a single comprehensive test document, see: + +👉 **[cURL Example](./Advanced%20Templating%20cURL%20Example.md)** + +This example includes: +- Complete test template covering all features +- Full cURL request with proper headers +- Complete payload with all variable types +- Expected output documentation + +--- + +## Additional Resources + +### Documentation +- [Create a Deliverable](./How%20to%20Create%20a%20Deliverable.md) +- [Template Generation API](./API%20Templates.md) +- [Variable System Guide](./Additional%20Information.md) +- [Template Troubleshooting](./Template%20Troubleshooting.md) + +### External Resources +- [Angular Expressions Documentation](https://www.npmjs.com/package/angular-expressions) +- [Docxtemplater Official Docs](https://docxtemplater.com/) +- [JSON Schema Validator](https://www.jsonschemavalidator.net/) + +### Support +- 📧 Email: support@turbodocx.com +- 💬 Discord Community: https://discord.gg/turbodocx +- 📚 Knowledge Base: https://docs.turbodocx.com + +--- + +**Last Updated:** January 2026 +**Version:** 1.0.0 +**Maintained by:** TurboDocx Engineering Team + +:::tip Found this helpful? +Share your use cases and feedback with our team. We're constantly improving the Advanced Templating Engine based on customer needs! +::: diff --git a/docs/TurboDocx Templating/Advanced Templating Troubleshooting.md b/docs/TurboDocx Templating/Advanced Templating Troubleshooting.md new file mode 100644 index 0000000..7724c34 --- /dev/null +++ b/docs/TurboDocx Templating/Advanced Templating Troubleshooting.md @@ -0,0 +1,496 @@ +--- +title: Advanced Templating Troubleshooting +sidebar_position: 4 +description: Comprehensive troubleshooting guide for TurboDocx Advanced Templating Engine. Solutions for common errors, debugging strategies, and best practices. +keywords: + - troubleshooting + - advanced templating errors + - debugging + - template issues + - variable errors + - expression errors + - nested variables issues + - loop errors + - conditional errors + - turbodocx debugging +--- + +# Advanced Templating Troubleshooting + +Encountering issues with Advanced Templating? This comprehensive guide covers common problems, their causes, and solutions. + +## Quick Diagnostic Checklist + +Before diving into specific issues, run through this checklist: + +- [ ] Is `mimeType` correct (`json` or `text` with `usesAdvancedTemplatingEngine: true`)? +- [ ] Is the JSON structure valid? (Test with [JSONLint](https://jsonlint.com/)) +- [ ] Do nested paths exist in the data? (`user.email` requires `user` object with `email` property) + +--- + +## Common Issues + +### 1. Variable Remains as undefined in Output + +#### Symptoms +``` +Template: Hello {user.firstName}! +Output: Hello undefined! +``` + +#### Causes & Solutions + +**Cause 1: Variable not in payload** +```json +// ❌ Missing {user} variable +{ + "variables": [] +} +``` + +**Solution:** +```json +// ✅ Add the variable +{ + "variables": [ + { + "placeholder": "{user}", + "mimeType": "json", + "value": {"firstName": "John"} + } + ] +} +``` + +**Cause 2: Placeholder mismatch** +``` +Template: {user.firstName} +Payload placeholder: "{userData}" // ❌ Wrong name +``` + +**Solution:** +``` +Template: {user.firstName} +Payload placeholder: "{user}" // ✅ Matches +``` + +**Cause 3: Nested path doesn't exist** +```json +// Template: {user.profile.name} +{ + "value": { + "user": { + // ❌ Missing 'profile' property + "name": "John" + } + } +} +``` + +**Solution:** +```json +{ + "value": { + "user": { + "profile": { // ✅ Add missing path + "name": "John" + } + } + } +} +``` + +--- + +### 2. Expression Not Evaluated + +#### Symptoms +``` +Template: Total: ${price + tax} +Output: Total: ${price + tax} +``` + +#### Causes & Solutions + +**Cause 1: Missing `usesAdvancedTemplatingEngine` and `mimeType: "text"` flag or `mimeType: json` flag** +```json +// ❌ Flag not set +{ + "placeholder": "{price}", + "mimeType": "text", + "value": 100 +} +``` + +**Solution:** +```json +// ✅ Add the flag +{ + "placeholder": "{price}", + "mimeType": "text", + "value": "100", + "usesAdvancedTemplatingEngine": true +} +``` + +**Cause 2: One or more variables in expression missing** +```json +// Template: {price + tax} +// ❌ Only provided {price} +{ + "variables": [ + {"placeholder": "{price}", "value": "100", "usesAdvancedTemplatingEngine": true} + ] +} +``` + +**Solution:** +```json +// ✅ Provide all variables +{ + "variables": [ + {"placeholder": "{price}", "value": "100", "usesAdvancedTemplatingEngine": true}, + {"placeholder": "{tax}", "value": "10", "usesAdvancedTemplatingEngine": true} + ] +} +``` + +--- + +### 3. Loop Not Rendering / Empty Output + +#### Symptoms +``` +Template: {#items}{name}{/} +Output: (nothing) +``` + +#### Causes & Solutions + +**Cause 1: Wrong MIME type** +```json +// ❌ Using text instead of json +{ + "placeholder": "{items}", + "mimeType": "text", + "value": "[{\"name\":\"Item 1\"}]" +} +``` + +**Solution:** +```json +// ✅ Use json MIME type +{ + "placeholder": "{items}", + "mimeType": "json", + "value": [ + {"name": "Item 1"} + ] +} +``` + +**Cause 2: Empty array** +```json +{ + "placeholder": "{items}", + "mimeType": "json", + "value": [] // ❌ No items to loop over +} +``` + +**Solution:** Check for empty arrays and provide feedback +``` +Template: +{#items.length > 0} +{#items}{name}{/} +{/} + +{#items.length == 0} +No items available. +{/} +``` + +**Cause 3: Array is nested incorrectly** +```json +// ❌ Array is too deeply nested +{ + "placeholder": "{data}", + "mimeType": "json", + "value": { + "items": [ + {"name": "Item 1"} + ] + } +} +``` + +``` +// Template should be: +{#data.items}{name}{/} // Not {#items} +``` + +--- + +### 4. Conditional Block Not Showing + +#### Symptoms +``` +Template: {#isPremium}Premium User{/} +Output: (nothing) +``` + +#### Causes & Solutions + +**Cause 1: Value is string "false" instead of boolean** +```json +// ❌ String "false" is truthy! +{ + "placeholder": "{isPremium}", + "mimeType": "text", + "value": "false" +} +``` + +**Solution:** Use actual boolean or check string value +```json +// Option 1: Use boolean value (requires preprocessing) +{ + "placeholder": "{isPremium}", + "mimeType": "json", + "value": false +} + +// Option 2: Compare string explicitly +``` + +``` +Template: {#isPremium == "true"}Premium User{/} +``` + +**Cause 2: Comparison operator issue** +``` +// ❌ Using = instead of == +{#status = "active"}Content{/} +``` + +**Solution:** +``` +// ✅ Use == for comparison +{#status == "active"}Content{/} +``` + +**Cause 3: Variable is undefined** +```json +// ❌ isPremium not provided +{ + "variables": [] +} +``` + +**Solution:** Always provide conditional variables +```json +{ + "variables": [ + { + "placeholder": "{isPremium}", + "mimeType": "text", + "value": "true", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +--- + +### 5. Nested Variable Access Not Working + +#### Symptoms +``` +Template: {customer.contact.email} +Output: {customer.contact.email} +``` + +#### Causes & Solutions + +**Cause 1: JSON string instead of object** +```json +// ❌ Stringified JSON +{ + "placeholder": "{customer}", + "mimeType": "json", + "value": "{\"contact\":{\"email\":\"...\"}}" // String, not object +} +``` + +**Solution:** +```json +// ✅ Actual JSON object +{ + "placeholder": "{customer}", + "mimeType": "json", + "value": {"contact": {"email": "john@example.com"}} // Object +} +``` + +**Cause 2: Path doesn't match structure** +``` +Template: {customer.contact.email} + +// ❌ Wrong structure +{ + "value": { + "contact_email": "john@example.com" // Flat, not nested + } +} +``` + +**Solution:** +```json +// ✅ Match template structure +{ + "value": { + "contact": { + "email": "john@example.com" + } + } +} +``` + +--- + +### 6. Arithmetic Calculation Wrong or Not Working + +#### Symptoms +``` +Template: Total: ${price + tax} +Output: Total: NaN +``` +or +``` +Output: Total: 10020 (concatenation instead of addition) +``` + +#### Causes & Solutions + +**Cause 1: Values are strings and concatenating** +```json +// ❌ String concatenation: "100" + "20" = "10020" +{ + "placeholder": "{price}", + "mimeType": "text", + "value": "100" // String +} +``` + +```json +// ✅ Will be converted to numbers +{ + "placeholder": "{price}", + "mimeType": "text", + "value": 100, + "usesAdvancedTemplatingEngine": true +} +``` + +**Cause 2: One variable is undefined** +``` +// Template: {price + tax} +// Only {price} provided, {tax} is undefined +// undefined + 100 = NaN +``` + +**Solution:** Provide all variables in expression +```json +{ + "variables": [ + {"placeholder": "{price}", "value": 100, "usesAdvancedTemplatingEngine": true}, + {"placeholder": "{tax}", "value": 20, "usesAdvancedTemplatingEngine": true} + ] +} +``` + +**Cause 3: Non-numeric value** +```json +{ + "placeholder": "{price}", + "value": "N/A" // ❌ Can't convert to number +} +``` + +**Solution:** Use conditional to handle non-numeric values +``` +{#price != "N/A"} +Total: ${price + tax} +{/} + +{#price == "N/A"} +Price not available +{/} +``` + +--- + +### 7. Array Length or Built-in Properties Not Working + +#### Symptoms +``` +Template: Found {items.length} items +Output: Found {items.length} items +``` + +#### Causes & Solutions + +**Cause 1: Array variable not provided** +```json +// ❌ items not in payload +{ + "variables": [] +} +``` + +**Solution:** +```json +// ✅ Provide array variable +{ + "variables": [ + { + "placeholder": "{items}", + "mimeType": "json", + "value": [ + {"name": "Item 1"}, + {"name": "Item 2"} + ], + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Cause 2: Not an array** +```json +// ❌ Object, not array +{ + "placeholder": "{items}", + "mimeType": "json", + "value": {"count": 2} // Object has no .length +} +``` + +--- + +## Additional Resources + +- [Advanced Templating Engine](./Advanced%20Templating%20Engine.md) - Full feature guide +- [Simple vs Advanced Variables](./Simple%20vs%20Advanced%20Variables.md) - Comparison guide +- [Template Troubleshooting](./Template%20Troubleshooting.md) - General template issues +- [API Templates](./API%20Templates.md) - API integration guide + +--- + +**Last Updated:** January 2026 + +:::tip Still Stuck? +Our support team is here to help! Don't hesitate to reach out at support@turbodocx.com with your specific issue. +::: diff --git a/docs/TurboDocx Templating/Advanced Templating cURL Example.md b/docs/TurboDocx Templating/Advanced Templating cURL Example.md new file mode 100644 index 0000000..ff759a3 --- /dev/null +++ b/docs/TurboDocx Templating/Advanced Templating cURL Example.md @@ -0,0 +1,1279 @@ +--- +title: cURL Example +sidebar_position: 2.1 +description: Complete cURL example demonstrating all advanced templating features with a comprehensive test document +keywords: + - curl example + - api request + - advanced templating + - complete example + - test document + - api integration +--- + +# cURL Example + +This page provides a complete, working cURL example that demonstrates **all advanced templating features** in a single request. Use this as a reference for testing and implementing advanced templating in your applications. + +:::info Note on Sample Data +All names, companies, and personal information in this example are fictional and randomly generated for demonstration purposes only. +::: + +## Complete Test Template + +The template below exercises every feature of the Advanced Templating Engine: + +``` +ADVANCED TEMPLATING ENGINE - COMPLETE TEST DOCUMENT +==================================================== + +SECTION 1: NESTED PROPERTY ACCESS +--------------------------------- +1.1 Simple Nesting: Hello {user.firstName}, your email is {user.email} +1.2 Deep Nesting: Company Lead: {company.divisions.engineering.teamLead.name}, Phone: {company.divisions.engineering.teamLead.contact.phone} +1.3 Array Length: Total items in cart: {cart.items.length} +1.4 Array Index Access: First product: {products[0].name}, Second price: {products[1].price}, Third: {products[2].name} + + +SECTION 2: ARITHMETIC EXPRESSIONS +--------------------------------- +2.1 Basic Addition: {price} + {tax} = {price + tax} +2.2 All Operators: + - Addition: {a} + {b} = {a + b} + - Subtraction: {a} - {b} = {a - b} + - Multiplication: {a} * {b} = {a * b} + - Division: {a} / {b} = {a / b} + - Modulo: {a} % {b} = {a % b} +2.3 Complex Expression: ({basePrice} * {quantity}) + {shipping} - {discount} = {(basePrice * quantity) + shipping - discount} +2.4 Nested Property Math: {item.price} * {item.quantity} = {item.price * item.quantity} +2.5 Percentage: {originalPrice} - {discountPercent}% = {originalPrice - (originalPrice * discountPercent / 100)} + + +SECTION 3: CONDITIONAL LOGIC +---------------------------- +3.1 Boolean Conditions: +{#isActive}[ACTIVE] Account is Active{/} +{#isPremium}[PREMIUM] Premium Member Benefits Applied{/} + +3.2 Numeric Comparisons: +Score: {score} +{#score > 80}Result: Excellent Performance!{/} +{#score > 50}Result: Passed{/} +{#score <= 50}Result: Needs Improvement{/} + +3.3 String Equality: +Status: {status} +{#status == "approved"}Decision: Your request has been APPROVED{/} +{#status == "pending"}Decision: Your request is PENDING review{/} +{#status == "rejected"}Decision: Your request was REJECTED{/} + +3.4 Logical AND/OR: +Age: {age}, Has License: {hasLicense} +{#age >= 18 && hasLicense == true}Eligibility: You are eligible to drive{/} +{#age < 18 || hasLicense == false}Eligibility: You cannot drive yet{/} + +3.5 Nested Conditionals: +User Type: {userType}, Department: {department} +{#userType == "employee"} +--- Employee Section --- +{#department == "engineering"}Department: Engineering Department Benefits{/} +{#department == "sales"}Department: Sales Department Benefits{/} +{/} +{#userType == "contractor"} +--- Contractor Section --- +{/} + +3.6 Array Length Conditional: +{#cartItems.length > 0}Cart Status: You have {cartItems.length} items in your cart{/} +{#cartItems.length == 0}Cart Status: Your cart is empty{/} + +3.7 Truthy/Falsy: +{#nickname}Nickname: {nickname}{/} +{#middleName}Middle Name: {middleName}{/} + + +SECTION 4: LOOPS +---------------- +4.1 Simple Loop - Product List: +{#productList} + - {name}: ${price} +{/productList} + +4.2 Loop with Nested Properties - Team Members: +{#team} + Name: {member.fullName} + Email: {member.contact.email} + Role: {member.role} + --- +{/team} + +4.3 Nested Loops - Departments & Employees: +{#departments} +DEPARTMENT: {deptName} +Employees: +{#employees} + - {employeeName} ({title}) +{/employees} +{/departments} + +4.4 Loop with Conditionals: +{#orderItems} + Product: {productName} - ${itemPrice} + {#isOnSale}*** SALE ITEM ***{/} + {#qty > 5}[Bulk discount applied]{/} +{/orderItems} + +4.5 Loop with Arithmetic: +{#lineItems} + {description}: {quantity} x ${unitPrice} = ${quantity * unitPrice} +{/lineItems} + +SECTION 5: LOGICAL AND/OR +------------------------- +5.1 AND operator +{#cond1 && cond2} +Renders if both conditions are true +{/} +5.2 OR operator +{#cond3 || cond4} +Renders if any one condition is true +{/} +5.3 PARENTHESES +{#(cond1 && cond3) || cond4} +Complex logic with parentheses +{/} + + +SECTION 6: COMPLETE INVOICE (ALL FEATURES COMBINED) +--------------------------------------------------- +INVOICE #{invoice.number} +Date: {invoice.date} +Due Date: {invoice.dueDate} + +BILL TO: +{invCustomer.company} +{invCustomer.address.line1} +{invCustomer.address.line2} +{invCustomer.address.city}, {invCustomer.address.state} {invCustomer.address.zip} +Contact: {invCustomer.contact.name} | {invCustomer.contact.email} + +LINE ITEMS: +{#invLineItems} +| {sku} | {lineDesc} | Qty: {lineQty} | ${linePrice} | Total: ${lineQty * linePrice} | +{#isTaxExempt} [TAX EXEMPT]{/} +{/invLineItems} + +SUMMARY: +Subtotal: ${invTotals.subtotal} +{#invTotals.hasDiscount} +Discount ({invTotals.discountCode}): -${invTotals.discountAmount} +{/} + +TAX BREAKDOWN: +{#taxBreakdown} + {taxName} ({rate}%): ${taxAmt} +{/taxBreakdown} + +------------------------------------------- +TOTAL DUE: ${invTotals.grandTotal} +------------------------------------------- + +Payment Terms: +{#paymentTerms == "NET30"}Payment due within 30 days{/} +{#paymentTerms == "NET60"}Payment due within 60 days{/} +{#paymentTerms == "DUE_ON_RECEIPT"}Payment due upon receipt{/} + +{#invIsPaid} +*** PAID - Thank you for your business! *** +{/} +{#invIsPaid == false} +*** PAYMENT DUE - Please remit payment by due date *** +{/} + + +SECTION 7: EMPLOYEE OFFER LETTER +-------------------------------- +[COMPANY LETTERHEAD] + +Date: {letter.date} + +Dear {candidate.name}, + +We are pleased to offer you the position of {position.title} in our {position.department} department at {offerCompany.name}. + +POSITION DETAILS: +Title: {position.title} +Department: {position.department} +Reports To: {position.manager.name}, {position.manager.title} +Start Date: {position.startDate} +Location: {position.location.office} +{#position.isHybrid}Work Arrangement: Hybrid ({position.hybridDays} days in office per week){/} +{#position.isRemote}Work Arrangement: Fully Remote{/} + +COMPENSATION: +Base Salary: ${compensation.baseSalary} per year ({compensation.payFrequency}) +{#compensation.hasBonus} +Signing Bonus: ${compensation.signingBonus} +Annual Bonus Target: {compensation.bonusTarget}% of base salary +{/} +{#compensation.hasEquity} +Equity: {compensation.equityShares} shares, vesting over {compensation.vestingYears} years +{/} + +BENEFITS: +{#benefits} +- {benefitName}: {benefitDesc} +{/benefits} + +{#relocation.offered} +RELOCATION: +Allowance: ${relocation.allowance} +{#relocation.tempHousing}Temporary Housing: {relocation.tempHousingDays} days{/} +{/} + +Please respond by: {letter.responseDeadline} + +Sincerely, +{letter.signatory.name} +{letter.signatory.title} + + +SECTION 8: PERFORMANCE REVIEW +----------------------------- +ANNUAL PERFORMANCE REVIEW +Period: {reviewPeriod.start} - {reviewPeriod.end} + +EMPLOYEE: +Name: {employee.name} +ID: {employee.id} +Title: {employee.title} +Department: {employee.department} +Manager: {employee.manager.name} +Tenure: {employee.tenure} years + +OVERALL RATING: {overallRating}/5 +{#overallRating >= 4.5}[EXCEPTIONAL PERFORMER]{/} +{#overallRating >= 4 && overallRating < 4.5}[EXCEEDS EXPECTATIONS]{/} +{#overallRating >= 3 && overallRating < 4}[MEETS EXPECTATIONS]{/} +{#overallRating < 3}[NEEDS IMPROVEMENT]{/} + +COMPETENCIES: +{#competencies} +{compName}: {compRating}/5 +{#compRating >= 4} -> Strength{/} +{#compRating < 3} -> Development Area{/} +Comments: {compComments} +{/competencies} + +GOALS: +{#goals} +{goalNumber}. {goalDesc} + Weight: {weight}% | Status: {goalStatus} + {#goalStatus == "completed"}Achievement: {achievement}%{/} + {#goalStatus == "in_progress"}Progress: {progress}%{/} +{/goals} + +Weighted Score: {goalsScore}% + +KEY ACHIEVEMENTS: +{#achievements} +- {achievementDesc} + Impact: {impact} +{/achievements} + +DEVELOPMENT AREAS: +{#developmentAreas} +- {area} + Plan: {actionPlan} + Target: {targetDate} +{/developmentAreas} + +COMPENSATION: +{#compRecommendation.meritIncrease > 0} +Merit Increase: {compRecommendation.meritIncrease}% +New Salary: ${compRecommendation.newSalary} +Effective: {compRecommendation.effectiveDate} +{/} +{#compRecommendation.promotionRecommended} +*** PROMOTION RECOMMENDED: {compRecommendation.newTitle} *** +{/} + + +SECTION 9: SUBSCRIPTION BILLING +------------------------------- +BILLING STATEMENT + +Account: {account.id} +Plan: {account.plan.name} ({account.plan.tier}) +Period: {billingPeriod.start} - {billingPeriod.end} + +BASE CHARGE: ${account.plan.basePrice}/month + +USAGE: +{#usageCharges} +{serviceName}: {usage} {unit} @ ${ratePerUnit}/{unit} = ${usage * ratePerUnit} +{#usage > freeAllowance} (Exceeded free tier by {usage - freeAllowance} {unit}){/} +{/usageCharges} + +{#credits.length > 0} +CREDITS: +{#credits} +{creditDesc}: -${creditAmount} +{/credits} +{/} + +SUMMARY: +Current Charges: ${currentTotal} +{#account.credits > 0}Account Credits: -${account.credits}{/} +--- +AMOUNT DUE: ${currentTotal - account.credits} + +{#account.isAutoPay} +Auto-pay enabled. Card ending in {account.paymentMethod.lastFour} will be charged on {billingPeriod.chargeDate}. +{/} + + +SECTION 10: PURCHASE ORDER +------------------------- +PURCHASE ORDER #{po.number} +Date: {po.date} +Priority: {po.priority} + +REQUESTOR: {po.requestor.name} ({po.requestor.department}) + +VENDOR: +{vendor.name} +{vendor.address} +Contact: {vendor.contact.name} | {vendor.contact.email} + +ITEMS: +{#poItems} +{lineNumber}. {poDesc} + Qty: {poQty} {poUnit} @ ${poUnitCost} = ${poQty * poUnitCost} + {#isUrgent}[URGENT]{/} + {#requiresApproval}[REQUIRES APPROVAL]{/} +{/poItems} + +ORDER TOTAL: ${orderTotal} + +APPROVALS: +{#approvals} +{level}. {approverName} ({approverTitle}) + {#approvalStatus == "approved"}APPROVED - {approvalDate}{/} + {#approvalStatus == "pending"}PENDING{/} + {#approvalStatus == "rejected"}REJECTED: {reason}{/} +{/approvals} + +{#allApproved}*** ORDER APPROVED - Ready for Processing ***{/} +{#allApproved == false}*** AWAITING APPROVAL ***{/} + + +SECTION 11: BACKWARD COMPATIBILITY +---------------------------------- +Simple Variables Test: +Hello {firstName} {lastName}! +Your email is {simpleEmail}. + +==================================================== +END OF TEST DOCUMENT +==================================================== +``` + +## cURL Request + +Replace the placeholder values (`YOUR_API_KEY`, `YOUR_ORG_ID`) with your actual credentials: + +```bash +curl -X POST https://api.turbodocx.com/v1/deliverables \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "x-rapiddocx-org-id: YOUR_ORG_ID" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Example Deliverable", + "description": "Example showing advance features", + "templateId": "TemplateID", + "variables": [ + { + "placeholder": "{user}", + "mimeType": "json", + "value": { + "firstName": "User001", + "email": "user001@example.com" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{company}", + "mimeType": "json", + "value": { + "divisions": { + "engineering": { + "teamLead": { + "name": "Lead789", + "contact": { + "phone": "+1-555-0100" + } + } + } + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cart}", + "mimeType": "json", + "value": { + "items": [ + {"id": 1}, + {"id": 2}, + {"id": 3} + ] + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{products}", + "mimeType": "json", + "value": [ + {"name": "Laptop", "price": 999.99}, + {"name": "Mouse", "price": 29.99}, + {"name": "Keyboard", "price": 79.99} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{price}", + "mimeType": "text", + "value": 100, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{tax}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{a}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{b}", + "mimeType": "text", + "value": 3, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{basePrice}", + "mimeType": "text", + "value": 50, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{quantity}", + "mimeType": "text", + "value": 2, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{shipping}", + "mimeType": "text", + "value": 15, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{discount}", + "mimeType": "text", + "value": 10, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{item}", + "mimeType": "json", + "value": { + "price": 25, + "quantity": 4 + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{originalPrice}", + "mimeType": "text", + "value": 200, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{discountPercent}", + "mimeType": "text", + "value": 20, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{isActive}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{isPremium}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{score}", + "mimeType": "text", + "value": 85, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{status}", + "mimeType": "text", + "value": "approved", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{age}", + "mimeType": "text", + "value": 25, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{hasLicense}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{userType}", + "mimeType": "text", + "value": "employee", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{department}", + "mimeType": "text", + "value": "engineering", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cartItems}", + "mimeType": "json", + "value": [ + {"id": 1}, + {"id": 2} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{nickname}", + "mimeType": "text", + "value": "Nickname123", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{middleName}", + "mimeType": "text", + "value": "", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{productList}", + "mimeType": "json", + "value": [ + {"name": "Product A", "price": 29.99}, + {"name": "Product B", "price": 49.99}, + {"name": "Product C", "price": 19.99} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{team}", + "mimeType": "json", + "value": [ + { + "member": { + "fullName": "Member456", + "contact": {"email": "member456@company.example"}, + "role": "Senior Developer" + } + }, + { + "member": { + "fullName": "Member789", + "contact": {"email": "member789@company.example"}, + "role": "Designer" + } + } + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{departments}", + "mimeType": "json", + "value": [ + { + "deptName": "Engineering", + "employees": [ + {"employeeName": "Employee123", "title": "Developer"}, + {"employeeName": "Manager456", "title": "Manager"} + ] + }, + { + "deptName": "Sales", + "employees": [ + {"employeeName": "Rep789", "title": "Sales Rep"} + ] + } + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{orderItems}", + "mimeType": "json", + "value": [ + {"productName": "Widget A", "itemPrice": 25.00, "isOnSale": true, "qty": 10}, + {"productName": "Widget B", "itemPrice": 50.00, "isOnSale": false, "qty": 3} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{lineItems}", + "mimeType": "json", + "value": [ + {"description": "Service Fee", "quantity": 1, "unitPrice": 100}, + {"description": "Consulting Hours", "quantity": 5, "unitPrice": 150} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cond1}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cond2}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cond3}", + "mimeType": "text", + "value": false, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{cond4}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{invoice}", + "mimeType": "json", + "value": { + "number": "INV-2024-001", + "date": "2024-01-15", + "dueDate": "2024-02-15" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{invCustomer}", + "mimeType": "json", + "value": { + "company": "Company XYZ", + "address": { + "line1": "123 Business St", + "line2": "Suite 100", + "city": "San Francisco", + "state": "CA", + "zip": "94105" + }, + "contact": { + "name": "Contact001", + "email": "contact@company-xyz.example" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{invLineItems}", + "mimeType": "json", + "value": [ + {"sku": "PROD-001", "lineDesc": "Professional Services", "lineQty": 10, "linePrice": 150, "isTaxExempt": false}, + {"sku": "PROD-002", "lineDesc": "Software License", "lineQty": 5, "linePrice": 200, "isTaxExempt": true} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{invTotals}", + "mimeType": "json", + "value": { + "subtotal": 2500, + "hasDiscount": true, + "discountCode": "SAVE10", + "discountAmount": 250, + "grandTotal": 2475 + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{taxBreakdown}", + "mimeType": "json", + "value": [ + {"taxName": "State Tax", "rate": 8, "taxAmt": 180}, + {"taxName": "County Tax", "rate": 1.5, "taxAmt": 33.75} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{paymentTerms}", + "mimeType": "text", + "value": "NET30", + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{invIsPaid}", + "mimeType": "text", + "value": false, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{letter}", + "mimeType": "json", + "value": { + "date": "January 15, 2024", + "responseDeadline": "January 30, 2024", + "signatory": { + "name": "Signatory001", + "title": "VP of Human Resources" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{candidate}", + "mimeType": "json", + "value": { + "name": "Candidate789" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{position}", + "mimeType": "json", + "value": { + "title": "Senior Software Engineer", + "department": "Engineering", + "manager": { + "name": "Manager001", + "title": "Engineering Manager" + }, + "startDate": "February 1, 2024", + "location": { + "office": "San Francisco HQ" + }, + "isHybrid": true, + "hybridDays": 3, + "isRemote": false + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{offerCompany}", + "mimeType": "json", + "value": { + "name": "Organization ABC" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{compensation}", + "mimeType": "json", + "value": { + "baseSalary": 150000, + "payFrequency": "bi-weekly", + "hasBonus": true, + "signingBonus": 10000, + "bonusTarget": 15, + "hasEquity": true, + "equityShares": 5000, + "vestingYears": 4 + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{benefits}", + "mimeType": "json", + "value": [ + {"benefitName": "Health Insurance", "benefitDesc": "Comprehensive medical, dental, vision"}, + {"benefitName": "401(k)", "benefitDesc": "6% company match"}, + {"benefitName": "PTO", "benefitDesc": "20 days vacation + 10 holidays"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{relocation}", + "mimeType": "json", + "value": { + "offered": true, + "allowance": 15000, + "tempHousing": true, + "tempHousingDays": 30 + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{reviewPeriod}", + "mimeType": "json", + "value": { + "start": "2023-01-01", + "end": "2023-12-31" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{employee}", + "mimeType": "json", + "value": { + "name": "EMP456", + "id": "EMP-12345", + "title": "Senior Developer", + "department": "Engineering", + "manager": { + "name": "Supervisor123" + }, + "tenure": 3 + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{overallRating}", + "mimeType": "text", + "value": 4.5, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{competencies}", + "mimeType": "json", + "value": [ + {"compName": "Technical Skills", "compRating": 5, "compComments": "Exceptional coding abilities"}, + {"compName": "Communication", "compRating": 4, "compComments": "Strong communicator"}, + {"compName": "Leadership", "compRating": 3, "compComments": "Room for growth"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{goals}", + "mimeType": "json", + "value": [ + {"goalNumber": 1, "goalDesc": "Complete Project X", "weight": 40, "goalStatus": "completed", "achievement": 100}, + {"goalNumber": 2, "goalDesc": "Mentor 2 junior developers", "weight": 30, "goalStatus": "completed", "achievement": 100}, + {"goalNumber": 3, "goalDesc": "Learn new framework", "weight": 30, "goalStatus": "in_progress", "progress": 75} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{goalsScore}", + "mimeType": "text", + "value": 92.5, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{achievements}", + "mimeType": "json", + "value": [ + {"achievementDesc": "Led migration to microservices architecture", "impact": "Reduced deployment time by 50%"}, + {"achievementDesc": "Implemented automated testing suite", "impact": "Improved code quality metrics by 30%"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{developmentAreas}", + "mimeType": "json", + "value": [ + {"area": "Public speaking", "actionPlan": "Attend public speaking workshop", "targetDate": "Q2 2024"}, + {"area": "Project management", "actionPlan": "Complete project management certification", "targetDate": "Q3 2024"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{compRecommendation}", + "mimeType": "json", + "value": { + "meritIncrease": 8, + "newSalary": 162000, + "effectiveDate": "2024-01-01", + "promotionRecommended": true, + "newTitle": "Staff Engineer" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{account}", + "mimeType": "json", + "value": { + "id": "ACC-789456", + "plan": { + "name": "Professional", + "tier": "Pro", + "basePrice": 99 + }, + "credits": 25, + "isAutoPay": true, + "paymentMethod": { + "lastFour": "1234" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{billingPeriod}", + "mimeType": "json", + "value": { + "start": "2024-01-01", + "end": "2024-01-31", + "chargeDate": "2024-02-01" + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{usageCharges}", + "mimeType": "json", + "value": [ + {"serviceName": "API Calls", "usage": 150000, "unit": "calls", "ratePerUnit": 0.001, "freeAllowance": 100000}, + {"serviceName": "Storage", "usage": 500, "unit": "GB", "ratePerUnit": 0.10, "freeAllowance": 100} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{credits}", + "mimeType": "json", + "value": [ + {"creditDesc": "Referral bonus", "creditAmount": 10}, + {"creditDesc": "Service credit", "creditAmount": 15} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{currentTotal}", + "mimeType": "text", + "value": 249, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{po}", + "mimeType": "json", + "value": { + "number": "PO-2024-0042", + "date": "2024-01-15", + "priority": "High", + "requestor": { + "name": "Requestor789", + "department": "IT" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{vendor}", + "mimeType": "json", + "value": { + "name": "Vendor XYZ Ltd", + "address": "456 Supplier Blvd, Supply City, SC 12345", + "contact": { + "name": "VendorContact456", + "email": "vendor@supplier-xyz.example" + } + }, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{poItems}", + "mimeType": "json", + "value": [ + {"lineNumber": 1, "poDesc": "Laptop computers", "poQty": 10, "poUnit": "units", "poUnitCost": 1200, "isUrgent": true, "requiresApproval": true}, + {"lineNumber": 2, "poDesc": "Office chairs", "poQty": 15, "poUnit": "units", "poUnitCost": 300, "isUrgent": false, "requiresApproval": false} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{orderTotal}", + "mimeType": "text", + "value": 16500, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{approvals}", + "mimeType": "json", + "value": [ + {"level": 1, "approverName": "Approver001", "approverTitle": "Department Manager", "approvalStatus": "approved", "approvalDate": "2024-01-16"}, + {"level": 2, "approverName": "Approver002", "approverTitle": "Finance Director", "approvalStatus": "approved", "approvalDate": "2024-01-17"}, + {"level": 3, "approverName": "Approver003", "approverTitle": "VP Operations", "approvalStatus": "approved", "approvalDate": "2024-01-18"} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{allApproved}", + "mimeType": "text", + "value": true, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{firstName}", + "mimeType": "text", + "value": "TestUser" + }, + { + "placeholder": "{lastName}", + "mimeType": "text", + "value": "LastName" + }, + { + "placeholder": "{simpleEmail}", + "mimeType": "text", + "value": "testuser@example.com" + } + ] +}' +``` + +## Expected Output + +When the above template is processed with the provided payload, you will receive a response similar to: + +```json +{ + "id": "deliverable-uuid-here", + "name": "Value Testing with 0", + "description": "Testing ALL advanced templating features", + "status": "processing", + "templateId": "TemplateID", + "createdAt": "2024-01-15T10:30:00Z", + "updatedAt": "2024-01-15T10:30:00Z" +} +``` + +The generated document will contain output similar to: + +``` +ADVANCED TEMPLATING ENGINE - COMPLETE TEST DOCUMENT +==================================================== + +SECTION 1: NESTED PROPERTY ACCESS +--------------------------------- +1.1 Simple Nesting: Hello User001, your email is user001@example.com +1.2 Deep Nesting: Company Lead: Lead789, Phone: +1-555-0100 +1.3 Array Length: Total items in cart: 3 +1.4 Array Index Access: First product: Laptop, Second price: 29.99, Third: Keyboard + + +SECTION 2: ARITHMETIC EXPRESSIONS +--------------------------------- +2.1 Basic Addition: 100 + 10 = 110 +2.2 All Operators: + - Addition: 10 + 3 = 13 + - Subtraction: 10 - 3 = 7 + - Multiplication: 10 * 3 = 30 + - Division: 10 / 3 = 3.333333333333333 + - Modulo: 10 % 3 = 1 +2.3 Complex Expression: (50 * 2) + 15 - 10 = 105 +2.4 Nested Property Math: 25 * 4 = 100 +2.5 Percentage: 200 - 20% = 160 + + +SECTION 3: CONDITIONAL LOGIC +---------------------------- +3.1 Boolean Conditions: +[ACTIVE] Account is Active +[PREMIUM] Premium Member Benefits Applied + +3.2 Numeric Comparisons: +Score: 85 +Result: Excellent Performance! +Result: Passed + +3.3 String Equality: +Status: approved +Decision: Your request has been APPROVED + +3.4 Logical AND/OR: +Age: 25, Has License: true +Eligibility: You are eligible to drive + +3.5 Nested Conditionals: +User Type: employee, Department: engineering +--- Employee Section --- +Department: Engineering Department Benefits + +3.6 Array Length Conditional: +Cart Status: You have 2 items in your cart + +3.7 Truthy/Falsy: +Nickname: Nickname123 + + +SECTION 4: LOOPS +---------------- +4.1 Simple Loop - Product List: + - Product A: $29.99 + - Product B: $49.99 + - Product C: $19.99 + +4.2 Loop with Nested Properties - Team Members: + Name: Member456 + Email: member456@company.example + Role: Senior Developer + --- + Name: Member789 + Email: member789@company.example + Role: Designer + --- + +4.3 Nested Loops - Departments & Employees: +DEPARTMENT: Engineering +Employees: + - Employee123 (Developer) + - Manager456 (Manager) +DEPARTMENT: Sales +Employees: + - Rep789 (Sales Rep) + +4.4 Loop with Conditionals: + Product: Widget A - $25.00 + *** SALE ITEM *** + [Bulk discount applied] + Product: Widget B - $50.00 + +4.5 Loop with Arithmetic: + Service Fee: 1 x $100 = $100 + Consulting Hours: 5 x $150 = $750 + +SECTION 5: LOGICAL AND/OR +------------------------- +5.1 AND operator +Renders if both conditions are true + +5.2 OR operator +Renders if any one condition is true + +5.3 PARENTHESES +Complex logic with parentheses + + +SECTION 6: COMPLETE INVOICE (ALL FEATURES COMBINED) +--------------------------------------------------- +INVOICE #INV-2024-001 +Date: 2024-01-15 +Due Date: 2024-02-15 + +BILL TO: +Company XYZ +123 Business St +Suite 100 +San Francisco, CA 94105 +Contact: Contact001 | contact@company-xyz.example + +LINE ITEMS: +| PROD-001 | Professional Services | Qty: 10 | $150 | Total: $1500 | +| PROD-002 | Software License | Qty: 5 | $200 | Total: $1000 | + [TAX EXEMPT] + +SUMMARY: +Subtotal: $2500 +Discount (SAVE10): -$250 + +TAX BREAKDOWN: + State Tax (8%): $180 + County Tax (1.5%): $33.75 + +------------------------------------------- +TOTAL DUE: $2475 +------------------------------------------- + +Payment Terms: +Payment due within 30 days + +*** PAYMENT DUE - Please remit payment by due date *** + + +SECTION 7: EMPLOYEE OFFER LETTER +-------------------------------- +[COMPANY LETTERHEAD] + +Date: January 15, 2024 + +Dear Candidate789, + +We are pleased to offer you the position of Senior Software Engineer in our Engineering department at Organization ABC. + +POSITION DETAILS: +Title: Senior Software Engineer +Department: Engineering +Reports To: Manager001, Engineering Manager +Start Date: February 1, 2024 +Location: San Francisco HQ +Work Arrangement: Hybrid (3 days in office per week) + +COMPENSATION: +Base Salary: $150000 per year (bi-weekly) +Signing Bonus: $10000 +Annual Bonus Target: 15% of base salary +Equity: 5000 shares, vesting over 4 years + +BENEFITS: +- Health Insurance: Comprehensive medical, dental, vision +- 401(k): 6% company match +- PTO: 20 days vacation + 10 holidays + +RELOCATION: +Allowance: $15000 +Temporary Housing: 30 days + +Please respond by: January 30, 2024 + +Sincerely, +Signatory001 +VP of Human Resources + + +[... Additional sections continue with populated data ...] + + +SECTION 11: BACKWARD COMPATIBILITY +---------------------------------- +Simple Variables Test: +Hello TestUser LastName! +Your email is testuser@example.com. + +==================================================== +END OF TEST DOCUMENT +==================================================== +``` + +## Key Points + +- **Authorization**: Use `Bearer YOUR_API_KEY` in the Authorization header +- **Organization ID**: Include your organization ID in the `x-rapiddocx-org-id` header +- **Template ID**: Replace `TemplateID` with your actual template ID +- **All Variables**: Must have `usesAdvancedTemplatingEngine: true` with `mimeType: "text"` or `mimeType: "json"` for advanced features. +- **Numeric Values**: Use numbers, not strings, for arithmetic operations + + +## Related Documentation + +- [Advanced Templating Engine](./Advanced%20Templating%20Engine.md) +- [Create a Deliverable](./How%20to%20Create%20a%20Deliverable.md) +- [API Templates](./API%20Templates.md) + +--- + +**Need Help?** +- 📧 Email: support@turbodocx.com +- 💬 Discord Community: https://discord.gg/turbodocx +- 📚 Knowledge Base: https://docs.turbodocx.com diff --git a/docs/TurboDocx Templating/Simple vs Advanced Variables.md b/docs/TurboDocx Templating/Simple vs Advanced Variables.md new file mode 100644 index 0000000..c42f2ea --- /dev/null +++ b/docs/TurboDocx Templating/Simple vs Advanced Variables.md @@ -0,0 +1,669 @@ +--- +title: Simple vs Advanced Variables +sidebar_position: 3 +description: Comprehensive comparison between Simple and Advanced Variables in TurboDocx. Learn when to use each approach, migration strategies, and see side-by-side examples. +keywords: + - simple variables + - advanced variables + - variable comparison + - migration guide + - turbodocx variables + - template variables + - variable types + - nested variables + - json variables +--- + +# Simple vs Advanced Variables + +Choose the right variable approach for your document automation needs. This guide compares Simple and Advanced variables side-by-side to help you make informed decisions. + +## Quick Comparison + +| Feature | Simple Variables | Advanced Variables | +|---------|-----------------|-------------------| +| **Setup Complexity** | ⭐ Easy | ⭐⭐ Moderate | +| **Payload Size** | Large (many variables) | Small (fewer, structured) | +| **Rich Text Support** | Yes | No | +| **Data Structure** | Flat | Nested/hierarchical | +| **Calculations** | ❌ No | ✅ Yes (arithmetic) | +| **Conditionals** | ❌ No | ✅ Yes (show/hide) | +| **Loops** | ❌ No | ✅ Yes (arrays) | +| **Preview Mode** | ✅ Full support | ⚠️ Limited support | +| **Best For** | Simple forms, static content | Complex documents, dynamic logic | + +--- + +## When to Use Each Approach + +### Use Simple Variables When: + +- ✅ Building basic templates with static content +- ✅ Using UI-based template preview extensively +- ✅ Working with non-technical users +- ✅ Templates have < 20 variables +- ✅ No calculations or conditional logic needed +- ✅ Quick prototyping or proof-of-concept +- ✅ Simple mail merge style documents + +### Use Advanced Variables When: + +- ✅ Working with complex, structured data +- ✅ Need calculations or dynamic content +- ✅ Templates have > 20 related variables +- ✅ Data comes from APIs or databases +- ✅ Need conditional rendering +- ✅ Working with lists or repeating sections +- ✅ Building invoice, reports, or complex contracts + +--- + +## Side-by-Side Examples + +### Example 1: Contact Information + +#### Simple Variables Approach + +**Template:** +``` +Contact: {firstName} {lastName} +Email: {email} +Phone: {phone} +Address: {street} +City: {city} +State: {state} +ZIP: {zip} +``` + +**Payload (7 variables):** +```json +{ + "variables": [ + { + "placeholder": "{firstName}", + "mimeType": "text", + "value": "Jane" + }, + { + "placeholder": "{lastName}", + "mimeType": "text", + "value": "Smith" + }, + { + "placeholder": "{email}", + "mimeType": "text", + "value": "jane.smith@example.com" + }, + { + "placeholder": "{phone}", + "mimeType": "text", + "value": "+1-555-0123" + }, + { + "placeholder": "{street}", + "mimeType": "text", + "value": "123 Main St" + }, + { + "placeholder": "{city}", + "mimeType": "text", + "value": "San Francisco" + }, + { + "placeholder": "{state}", + "mimeType": "text", + "value": "CA" + }, + { + "placeholder": "{zip}", + "mimeType": "text", + "value": "94102" + } + ] +} +``` + +**Pros:** +- ✅ Simple to understand +- ✅ Easy to test in UI +- ✅ Works in preview mode + +**Cons:** +- ❌ 8 separate variables to manage +- ❌ Large payload +- ❌ No logical grouping + +--- + +#### Advanced Variables Approach + +**Template:** +``` +Contact: {contact.firstName} {contact.lastName} +Email: {contact.email} +Phone: {contact.phone} +Address: {contact.address.street} +City: {contact.address.city} +State: {contact.address.state} +ZIP: {contact.address.zip} +``` + +**Payload (1 variable):** +```json +{ + "variables": [ + { + "placeholder": "{contact}", + "mimeType": "json", + "value": { + "firstName": "Jane", + "lastName": "Smith", + "email": "jane.smith@example.com", + "phone": "+1-555-0123", + "address": { + "street": "123 Main St", + "city": "San Francisco", + "state": "CA", + "zip": "94102" + } + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Pros:** +- ✅ Single structured object +- ✅ Mirrors your data model +- ✅ Easier to maintain +- ✅ Smaller payload + +**Cons:** +- ❌ Can't preview in UI mode +- ❌ Requires JSON structure +- ❌ Slightly more complex setup + +**Winner:** 🏆 Advanced Variables (for structured data) + +--- + +### Example 2: Invoice with Line Items + +#### Simple Variables Approach + +**Not Feasible** ❌ + +Simple variables cannot handle repeating line items without pre-generating individual variables for each possible line item (e.g., `{item1Name}`, `{item2Name}`, etc.), which is impractical. + +**Workaround (limited to fixed number of items):** +``` +Template: +Item 1: {item1Name} - ${item1Price} +Item 2: {item2Name} - ${item2Price} +Item 3: {item3Name} - ${item3Price} +Total: {total} +``` + +**Issues:** +- ❌ Fixed number of items +- ❌ Empty items show blank lines +- ❌ Can't handle variable-length lists +- ❌ Requires many placeholder variables + +--- + +#### Advanced Variables Approach + +**Template:** +``` +INVOICE + +{#lineItems} +{lineItems.name} +Qty: {lineItems.quantity} × ${lineItems.price} = ${lineItems.quantity * lineItems.price} +--- +{/} + +Subtotal: ${subtotal} +Tax (10%): ${subtotal * 0.10} +TOTAL: ${subtotal + (subtotal * 0.10)} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{lineItems}", + "mimeType": "json", + "value": [ + {"name": "Widget A", "quantity": 5, "price": 25.00}, + {"name": "Widget B", "quantity": 3, "price": 40.00}, + {"name": "Widget C", "quantity": 2, "price": 15.00} + ], + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{subtotal}", + "mimeType": "text", + "value": "275.00", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Output:** +``` +INVOICE + +Widget A +Qty: 5 × $25.00 = $125.00 +--- +Widget B +Qty: 3 × $40.00 = $120.00 +--- +Widget C +Qty: 2 × $15.00 = $30.00 +--- + +Subtotal: $275.00 +Tax (10%): $27.50 +TOTAL: $302.50 +``` + +**Winner:** 🏆 Advanced Variables (only viable option) + +--- + +### Example 3: Conditional Content + +#### Simple Variables Approach + +**Template (requires multiple versions):** +``` +Status: {status} + +(Must create separate templates for each status or show all content) +``` + +**Issues:** +- ❌ No way to show/hide sections +- ❌ Must pre-process content +- ❌ Requires template versioning +- ❌ All content always visible + +--- + +#### Advanced Variables Approach + +**Template (single version handles all cases):** +``` +Status: {status} + +{#status == "approved"} +✓ Your application has been APPROVED +Next steps: Complete onboarding +{/} + +{#status == "pending"} +⏳ Your application is UNDER REVIEW +Estimated time: 2-3 business days +{/} + +{#status == "rejected"} +✗ Your application was NOT APPROVED +{/} +``` + +**Payload:** +```json +{ + "variables": [ + { + "placeholder": "{status}", + "mimeType": "text", + "value": "approved", + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Winner:** 🏆 Advanced Variables (only viable option) + +--- + +### Example 4: Price Calculations + +#### Simple Variables Approach + +**Template:** +``` +Base Price: ${basePrice} +Tax: ${tax} +Shipping: ${shipping} +Total: ${total} +``` + +**Payload (pre-calculated backend):** +```json +{ + "variables": [ + {"placeholder": "{basePrice}", "mimeType": "text", "value": "100.00"}, + {"placeholder": "{tax}", "mimeType": "text", "value": "10.00"}, + {"placeholder": "{shipping}", "mimeType": "text", "value": "15.00"}, + {"placeholder": "{total}", "mimeType": "text", "value": "125.00"} + ] +} +``` + +**Issues:** +- ⚠️ Need to provide value for each data +- ⚠️ Risk of calculation error and wrong data + +--- + +#### Advanced Variables Approach + +**Template:** +``` +Base Price: ${basePrice} +Tax (10%): ${basePrice * 0.10} +Shipping: ${shipping} +Total: ${basePrice + (basePrice * 0.10) + shipping} +``` + +**Payload (raw values):** +```json +{ + "variables": [ + { + "placeholder": "{basePrice}", + "mimeType": "text", + "value": 100.00, + "usesAdvancedTemplatingEngine": true + }, + { + "placeholder": "{shipping}", + "mimeType": "text", + "value": 15.00, + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +**Winner:** 🏆 Advanced Variables (calculations in template) + +--- + +## Migration Path + +### When to Migrate + +Consider migrating from Simple to Advanced variables when: + +- ✅ Template complexity increasing +- ✅ Managing 20+ variables per template +- ✅ Need calculations or conditional logic +- ✅ Data comes from structured sources (APIs, databases) +- ✅ Multiple related fields (addresses, contact info, etc.) +- ✅ Need repeating sections + +### When NOT to Migrate + +:::warning Do Not Migrate for Rich Text Content +**Do NOT migrate to advanced variables** if your nested variables need to render **rich text content** (bold, italic, colors, formatting, etc.). + +**Why:** Advanced templating features do not support rich text data - all formatting will be lost and content will render as plain text only. + +**Solution:** Keep using separate simple variables for each piece of rich text content instead of grouping them into nested structures. + +**Example:** +``` +❌ Don't use: {user.bio} // Rich text will lose formatting +✅ Use instead: {userBio} // Keeps rich text formatting +``` +::: + +### Migration Strategy + +#### Step 1: Identify Candidate Variables + +Look for related variables that can be grouped: + +``` +Before: +{firstName}, {lastName}, {email}, {phone} + +After: +{user.firstName}, {user.lastName}, {user.email}, {user.phone} +``` + +#### Step 2: Update Template + +Update placeholders to use dot notation: + +```diff +- Hello {firstName} {lastName}! ++ Hello {user.firstName} {user.lastName}! + +- Contact: {email} ++ Contact: {user.email} +``` + +#### Step 3: Restructure Payload + +Convert flat variables to nested structure: + +**Before:** +```json +{ + "variables": [ + {"placeholder": "{firstName}", "value": "John"}, + {"placeholder": "{lastName}", "value": "Doe"}, + {"placeholder": "{email}", "value": "john@example.com"} + ] +} +``` + +**After:** +```json +{ + "variables": [ + { + "placeholder": "{user}", + "mimeType": "json", + "value": { + "firstName": "John", + "lastName": "Doe", + "email": "john@example.com" + } + "usesAdvancedTemplatingEngine": true + } + ] +} +``` + +### Gradual Migration + +You can mix both approaches during migration: + +**Hybrid Template:** +``` +// Keep simple for now +Name: {firstName} {lastName} + +// Migrated to advanced +Address: {customer.address.street} + {customer.address.city}, {customer.address.state} + +// Calculate total +Total: ${price + tax} +``` + +**Hybrid Payload:** +```json +{ + "variables": [ + {"placeholder": "{firstName}", "mimeType": "text", "value": "John"}, + {"placeholder": "{lastName}", "mimeType": "text", "value": "Doe"}, + { + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "address": { + "street": "123 Main St", + "city": "San Francisco", + "state": "CA" + } + }, + "usesAdvancedTemplatingEngine": true + }, + {"placeholder": "{price}", "mimeType": "text", "value": 100, "usesAdvancedTemplatingEngine": true}, + {"placeholder": "{tax}", "mimeType": "text", "value": 10, "usesAdvancedTemplatingEngine": true} + ] +} +``` + +--- + +## Decision Matrix + +Use this matrix to decide which approach to use for your use case: + +| Your Scenario | Recommended Approach | Reason | +|---------------|---------------------|--------| +| Simple form letter with < 10 fields | **Simple Variables** | Easier to set up and test | +| Customer profiles with multiple sections | **Advanced Variables** | Natural grouping of related data | +| Invoice with line items | **Advanced Variables** | Requires loops | +| Certificate with name and date only | **Simple Variables** | Overkill for 2 variables | +| Contract with conditional clauses | **Advanced Variables** | Needs conditional logic | +| Report with calculations | **Advanced Variables** | Needs arithmetic | +| Mail merge from spreadsheet | **Simple Variables** | Direct mapping from columns | +| Integration with REST API | **Advanced Variables** | Mirrors JSON response | +| UI-driven template builder | **Simple Variables** | Preview mode compatibility | +| Programmatic document generation | **Advanced Variables** | More efficient | + +--- + +## Common Patterns + +### Pattern 1: Customer Data + +**Use:** Advanced Variables + +```json +{ + "placeholder": "{customer}", + "mimeType": "json", + "value": { + "name": {"first": "Jane", "last": "Smith"}, + "contact": {"email": "...", "phone": "..."}, + "address": {"street": "...", "city": "...", ...} + } +} +``` + +### Pattern 2: Simple Certificate + +**Use:** Simple Variables + +```json +{ + "variables": [ + {"placeholder": "{recipientName}", "value": "John Doe"}, + {"placeholder": "{courseName}", "value": "Advanced JavaScript"}, + {"placeholder": "{completionDate}", "value": "January 15, 2024"} + ] +} +``` + +### Pattern 3: Invoice with Items + +**Use:** Advanced Variables (required) + +```json +{ + "placeholder": "{lineItems}", + "mimeType": "json", + "value": [ + {"name": "Item 1", "qty": 5, "price": 25.00}, + {"name": "Item 2", "qty": 3, "price": 40.00} + ] +} +``` + +### Pattern 4: Form Letter + +**Use:** Simple Variables + +```json +{ + "variables": [ + {"placeholder": "{date}", "value": "January 15, 2024"}, + {"placeholder": "{recipientName}", "value": "John Doe"}, + {"placeholder": "{senderName}", "value": "Jane Smith"} + ] +} +``` + +--- + +## Frequently Asked Questions + +### Can I mix Simple and Advanced variables in one template? + +Yes! You can use both approaches in the same template during migration or based on specific needs. + +### Will Simple variables become deprecated? + +No. Simple variables are fully supported and will continue to work. Choose based on your needs. + +### Which approach is more performant? + +Both perform similarly for small templates. Advanced variables are more efficient for large, complex templates with many related variables. + +### Can I convert Advanced variables back to Simple? + +Yes, you can "flatten" nested structures back to simple variables, though you'll lose the benefits of nesting, calculations, and logic. + +### Do Advanced variables cost more? + +No. Pricing is based on document generation, not variable complexity. + +### Which approach works with the API? + +Both work with all TurboDocx APIs. The payload structure is the only difference. + +--- + +## Summary + +| Aspect | Simple Variables | Advanced Variables | +|--------|-----------------|-------------------| +| **Complexity** | Low | Medium | +| **Flexibility** | Limited | High | +| **Rich Text Support** | Full | None | +| **Preview Support** | Full | Limited | +| **Calculations** | None | Built-in | +| **Conditionals** | None | Built-in | +| **Loops** | None | Built-in | +| **Payload Size** | Larger | Smaller | +| **Best For** | Simple templates | Complex templates | + +**Bottom Line:** Start with Simple variables for basic needs, graduate to Advanced variables as your templates grow in complexity. + +--- + +## Additional Resources + +- [Advanced Templating Engine](./Advanced%20Templating%20Engine.md) - Full advanced features guide +- [How to Create a Template](./How%20to%20Create%20a%20Template.md) - Template basics +- [Template Troubleshooting](./Template%20Troubleshooting.md) - Common issues and fixes + +--- + +**Still unsure which to use?** Contact our support team at support@turbodocx.com and we'll help you choose the best approach for your use case. diff --git a/sidebars.js b/sidebars.js index 2283057..e9435b4 100644 --- a/sidebars.js +++ b/sidebars.js @@ -23,8 +23,91 @@ const sidebars = { collapsed: false, items: [ { - type: 'autogenerated', - dirName: 'TurboDocx Templating', + type: 'doc', + id: 'TurboDocx Templating/API Templates', + label: 'Template Generation API', + }, + { + type: 'doc', + id: 'TurboDocx Templating/How to Create a Template', + label: 'How to Create a Template', + }, + { + type: 'doc', + id: 'TurboDocx Templating/How to Create a Document Template', + label: 'How to Create a Document Template', + }, + { + type: 'doc', + id: 'TurboDocx Templating/How to Create a Presentation Template', + label: 'How to Create a Presentation Template', + }, + { + type: 'doc', + id: 'TurboDocx Templating/How to Create a Deliverable', + label: 'How to Create a Deliverable', + }, + { + type: 'doc', + id: 'TurboDocx Templating/How to Create a Knowledgebase Entry', + label: 'How to Create a Knowledgebase Entry', + }, + { + type: 'category', + label: 'Advanced Templating Engine', + collapsed: true, + items: [ + { + type: 'doc', + id: 'TurboDocx Templating/Advanced Templating Engine', + label: 'Overview & Features', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Simple vs Advanced Variables', + label: 'Simple vs Advanced Variables', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Advanced Templating Troubleshooting', + label: 'Troubleshooting', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Advanced Templating cURL Example', + label: 'Advanced Templating CURL Example', + }, + ], + }, + { + type: 'doc', + id: 'TurboDocx Templating/ai-variable-generation', + label: 'AI Variable Generation', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Brand Identity', + label: 'Brand Identity', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Office Integration', + label: 'Office Integration', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Working with Fonts', + label: 'Working with Fonts', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Template Troubleshooting', + label: 'Template Troubleshooting', + }, + { + type: 'doc', + id: 'TurboDocx Templating/Additional Information', + label: 'Additional Information', }, ], },