Pebble Syntax
CodeBaker's template language is Pebble, which looks like Twig and Jinja. This page lists the parts you will use most, and then what CodeBaker adds on top. For everything else, see the Pebble documentation.
Every example here was run through CodeBaker. The values are: name = Alice, n = 3, ok = true, no = false, items = a, b, c, user = { name: x, tags: [t1, t2] } and m = { a: 1, b: 2 }.
The three kinds of markup
| Written | Meaning |
|---|---|
{{ ... }} | Print a value |
{% ... %} | Do something: a condition, a loop, a variable |
{# ... #} | A comment. It is not part of the output |
If your template chose another syntax, the delimiters are different (for example [[ ]], [% %] and [# #]), and everything else on this page stays the same.
Printing values
| Template | Output |
|---|---|
{{ name }} | Alice |
{{ user.name }} | x |
{{ user['name'] }} | x |
{{ items[0] }} | a |
{{ user.tags[1] }} | t2 |
[{{ missing }}] | [] (a variable that does not exist prints nothing, it is not an error) |
{{ 'a' ~ 'b' }} | ab (~ joins text) |
{{ "Sum: #{ n + 1 }" }} | Sum: 4 (#{ } inside double quotes) |
{{ 1 + 1 }}, {{ 5 - 1 }}, {{ 2 * 3 }} | 2, 4, 6 |
{{ 7 % 3 }}, {{ 10 / 4 }} | 1, 2 (whole numbers divide to a whole number) |
{{ '<b>&' }} | <b>& (nothing is HTML-escaped: the output is source code) |
Filters
A filter changes a value. Write it after a |, and chain as many as you like.
| Template | Output |
|---|---|
{{ name | upper }} | ALICE |
{{ name | lower }} | alice |
{{ 'alice' | capitalize }} | Alice |
{{ 'hello world' | title }} | Hello World |
{{ ' x ' | trim }} | x |
{{ missing | default('n/a') }} | n/a |
{{ items | join(', ') }} | a, b, c |
{{ items | length }} | 3 |
{{ items | first }}, {{ items | last }} | a, c |
{{ name | slice(0, 2) }} | Al |
{{ 'abc' | replace({'a': 'z'}) }} | zbc |
{{ 'abcdefgh' | abbreviate(5) }} | ab... |
{{ items | reverse | join('-') }} | c-b-a |
{{ ['b','a'] | sort | join(',') }} | a,b |
{{ 'a,b' | split(',') | length }} | 2 |
{{ name | upper | lower }} | alice (filters chain left to right) |
A whole block can be filtered too: {% filter upper %}shout{% endfilter %} gives SHOUT.
CodeBaker adds filters of its own: see What CodeBaker adds.
Conditions
{% if n > 2 %}big{% elseif n == 2 %}two{% else %}small{% endif %} → big
Write elseif as one word. Comparisons are ==, !=, <, >, <= and >=, and you combine them with and, or and not.
| Template | Output |
|---|---|
{% if ok and not no %}yes{% endif %} | yes |
{% if no or ok %}either{% endif %} | either |
{% if items contains 'b' %}has b{% endif %} | has b |
{% if user.name == 'x' %}is x{% endif %} | is x |
{% if missing is null %}null{% endif %} | null |
{% if user is defined %}defined{% endif %} | defined |
{% if n is even %}even{% else %}odd{% endif %} | odd |
{{ ok ? 'yes' : 'no' }} | yes (a short condition) |
Pebble has no in operator and no ??: use contains and the default filter instead.
A value typed in the dialog that is exactly true or false, or a plain number, is converted before it reaches the template, so {% if x %} and {% if x > 10 %} work as you expect. See vars.
Loops
{% for i in items %}{{ i }}{% endfor %} → abc
| Template | Output |
|---|---|
{% for i in items %}{{ loop.index }}:{{ i }} {% endfor %} | 0:a 1:b 2:c |
{% for i in items %}{{ loop.index + 1 }}{% endfor %} | 123 |
{% for i in items %}{% if loop.first %}[{% endif %}{{ i }}{% if loop.last %}]{% endif %}{% endfor %} | [abc] |
{% for i in items %}{{ loop.length }}/{{ loop.revindex }}{% if not loop.last %},{% endif %}{% endfor %} | 3/2,3/1,3/0 |
{% for i in nothing %}x{% else %}no items{% endfor %} | no items (the else part runs for an empty list) |
{% for i in 1..3 %}{{ i }}{% endfor %} | 123 (a range) |
{% for entry in m %}{{ entry.key }}={{ entry.value }};{% endfor %} | a=1;b=2; (an object gives key and value) |
loop.index starts at 0. Use loop.index + 1 when you need to count from 1. loop.first, loop.last, loop.length and loop.revindex are also there.
Do not name a variable none, null, true or false: Pebble reads them as values.
Your own variables and macros
{% set total = n + 1 %}{{ total }} → 4
{% set label = 'x' ~ n %}{{ label }} → x3
A macro is a small reusable piece of the template:
{% macro greet(who, punct='!') %}Hi {{ who }}{{ punct }}{% endmacro %}{{ greet('Bob') }} {{ greet('Bob', '?') }}
→ Hi Bob! Hi Bob?
Comments and whitespace
{# ... #} is removed from the output.
Whitespace control: the - marker
Pebble can remove the whitespace around a tag when you ask it to. Put a - inside the tag, next to its delimiter:
| Written | Removes |
|---|---|
{%- ... %}, {{- ... }} | the spaces and line breaks before the tag |
{% ... -%}, {{ ... -}} | the spaces and line breaks after the tag |
a {{- name -}} b → aAliceb
line1
{%- if ok %}X{% endif %} → line1X
CodeBaker already joins a line that holds only tags to the next line, so you rarely need this. It helps when a tag is in the middle of a line and the spaces around it must go. It works in CodeBaker: directives too (// CodeBaker: {%- if ok -%}).
What is not available
{% include %}, {% extends %}, {% import %}, {% embed %} and {% from %} do not work, because a template file is a single text. Using one stops the generation with an explanation. See Known Limitations.
What CodeBaker adds
| Addition | What it does | Read more |
|---|---|---|
| More filters | pluralize, singularize, tableize, classify, camelize, underscore, dasherize, slug and many more, for names | Inflection & Case Filters |
json filter | Prints a list or object as JSON. {{ items | json }} is indented, and json(pretty=false) gives one compact line, ["a","b","c"] | Lists and objects |
Safe reverse, sort, rsort | They work on a copy, so the variable is not reordered for the rest of the template and for the files after it | |
| Variables you did not declare | System properties such as DATE, USER and PROJECT_NAME, and every key of the json section | System Properties, json |
| Tags in comments | // CodeBaker: {% if x %} keeps the template file valid for your IDE; the comment is replaced by the tag. // CodeBaker: separator writes a comma between the items of a loop | How CodeBaker comments work |
| Other ways to write a value | A placeholder style of your own, such as ___name___, which becomes {{ name }} | placeholders |
| Other delimiters | Choose [[ ]] and [% %] (or your own) for the whole template, so {{ }} and {% %} stay plain text | syntax |
| Text that stays as written | {% raw %} is another name for {% verbatim %}, and {{ 'text' }} prints one string. Nothing inside is read or changed | Preserving code with raw blocks |
| Replace rules | //CodeBaker: replace and regex change a value from one line downwards, and the replace entries of the config change text everywhere | Inline & Block Replace |
| Slot markers | {% slot name %} and {% fragment id %} mark a place for the insert type. They are CodeBaker's own tags, not Pebble's, and are kept as written | insert |
| Tidy line breaks | A line that holds only tags leaves no empty line, and a value at the end of a line keeps its line break | How One File Is Processed |
| No HTML escaping | Values are printed exactly as they are |
The order in which all of this is applied to a file is described on How One File Is Processed.