Advanced
Advanced Templating
DBindly v2.3.0 introduces powerful templating features for more flexible data rendering.
Template Syntax
Basic Interpolation
Use double curly braces to insert field values:
<div dbind_repeat="users">
<p>Hello, {{name}}!</p>
</div>
Nested Properties
Access nested data with dot notation:
<div dbind_repeat="orders">
<p>Customer: {{customer.name}}</p>
<p>Email: {{customer.contact.email}}</p>
<p>Address: {{shipping.address.city}}, {{shipping.address.country}}</p>
</div>
String Concatenation
Combine multiple fields and literals using +:
<div dbind_repeat="users">
<!-- Combine first and last name -->
<h3>{{firstName + ' ' + lastName}}</h3>
<!-- Build a full address -->
<p>{{address.street + ', ' + address.city + ' ' + address.zip}}</p>
<!-- Mix fields with static text -->
<p>{{'Welcome, ' + displayName + '!'}}</p>
</div>
Rules for Concatenation
- Use
+to join parts - String literals must be in single or double quotes
- Field names are unquoted
- Spaces around
+are optional
<!-- All valid -->
<span>{{first + ' ' + last}}</span>
<span>{{first+' '+last}}</span>
<span>{{"Hello, " + name}}</span>
<span>{{'Hello, ' + name}}</span>
Inline Pipes (Filters)
Apply formatting filters directly in templates:
<div dbind_repeat="products">
<h3>{{name|uppercase}}</h3>
<p>{{price|currency:USD}}</p>
<p>{{description|truncate:100}}</p>
<time>{{createdAt|date:relative}}</time>
</div>
Pipe Syntax
{{fieldName|filterName}}
{{fieldName|filterName:parameter}}
Available Filters
Text Filters
| Filter | Description | Example |
|---|---|---|
uppercase | Convert to uppercase | {{name|uppercase}} |
lowercase | Convert to lowercase | {{email|lowercase}} |
capitalize | Capitalize first letter | {{title|capitalize}} |
titlecase | Capitalize each word | {{name|titlecase}} |
trim | Remove whitespace | {{input|trim}} |
truncate:N | Limit to N characters | {{desc|truncate:50}} |
slug | URL-friendly string | {{title|slug}} |
nl2br | Newlines to <br> | {{bio|nl2br}} |
striphtml | Remove HTML tags | {{content|striphtml}} |
Number Filters
| Filter | Description | Example |
|---|---|---|
number | Format with locale | {{count|number}} |
currency:CODE | Format as currency | {{price|currency:USD}} |
percent | Format as percentage | {{rate|percent}} |
Date Filters
| Filter | Description | Example |
|---|---|---|
date | Format date | {{createdAt|date}} |
date:short | Short date format | {{date|date:short}} |
date:long | Long date format | {{date|date:long}} |
time | Format time | {{timestamp|time}} |
datetime | Date and time | {{updated|datetime}} |
relative | Relative time | {{posted|date:relative}} |
Other Filters
| Filter | Description | Example |
|---|---|---|
boolean | true/false string | {{active|boolean}} |
yesno | Yes/No string | {{subscribed|yesno}} |
default:value | Fallback value | {{nickname|default:Anonymous}} |
json | JSON stringify | {{data|json}} |
urlencode | URL encode | {{query|urlencode}} |
Chaining Filters
Apply multiple filters in sequence:
<!-- Trim, then truncate, then capitalize -->
<p>{{description|trim|truncate:100|capitalize}}</p>
<!-- Lowercase then URL encode -->
<a href="/search?q={{query|lowercase|urlencode}}">Search</a>
Special Variables
Loop Index Variables
Within dbind_repeat loops, special variables are available:
| Variable | Description |
|---|---|
{{_index}} | Zero-based index (0, 1, 2...) |
{{_number}} | One-based number (1, 2, 3...) |
<ol dbind_repeat="items">
<li>
<span class="number">{{_number}}.</span>
<span>{{name}}</span>
</li>
</ol>
Using Index for Styling
<div dbind_repeat="products">
<div class="product" style="animation-delay: calc({{_index}} * 0.1s)">
<span class="rank">#{{_number}}</span>
<h3>{{name}}</h3>
</div>
</div>
Combining Features
Concatenation + Pipes
<div dbind_repeat="users">
<!-- Full name, uppercase -->
<h3>{{firstName + ' ' + lastName|uppercase}}</h3>
<!-- Note: Pipe applies to entire expression -->
</div>
Complex Templates
<div dbind_repeat="orders">
<div class="order-card">
<header>
<span class="order-number">Order #{{_number}}</span>
<time>{{createdAt|date:relative}}</time>
</header>
<div class="customer">
<h4>{{customer.firstName + ' ' + customer.lastName}}</h4>
<p>{{customer.email|lowercase}}</p>
</div>
<div class="shipping">
<p>{{shipping.address.street}}</p>
<p>{{shipping.address.city + ', ' + shipping.address.state + ' ' + shipping.address.zip}}</p>
<p>{{shipping.address.country|uppercase}}</p>
</div>
<div class="total">
<span>Total: {{total|currency:USD}}</span>
</div>
<footer>
<span class="status {{status|lowercase}}">{{status|capitalize}}</span>
</footer>
</div>
</div>
Template in Attributes
Use templates in data attribute values:
<div dbind_repeat="products">
<!-- Dynamic classes -->
<div class="product {{category|lowercase}}">
<img
dbind_src="image"
dbind_alt="name"
loading="lazy"
>
<h3 dbind_data="name"></h3>
<!-- Dynamic href with template -->
<a href="/products/{{slug}}">View Details</a>
</div>
</div>
Default Values
Provide fallback values for missing data:
<div dbind_repeat="users">
<img src="{{avatar|default:/images/default-avatar.png}}">
<h3>{{displayName|default:Anonymous User}}</h3>
<p>{{bio|default:No bio provided}}</p>
</div>
Escaping
Templates are automatically HTML-escaped to prevent XSS:
<!-- Safe: HTML entities are escaped -->
<p>{{userInput}}</p>
<!-- If userInput is "<script>alert('xss')</script>" -->
<!-- Output: <script>alert('xss')</script> -->
For trusted HTML content, use dbind_html:
<!-- Only use with trusted content! -->
<div dbind_html="richContent"></div>
Complete Example
<section class="team">
<h2>Our Team</h2>
<div class="team-grid" dbind_repeat="team">
<article class="team-member" dbind_transition="fade">
<div class="member-rank">#{{_number}}</div>
<img
src="{{avatar|default:/images/placeholder.jpg}}"
alt="{{firstName + ' ' + lastName}}"
loading="lazy"
>
<div class="member-info">
<h3>{{firstName + ' ' + lastName}}</h3>
<p class="role">{{role|titlecase}}</p>
<p class="department">{{department|uppercase}}</p>
<p class="bio">{{bio|truncate:120|default:No bio available}}</p>
<div class="meta">
<span>Joined {{joinDate|date:relative}}</span>
</div>
<div class="social">
<a href="mailto:{{email|lowercase}}">Email</a>
<a href="{{linkedin|default:#}}">LinkedIn</a>
<a href="{{twitter|default:#}}">Twitter</a>
</div>
</div>
</article>
</div>
</section>
<style>
.team-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.team-member {
position: relative;
padding: 20px;
border-radius: 12px;
background: #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.member-rank {
position: absolute;
top: 12px;
right: 12px;
font-weight: bold;
color: #666;
}
</style>
Next Steps
- TypeScript - Type definitions
- JavaScript API - API reference
- Lists - List rendering with dbind_repeat