DBindly Docs
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

FilterDescriptionExample
uppercaseConvert to uppercase{{name|uppercase}}
lowercaseConvert to lowercase{{email|lowercase}}
capitalizeCapitalize first letter{{title|capitalize}}
titlecaseCapitalize each word{{name|titlecase}}
trimRemove whitespace{{input|trim}}
truncate:NLimit to N characters{{desc|truncate:50}}
slugURL-friendly string{{title|slug}}
nl2brNewlines to <br>{{bio|nl2br}}
striphtmlRemove HTML tags{{content|striphtml}}

Number Filters

FilterDescriptionExample
numberFormat with locale{{count|number}}
currency:CODEFormat as currency{{price|currency:USD}}
percentFormat as percentage{{rate|percent}}

Date Filters

FilterDescriptionExample
dateFormat date{{createdAt|date}}
date:shortShort date format{{date|date:short}}
date:longLong date format{{date|date:long}}
timeFormat time{{timestamp|time}}
datetimeDate and time{{updated|datetime}}
relativeRelative time{{posted|date:relative}}

Other Filters

FilterDescriptionExample
booleantrue/false string{{active|boolean}}
yesnoYes/No string{{subscribed|yesno}}
default:valueFallback value{{nickname|default:Anonymous}}
jsonJSON stringify{{data|json}}
urlencodeURL 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:

VariableDescription
{{_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: &lt;script&gt;alert('xss')&lt;/script&gt; -->

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