---
title: "Handlebars"
description: "Create custom blocks with HTML and Handlebars templates using the Lazy Blocks plugin."
url: "https://www.lazyblocks.com/docs/blocks-code/handlebars/"
lastUpdated: 2026-09-09
source: "blocks-code/handlebars.mdx"
---
# Handlebars

The Handlebars output method builds a block's HTML from a template with the control values written into it, and the conditionals and loops of the Handlebars syntax around them.

## Basic usage

```hbs title="Handlebars Example"
{{#if control_name}}
  <div class="message">
    {{control_name}}
  </div>
{{/if}}
```

## Available helpers

In addition to [default Handlebars helpers](https://handlebarsjs.com/guide/builtin-helpers.html), Lazy Blocks provides custom helpers for WordPress-specific functionality.

Every helper except `truncate` returns a plain string, which Handlebars escapes. Write `{{helper ...}}` for text and `{{{helper ...}}}` when the helper produces markup you want rendered.

### truncate

Truncates text to a specified length.

```hbs title="Truncate Example"
{{truncate control_name 100 "true"}}
```

| Parameter | Description                |
| --------- | -------------------------- |
| String    | Text to truncate           |
| Limit     | Character limit            |
| Dots      | Show ellipsis (true/false) |

The cut walks back to the last space before the limit, so a word is kept whole. A run of characters with no space in it is cut at the limit itself. A string already shorter than the limit comes back untouched. This is the one helper whose output is left unescaped, and only when it truncates, so a cut string is printed as markup while an untouched one is escaped.

### compare

Compares values for conditional rendering.

```hbs title="Compare Example"
{{#compare price ">" 100}}
  <span class="premium">Premium Item</span>
{{/compare}}
```

| Parameter    | Description                                                            |
| ------------ | ---------------------------------------------------------------------- |
| First Value  | Left side value                                                        |
| Operator     | `==`, `===`, `!=`, `!==`, `<`, `>`, `<=`, `>=`, `&&`, `\|\|`, `typeof` |
| Second Value | Right side value                                                       |

`typeof` compares PHP's type name of the first value with the second, as in `{{#compare control_name "typeof" "array"}}`. Dropping the operator is allowed, and `{{#compare a b}}` compares with `===`. An operator outside the list makes the comparison false, so the `{{else}}` branch runs.

### math

Performs mathematical operations.

```hbs title="Math Example"
<div class="price">
  ${{math price "*" quantity}}
</div>
```

| Parameter    | Description             |
| ------------ | ----------------------- |
| First Value  | Left side value         |
| Operator     | `+`, `-`, `*`, `/`, `%` |
| Second Value | Right side value        |

Any other operator prints nothing, so a typo in the operator leaves an empty spot rather than an error.

### date_i18n

Formats dates using WordPress localization.

```hbs title="Date Example"
<time datetime="{{control_date}}">
  {{date_i18n "F j, Y" control_date}}
</time>
```

| Parameter | Description                      |
| --------- | -------------------------------- |
| Format    | Date format (e.g., `F j, Y H:i`) |
| Date      | Date string                      |

### do_shortcode

Processes WordPress shortcodes.

```hbs title="Shortcode Example"
{{{do_shortcode "my_shortcode" this}}}
```

| Parameter  | Description                         |
| ---------- | ----------------------------------- |
| Name       | Shortcode name                      |
| Attributes | Use `this` for all block attributes |

A `content` key in the passed object becomes the shortcode's inner content. The block's own code fields, `data` and `hash` are dropped, and an array value is encoded as JSON before it reaches the shortcode attribute.

### wp_get_attachment_image

Outputs WordPress image with proper srcset.

```hbs title="Image Example"
{{{wp_get_attachment_image image_control "large"}}}
```

| Parameter | Description                          |
| --------- | ------------------------------------ |
| Image     | Image control value                  |
| Size      | Image size name (default: thumbnail) |

The first argument takes an Image control value or a bare attachment ID. An image added by URL has no `id`, and the helper falls back to a plain `<img>` tag built from its `url`.

### var_dump

Dumps a value while you are building the block.

```hbs title="Debug Example"
{{{var_dump control_name}}}
```

| Parameter | Description                 |
| --------- | --------------------------- |
| Value     | Any value from the template |

The helper returns PHP's `var_dump()` output as a plain string, so `{{var_dump control_name}}` shows it escaped and `{{{var_dump control_name}}}` renders it as markup. Nothing gates it, not `WP_DEBUG` and not a capability, so a block published with it dumps the value to logged-out visitors on the front end. Take it out before the block goes live.

## Adding custom helpers

Create your own Handlebars helpers:

```php title="PHP"
function my_custom_handlebars_helper($handlebars) {
    $handlebars->registerHelper('format_price', function($price) {
        return '$' . number_format($price, 2);
    });
}
add_action('lzb/handlebars/object', 'my_custom_handlebars_helper');
```

Usage:

```hbs
<div class="price">
  {{format_price product_price}}
</div>
```

See [lzb/handlebars/object](https://www.lazyblocks.com/docs/php-actions/lzb-handlebars-object/) for the object the action passes and for when it fires.

  Use Handlebars when you need simple templates with basic logic. For complex
  dynamic content, consider using PHP output instead.

## Documentation Index
> Fetch the complete documentation index at: https://www.lazyblocks.com/llms.txt
> Fetch every page in a single file at: https://www.lazyblocks.com/llms-full.txt
