Template Variables
SwissArmyHammer uses the Liquid template engine for processing prompts. This provides powerful templating features including variables, conditionals, loops, and filters.
Basic Variable Substitution
Variables are inserted using double curly braces:
Hello {{ name }}!
Your email is {{ email }}.
For backward compatibility, variables without spaces also work:
Hello {{name}}!
Conditionals
If Statements
Use if
statements to conditionally include content:
{% if user_type == "admin" %}
Welcome, administrator!
{% elsif user_type == "moderator" %}
Welcome, moderator!
{% else %}
Welcome, user!
{% endif %}
Unless Statements
unless
is the opposite of if
:
{% unless error_count == 0 %}
Warning: {{ error_count }} errors found.
{% endunless %}
Comparison Operators
==
- equals!=
- not equals>
- greater than<
- less than>=
- greater or equal<=
- less or equalcontains
- string/array containsand
- logical ANDor
- logical OR
Example:
{% if age >= 18 and country == "US" %}
You are eligible to vote.
{% endif %}
{% if tags contains "urgent" %}
π¨ This is urgent!
{% endif %}
Case Statements
For multiple conditions, use case
:
{% case status %}
{% when "pending" %}
β³ Waiting for approval
{% when "approved" %}
β
Approved and ready
{% when "rejected" %}
β Rejected
{% else %}
β Unknown status
{% endcase %}
Loops
Basic For Loops
Iterate over arrays:
{% for item in items %}
- {{ item }}
{% endfor %}
Range Loops
Loop over a range of numbers:
{% for i in (1..5) %}
Step {{ i }} of 5
{% endfor %}
Loop Variables
Inside loops, you have access to special variables:
{% for item in items %}
{% if forloop.first %}First item: {% endif %}
{{ forloop.index }}. {{ item }}
{% if forloop.last %}(last item){% endif %}
{% endfor %}
Available loop variables:
forloop.index
- current iteration (1-based)forloop.index0
- current iteration (0-based)forloop.first
- true on first iterationforloop.last
- true on last iterationforloop.length
- total number of items
Loop Control
Use break
and continue
for flow control:
{% for item in items %}
{% if item == "skip" %}
{% continue %}
{% endif %}
{% if item == "stop" %}
{% break %}
{% endif %}
Processing: {{ item }}
{% endfor %}
Cycle
Alternate between values:
{% for row in data %}
<tr class="{% cycle 'odd', 'even' %}">
<td>{{ row }}</td>
</tr>
{% endfor %}
Filters
Filters modify variables using the pipe (|
) character:
String Filters
{{ name | upcase }} # ALICE
{{ name | downcase }} # alice
{{ name | capitalize }} # Alice
{{ text | strip }} # removes whitespace
{{ text | truncate: 20 }} # truncates to 20 chars
{{ text | truncate: 20, "..." }} # custom ellipsis
{{ text | append: "!" }} # adds to end
{{ text | prepend: "Hello " }} # adds to beginning
{{ text | remove: "bad" }} # removes all occurrences
{{ text | replace: "old", "new" }} # replaces all
{{ text | split: "," }} # splits into array
Array Filters
{{ array | first }} # first element
{{ array | last }} # last element
{{ array | join: ", " }} # joins with delimiter
{{ array | sort }} # sorts array
{{ array | reverse }} # reverses array
{{ array | size }} # number of elements
{{ array | uniq }} # removes duplicates
Math Filters
{{ number | plus: 5 }} # addition
{{ number | minus: 3 }} # subtraction
{{ number | times: 2 }} # multiplication
{{ number | divided_by: 4 }} # division
{{ number | modulo: 3 }} # remainder
{{ number | ceil }} # round up
{{ number | floor }} # round down
{{ number | round }} # round to nearest
{{ number | round: 2 }} # round to 2 decimals
{{ number | abs }} # absolute value
Default Filter
Provide fallback values:
Hello {{ name | default: "Guest" }}!
Score: {{ score | default: 0 }}
Date Filters
{{ date | date: "%Y-%m-%d" }} # 2024-01-15
{{ date | date: "%B %d, %Y" }} # January 15, 2024
{{ "now" | date: "%Y" }} # current year
Advanced Features
Comments
Comments are not rendered in output:
{% comment %}
This is a comment that won't appear in the output.
Useful for documentation or temporarily disabling code.
{% endcomment %}
Raw Blocks
Prevent Liquid processing:
{% raw %}
This {{ variable }} won't be processed.
Useful for showing Liquid syntax examples.
{% endraw %}
Assign Variables
Create new variables:
{% assign full_name = first_name | append: " " | append: last_name %}
Welcome, {{ full_name }}!
{% assign item_count = items | size %}
You have {{ item_count }} items.
Capture Blocks
Capture content into a variable:
{% capture greeting %}
{% if time_of_day == "morning" %}
Good morning
{% elsif time_of_day == "evening" %}
Good evening
{% else %}
Hello
{% endif %}
{% endcapture %}
{{ greeting }}, {{ name }}!
Environment Variables
Access environment variables through the env
object:
Current user: {{ env.USER }}
Home directory: {{ env.HOME }}
Custom setting: {{ env.MY_APP_CONFIG | default: "not set" }}
Object Access
Access nested objects and arrays:
{{ user.name }}
{{ user.address.city }}
{{ items[0] }}
{{ items[index] }}
{{ data["dynamic_key"] }}
Truthy and Falsy Values
In Liquid conditions:
- Falsy:
false
,nil
- Truthy: everything else (including
0
,""
,[]
)
{% if value %}
This shows unless value is false or nil
{% endif %}
Error Handling
When a variable is undefined:
- In backward-compatible mode:
{{ undefined }}
renders as{{ undefined }}
- With validation: An error is raised for missing required arguments
Use the default
filter to handle missing values gracefully:
{{ optional_var | default: "fallback value" }}
Migration from Basic Templates
If youβre migrating from basic {{variable}}
syntax:
- Your existing templates still work - backward compatibility is maintained
- Add spaces for clarity:
{{var}}
β{{ var }}
- Use filters for transformation:
{{ name | upcase }}
instead of post-processing - Add conditions for dynamic content: Use
{% if %}
blocks - Use loops for repetitive content: Replace manual duplication with
{% for %}
Migration Examples
Before: Basic Variable Substitution
Please review the {{language}} code in {{file}}.
Focus on {{focus_area}}.
After: Enhanced with Liquid Features
Please review the {{ language | capitalize }} code in {{ file }}.
{% if focus_area %}
Focus on {{ focus_area }}.
{% else %}
Perform a general code review.
{% endif %}
{% if language == "python" %}
Pay special attention to PEP 8 compliance.
{% elsif language == "javascript" %}
Check for ESLint rule violations.
{% endif %}
Before: Manual List Creation
Files to review:
- {{file1}}
- {{file2}}
- {{file3}}
After: Dynamic Lists with Loops
Files to review:
{% for file in files %}
- {{ file }}{% if forloop.last %} (final file){% endif %}
{% endfor %}
Total: {{ files | size }} files
Before: Fixed Templates
Status: {{status}}
After: Conditional Formatting
Status: {% case status %}
{% when "success" %}β
{{ status | upcase }}
{% when "error" %}β {{ status | upcase }}
{% when "warning" %}β οΈ {{ status | capitalize }}
{% else %}{{ status }}
{% endcase %}
Differences from Handlebars/Mustache
If youβre familiar with Handlebars or Mustache templating:
Feature | Handlebars/Mustache | Liquid |
---|---|---|
Variables | {{variable}} | {{ variable }} |
Conditionals | {{#if}}...{{/if}} | {% if %}...{% endif %} |
Loops | {{#each}}...{{/each}} | {% for %}...{% endfor %} |
Comments | {{! comment }} | {% comment %}...{% endcomment %} |
Filters | Limited | Extensive built-in filters |
Logic | Minimal | Full comparison operators |
Common Migration Patterns
-
Variable with Default
- Before: Handle missing variables in code
- After:
{{ variable | default: "fallback" }}
-
Conditional Sections
- Before: Generate different templates
- After: Single template with
{% if %}
blocks
-
Repeated Content
- Before: Manual duplication
- After:
{% for %}
loops withforloop
variables
-
String Transformation
- Before: Transform in application code
- After: Use Liquid filters directly
Backward Compatibility Notes
- Simple
{{variable}}
syntax continues to work - Undefined variables are preserved as
{{ variable }}
in output - No breaking changes to existing templates
- Gradual migration is supported - mix old and new syntax
Examples
Dynamic Code Review
{% if language == "python" %}
Please review this Python code for PEP 8 compliance.
{% elsif language == "javascript" %}
Please review this JavaScript code for ESLint rules.
{% else %}
Please review this {{ language }} code for best practices.
{% endif %}
{% if include_security %}
Also check for security vulnerabilities.
{% endif %}
Formatted List
{% for item in tasks %}
{{ forloop.index }}. {{ item.title }}
{% if item.completed %}β{% else %}β{% endif %}
Priority: {{ item.priority | default: "normal" }}
{% unless item.completed %}
Due: {{ item.due_date | date: "%B %d" }}
{% endunless %}
{% endfor %}
Conditional Debugging
{% if debug_mode %}
=== Debug Information ===
Variables: {{ arguments | json }}
Environment: {{ env.NODE_ENV | default: "development" }}
{% for key in api_keys %}
{{ key }}: {{ key | truncate: 8 }}...
{% endfor %}
{% endif %}
Best Practices
- Use meaningful variable names:
{{ user_email }}
instead of{{ ue }}
- Provide defaults:
{{ value | default: "N/A" }}
for optional values - Format output: Use filters to ensure consistent formatting
- Comment complex logic: Use
{% comment %}
blocks - Test edge cases: Empty arrays, nil values, missing variables
- Keep it readable: Break complex templates into sections
Custom Filters
SwissArmyHammer includes specialized custom filters designed for prompt engineering:
Code Filters
{{ code | format_lang: "rust" }} # Format code with language
{{ code | extract_functions }} # Extract function signatures
{{ path | basename }} # Get filename from path
{{ path | dirname }} # Get directory from path
{{ text | count_lines }} # Count number of lines
{{ code | dedent }} # Remove common indentation
Text Processing Filters
{{ text | extract_urls }} # Extract URLs from text
{{ title | slugify }} # Convert to URL-friendly slug
{{ text | word_wrap: 80 }} # Wrap text at 80 characters
{{ text | indent: 2 }} # Indent all lines by 2 spaces
{{ items | bullet_list }} # Convert array to bullet list
{{ text | highlight: "keyword" }} # Highlight specific terms
Data Transformation Filters
{{ json_string | from_json }} # Parse JSON string
{{ data | to_json }} # Convert to JSON string
{{ csv_string | from_csv }} # Parse CSV string
{{ array | to_csv }} # Convert to CSV string
{{ yaml_string | from_yaml }} # Parse YAML string
{{ data | to_yaml }} # Convert to YAML string
Utility Filters
{{ text | md5 }} # Generate MD5 hash
{{ text | sha1 }} # Generate SHA1 hash
{{ text | sha256 }} # Generate SHA256 hash
{{ number | ordinal }} # Convert to ordinal (1st, 2nd, 3rd)
{{ 100 | lorem_words }} # Generate lorem ipsum words
{{ date | format_date: "%Y-%m-%d" }} # Advanced date formatting
For complete documentation of custom filters, see the Custom Filters Reference.
Limitations
- No includes: Cannot include other template files
- No custom tags: Only standard Liquid tags are supported
- Performance: Very large loops may impact performance
Further Reading
- Official Liquid Documentation
- Liquid Playground - Test templates online
- Liquid Cheat Sheet