Skip to main content

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​

WrittenMeaning
{{ ... }}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​

TemplateOutput
{{ 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.

TemplateOutput
{{ 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.

TemplateOutput
{% 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
TemplateOutput
{% 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:

WrittenRemoves
{%- ... %}, {{- ... }}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​

AdditionWhat it doesRead more
More filterspluralize, singularize, tableize, classify, camelize, underscore, dasherize, slug and many more, for namesInflection & Case Filters
json filterPrints 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, rsortThey 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 declareSystem properties such as DATE, USER and PROJECT_NAME, and every key of the json sectionSystem 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 loopHow CodeBaker comments work
Other ways to write a valueA placeholder style of your own, such as ___name___, which becomes {{ name }}placeholders
Other delimitersChoose [[ ]] and [% %] (or your own) for the whole template, so {{ }} and {% %} stay plain textsyntax
Text that stays as written{% raw %} is another name for {% verbatim %}, and {{ 'text' }} prints one string. Nothing inside is read or changedPreserving 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 everywhereInline & 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 writteninsert
Tidy line breaksA line that holds only tags leaves no empty line, and a value at the end of a line keeps its line breakHow One File Is Processed
No HTML escapingValues 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.