← Back to Home

Templates & Helpers

Write powerful Handlebars templates with 47+ built-in helpers

Overview

Clay uses Handlebars templates to generate code. Templates can access your model data and use a rich set of helpers for formatting, logic, and iteration.

Basic Template Syntax

Templates use double curly braces to output values:

// {{name}} Model
class {{pascalCase name}} {
  constructor() {
    this.id = null;
  }
}

Context Variables

Clay automatically adds special context variables to help you navigate your model:

clay_model

Access the complete root model from anywhere in your template:

<!-- Access model name from anywhere -->
<h1>{{clay_model.name}}</h1>

<!-- Count total types -->
<p>Total types: {{clay_model.model.types.length}}</p>

clay_parent

Reference the parent element in the JSON structure:

<p>Parent name: {{clay_parent.name}}</p>
<p>Parent path: {{clay_parent.json_path}}</p>

clay_key

The JSON property name of the current element:

<p>Current property: {{clay_key}}</p>

String Helpers

Clay provides extensive string manipulation helpers:

Case Conversion

Helper Example Output
camelCase {{camelCase "user name"}} userName
pascalCase {{pascalCase "user name"}} UserName
kebabCase {{kebabCase "userName"}} user-name
snakeCase {{snakeCase "userName"}} user_name
upperCase {{upperCase "hello"}} HELLO
lowerCase {{lowerCase "HELLO"}} hello
capitalize {{capitalize "hello world"}} Hello world
startCase {{startCase "hello_world"}} Hello World

Pluralization

Helper Example Output
pluralize {{pluralize "category"}} categories
singularize {{singularize "users"}} user

String Utilities

Helper Description Example
pad Pads string to length with spaces {{pad "abc" 5}} → " abc "
repeat Repeats string N times {{repeat "*" 3}} → ***
replace Replaces part of string {{replace "hi" "i" "o"}} → ho
truncate Truncates string to length {{truncate "hello world" 8}} → hello...
words Splits string into word array {{#each (words "foo bar")}}{{this}}{{/each}}
split Splits string by delimiter {{#each (split "a,b,c" ",")}}{{this}}{{/each}}

Comparison Helpers

Compare values in conditional expressions:

Helper Description Example
eq Equals (===) {{#if (eq status "active")}}Active{{/if}}
ne Not equals (!==) {{#if (ne count 0)}}Has items{{/if}}
lt Less than (<) {{#if (lt age 18)}}Minor{{/if}}
gt Greater than (>) {{#if (gt score 100)}}High{{/if}}
lte Less than or equal (<=) {{#if (lte count 10)}}Small{{/if}}
gte Greater than or equal (>=) {{#if (gte age 18)}}Adult{{/if}}

Logic Helpers

Conditionals

{{#if isActive}}
  Active user
{{else}}
  Inactive user
{{/if}}

{{#ifCond age '>=' 18}}
  Adult
{{else}}
  Minor
{{/ifCond}}

The ifCond helper supports these operators:

Logical Operators

{{#if (and isActive isPremium)}}
  Premium Active User
{{/if}}

{{#if (or isAdmin isModerator)}}
  Staff Member
{{/if}}

Switch/Case

{{#switch type}}
  {{#case 'admin'}}
    Administrator
  {{/case}}
  {{#case 'user'}}
    Regular User
  {{/case}}
  {{#default}}
    Unknown
  {{/default}}
{{/switch}}

You can match multiple values in a single case:

{{#switch role}}
  {{#case 'admin' 'moderator'}}
    Staff Member
  {{/case}}
  {{#case 'user'}}
    Regular User
  {{/case}}
{{/switch}}

Property Checking

Use propertyExists to check if a property exists in any object:

{{#if (propertyExists items "email")}}
  <th>Email</th>
{{/if}}

Iteration Helpers

Basic Each

{{#each users}}
  - {{name}} ({{email}})
{{/each}}

Each with Unique Values

Iterate over unique values or unique values by property:

{{!-- Unique values --}}
{{#eachUnique tags}}
  <span>{{this}}</span>
{{/eachUnique}}

{{!-- Unique by property --}}
{{#eachUnique items 'category'}}
  Category: {{this.category}}
{{/eachUnique}}

Each Unique JSONPath

Iterate over items selected by JSONPath (uniqueness determined by path, not value):

{{!-- Select array items (each has unique index in path) --}}
{{#eachUniqueJSONPath clay_model '$.types[*]'}}
  <h2>{{this.name}} - {{this.category}}</h2>
{{/eachUniqueJSONPath}}

Times (Repeat N times)

{{#times 3}}
  Step {{inc @index}}
{{/times}}

Group By

Group items by a property:

{{#group posts by='category'}}
  <h2>{{value}}</h2>
  {{#each items}}
    <p>{{title}}</p>
  {{/each}}
{{/group}}

Type Check Helpers

Check the type of values in your templates:

Helper Description Example
isArray Check if value is an array {{#if (isArray items)}}Is array{{/if}}
isString Check if value is a string {{#if (isString name)}}Is string{{/if}}
isNumber Check if value is a number {{#if (isNumber count)}}Is number{{/if}}
isBoolean Check if value is a boolean {{#if (isBoolean active)}}Is bool{{/if}}
isEmpty Check if value is empty {{#if (isEmpty list)}}No items{{/if}}
isNull Check if value is null {{#if (isNull value)}}Is null{{/if}}
isUndefined Check if value is undefined {{#if (isUndefined opt)}}Not set{{/if}}

Utility Helpers

JSON Output

Pretty-print objects as JSON:

<pre>{{{json this}}}</pre>

Markdown Rendering

Convert markdown to HTML:

{{{markdown description}}}

Number Operations

{{!-- Increment (useful for 1-based indexes) --}}
Step {{inc @index}}

{{!-- Parse string to integer --}}
{{parseInt "42"}}

String Checks

{{!-- Check if string contains value --}}
{{#if (includes email "@")}}Valid email format{{/if}}

{{!-- Check if string starts with value --}}
{{#if (startsWith filename "test_")}}Is test file{{/if}}

{{!-- Check if string ends with value --}}
{{#if (endsWith filename ".js")}}Is JS file{{/if}}

Split and Extract

Split strings by delimiter and extract parts:

{{!-- Using split helper --}}
{{#each (split "foo,bar,baz" ",")}}
  - {{this}}
{{/each}}

{{!-- Using splitAndUseWord to get specific part --}}
{{splitAndUseWord "user-profile-page" "-" 1}}
{{!-- Output: profile --}}

Partials

Reuse template fragments with partials. Define them in your generator:

{
  "partials": ["partials/header.hbs"],
  "steps": [...]
}

Use in templates:

{{> header}}
<div class="content">
  {{name}}
</div>

Complete Helper List

Clay includes 47+ helpers across 8 categories:

💡 Pro Tip: Use the MCP server's clay_list_helpers tool to get detailed examples of all helpers when working with AI assistants!

Best Practices