Skip to content

Helpers reference

Squiffy uses Handlebars as its text processing engine, providing a powerful set of helpers for dynamic content. This page is a quick reference for all available helpers.

Squiffy processes all text through Handlebars, which means you can use:

  • Double curly braces {{}} to output values and call helpers
  • Block helpers with {{#helper}}...{{/helper}} syntax
  • Comments with {{! comment text }}
  • Markdown formatting (converted to HTML automatically)

Understanding parentheses vs double brackets

Section titled “Understanding parentheses vs double brackets”

When working with helpers, you’ll encounter two different bracket types:

Double brackets {{}} - Output values or call helpers:

{{score}} - Display an attribute
{{set "score" 100}} - Call a helper
{{#if has_key}}...{{/if}} - Block helper

Parentheses () - Subexpressions (helper arguments):

When you need to pass the result of one helper as an argument to another helper, use parentheses:

{{#if (and has_key door_locked)}}Can unlock{{/if}}
{{random (array "red" "green" "blue")}}
{{#if (eq status "complete")}}Done{{/if}}

In these examples:

  • (and has_key door_locked) - The and helper returns true/false, which becomes the condition for if
  • (array "red" "green" "blue") - The array helper creates an array, which is passed to random
  • (eq status "complete") - The eq helper returns true/false for the if condition

Why not {{#if {{and ...}}}}?

You cannot nest {{}} inside {{}} - that’s invalid Handlebars syntax. Use parentheses for subexpressions:

❌ Wrong: {{#if {{and has_key door_locked}}}}...{{/if}}
✅ Right: {{#if (and has_key door_locked)}}...{{/if}}
❌ Wrong: {{random {{array "a" "b" "c"}}}}
✅ Right: {{random (array "a" "b" "c")}}

Nesting subexpressions:

You can nest parentheses to combine multiple helpers:

{{#if (and (gt score 100) (not game_over))}}
You have a high score and the game is still running!
{{/if}}

Here, (gt score 100) and (not game_over) are evaluated first, then their results are passed to and, and finally the result of and is passed to if.

See Attributes for detailed documentation and examples.

Helper Description Example
{{attribute}} Display attribute value (single-word names, always gets latest value) {{score}}
{{get "name"}} Get attribute value (for multi-word names or dynamic attribute names from expressions) {{get "player name"}}
Helper Parameters Description Example
{{set}} "attribute" value Set attribute to a value {{set "score" 100}}
{{unset}} "attribute" Set attribute to false {{unset "has_key"}}
{{inc}} "attribute" [amount] Increment by 1 or specified amount {{inc "score"}} or {{inc "score" 10}}
{{dec}} "attribute" [amount] Decrement by 1 or specified amount {{dec "health"}} or {{dec "health" 5}}

See Attributes for examples.

Helper Description Example
{{eq a b}} Returns true if a equals b {{#if (eq status "complete")}}Done{{/if}}
{{ne a b}} Returns true if a not equals b {{#if (ne health 0)}}Still alive{{/if}}
{{gt a b}} Returns true if a > b {{#if (gt score 100)}}High score!{{/if}}
{{gte a b}} Returns true if a >= b {{#if (gte level 5)}}Advanced{{/if}}
{{lt a b}} Returns true if a < b {{#if (lt health 20)}}Low health{{/if}}
{{lte a b}} Returns true if a <= b {{#if (lte age 18)}}Minor{{/if}}

See Attributes for examples.

Helper Description Example
{{and ...}} Returns true if all arguments are truthy {{#if (and has_key door_locked)}}Can unlock{{/if}}
{{or ...}} Returns true if any argument is truthy {{#if (or is_admin is_moderator)}}Has powers{{/if}}
{{not value}} Negates a boolean value {{#if (not game_over)}}Continue{{/if}}

See Attributes for examples.

Helper Parameters Description Example
{{seen}} "name" Check if section/passage has been visited {{#if (seen "intro")}}Welcome back{{/if}}
{{at}} "name" or (array ...) Check if currently at a specific section {{#if (at "ending")}}Game over{{/if}}

See Attributes for examples.

Helper Parameters Description
{{section}} "name" [text="..."] [set="..."] Create a section link with optional custom text and attribute changes
{{passage}} "name" [text="..."] [set="..."] Create a passage link with optional custom text and attribute changes

Example:

{{section "next_room" text="Enter" set="visited=true, count+=1"}}
Helper Parameters Description Example
{{embed}} "name" Embed text from another section or passage {{embed "description"}}
{{array}} item1 item2 ... Create an array for use with other helpers {{array "red" "green" "blue"}}

See Attributes for embed examples.

These helpers let you manage arrays stored in attributes - useful for tracking items, available options, or game state.

Helper Parameters Description Example
{{array}} item1 item2 ... Create an array {{set "items" (array "a" "b" "c")}}
{{append}} "attribute" value Append value to array stored in attribute {{append "inventory" "sword"}}
{{prepend}} "attribute" value Prepend value to array stored in attribute {{prepend "queue" "urgent"}}
{{pop}} "attribute" Remove and return first element from array {{set "next" (pop "queue")}}
{{remove}} "attribute" value Remove first matching value from array {{remove "inventory" "key"}}
Helper Parameters Description Example
{{contains}} "attribute" value or (array ...) value Check if array contains value {{#if (contains "inventory" "key")}}...{{/if}}
{{length}} "attribute" or (array ...) Get number of elements in array {{length "inventory"}}

Track available game rounds:

{{!-- Initialize available rounds --}}
{{set "rounds" (array "Quiz" "Challenge" "Bonus")}}
{{!-- Pick a random round --}}
{{set "current" (random rounds)}}
You're playing: {{current}}
{{!-- Remove it so it can't be picked again --}}
{{remove "rounds" current}}
{{!-- Check if more rounds remain --}}
{{#if (gt (length "rounds") 0)}}
[[Play next round]]
{{else}}
[[Final round]]
{{/if}}

Manage an inventory:

{{set "inventory" (array)}}
[pick up sword]:
{{append "inventory" "sword"}}
You picked up the sword.
[use key]:
{{#if (contains "inventory" "key")}}
{{remove "inventory" "key"}}
You used the key.
{{else}}
You don't have a key.
{{/if}}

Process a queue:

{{set "tasks" (array "Task A" "Task B" "Task C")}}
[next task]:
{{#if (gt (length "tasks") 0)}}
Now doing: {{pop "tasks"}}
{{else}}
All tasks complete!
{{/if}}

See Dynamic text for detailed documentation and examples.

Helper Parameters Description
{{random}} (array ...) [set="attribute"] Select a random item from an array, optionally storing the result

Example:

The weather is {{random (array "sunny" "cloudy" "rainy") set="weather"}}.
Helper Parameters Description
{{#animate}}...{{/animate}} "effect" [trigger="link"] [style="..."] [loop=true] Animate text with visual effects

Available effects:

  • typewriter - Text appears character by character
  • toast - Text slides in from bottom
  • fadeIn - Text fades in
  • continue - Clickable link that pauses animation queue

Example:

{{#animate "typewriter"}}This text appears gradually.{{/animate}}
Helper Parameters Description
{{#label}}...{{/label}} "name" Create a labeled span that can be replaced later
{{replace}} "label" [text] Replace the content of a labeled span

Example:

I bought {{#label "item"}}milk{{/label}}.
[change]:
{{replace "item"}}bread{{/replace}}
Helper Parameters Description
{{rotate}} (array ...) [set="attribute"] [show="next"] Create a cycling link that rotates through options infinitely
{{sequence}} (array ...) [set="attribute"] [show="next"] Create a sequence link that disables after the last option

Example:

Size: {{rotate (array "small" "medium" "large") set="size"}}
Helper Parameters Description
{{live}} "attribute" [section="name"] [passage="name"] Display attribute value that updates automatically when the attribute changes

Example:

Score: {{live "score"}}

The section and passage parameters let you display processed content from another section/passage that updates when the attribute changes:

{{live "category" section="categoryDescription"}}

In addition to Squiffy’s custom helpers, you have access to standard Handlebars block helpers:

Helper Description Example
{{#if}}...{{/if}} Conditional content {{#if has_key}}You have a key{{/if}}
{{#if}}...{{else}}...{{/if}} Conditional with fallback {{#if alive}}Living{{else}}Dead{{/if}}
{{#if}}...{{else if}}...{{/if}} Multiple conditions {{#if (gt score 100)}}High{{else if (gt score 50)}}Medium{{else}}Low{{/if}}
{{#unless}}...{{/unless}} Inverted conditional {{#unless game_over}}Keep playing{{/unless}}
{{#each}}...{{/each}} Iterate over arrays (advanced usage) Not commonly used in Squiffy

Squiffy has two ways to modify attributes:

Execute when a section or passage loads, before any rendering:

@set score = 100
@inc counter
@dec health
@unset flag
  • Always execute, regardless of any {{#if}} conditions in the text
  • Run once when the section/passage loads
  • Cannot be used inside conditionals

Execute during rendering, at the point where they appear in the text:

{{set "score" 100}}
{{inc "counter"}}
{{dec "health"}}
{{unset "flag"}}
  • Respect {{#if}} conditions - only execute if the condition is true
  • Run at render time, when that part of the text is processed
  • Can be used inside conditionals and helpers

When to use each:

  • Use directives for unconditional changes when a section/passage loads
  • Use helpers for conditional changes that depend on {{#if}} or other conditions

Advanced users can define custom Handlebars helpers in the @ui section using JavaScript. See the examples directory for examples of custom animations and helpers.