2. Statements¶
Capek supports a number of standard statements:
if
andswitch
statements to generate text based on conditions,for
loops,choice
to support alternative wordings,for_choice
to support a sequence of alternatives,set
andcapture
to set variables to a certain value,macro
to define reusable templates.
2.1. Common properties¶
Statements are of two types:
a simple statement:
{% ... %}
; for example,{% set a = expression %}
a block:
{% block %}
and{% end_block %}
; for example,{% for i in list %} ... {% end_for %}
For all statements, it is possible to control the surrounding whitespace:
trim leading whitespace:
{%- tag %}
trim trailing whitespace:
{% tag -%}
trim leading and trailing whitespace:
{%- tag -%}
2.2. Conditions¶
For cases where the message content depends on data we use classic conditions directly in text:
{% if <condition> %} text {% endif %}
{% if <condition> %} text {% else %} text2 {% endif %}
{% if <condition> %} text {% elif <condition2> %} text2 {% else %} text3 {% endif %}
{% switch expression %}
{% case 10 %}text1
{% case 20 %}text2
{% default %}text3
{% endswitch %}
2.3. Loops¶
To iterate over items in a sequence or a dictionary, we use a for loop.
A loop can iterate either over a list or a map.
For example, this template
{% for i in [1,2,3] %}
i={{i}}: i²={{i*i}}
{% endfor %}
produces:
i=1: i²=1
i=2: i²=4
i=3: i²=9
while this template
{% for k,v in {1: "a", 2: "b", 3: "c"} %}
{{k}} -> {{v}}
{% endfor %}
produces:
1 -> a
2 -> b
3 -> c
When combined with the unitNum
filter:
{% for q,u in {5: "box", 1: "bottle", 30: "cup"} %}
{{q|unitNum(u)}}
{% endfor %}
we can get the following for English:
five boxes
one bottle
30 cups
Inside loops, there is a special variable loop
with information about the iteration.
loop.length
- size of the iterated collection
loop.index
- the current iteration of the loop. (1-indexed)
loop.index0
- the current iteration of the loop. (0-indexed)
loop.revindex
- the number of iterations from the end of the loop (1-indexed)
loop.revindex0
- the number of iterations from the end of the loop (0-indexed)
loop.first
– true if the first iteration
loop.last
– true if the last iteration
2.4. Alternatives¶
A random choice between multiple alternatives is supported with the choose
tag.
For example, this template
{{% choose %}}
{{% case %}}text1
{{% case %}}text2
{{% case %}}text3
{{% endchoose %}}
randomly outputs either text1, text2, or text3. All choices are equally probable. To influence the relative probability, we can use the ``weight` parameter:
{{% choose %}}
{{% case weight=40 %}}text1
{{% case weight=20 %}}text2
{{% case %}}text3
{{% endchoose %}}
In this case, text1 will be twice as likely to be selected as text2,
which in turn will be twice as likely as text3 (weight=10
is the default).
We can also add conditions blocking individual choices. So, for example, the following template
{{% choose %}}
{{% case condition=(i>20) %}}text1
{{% case %}}text2
{{% endchoose %}}
outputs text1 only if the variable i
is greater than 20.
2.5. Looped alternatives¶
The for_choices
tag combines the functionality of a for
loop with a random choice of alternatives, similar to the choose
tag:
{% for_choices i in [1,2,3,4,5] %}
{% case %} The {{i | ord_numeral_in_words }} option is great.
{% case %} Option {{i}} is a good option .
{% case %} Let's not forget the option {{i|numeral}}.
{% endfor_choices %}
can generate for example:
Option 1 is a good option.
The second option is great.
Option 3 is a good option.
Let's not forget the option 4.
The fifth option is great.
Inside for_choices
, it is possible to use the loop
variable with information about the iteration
in the same way as within a for
loop.
The probability of generating a particular case can be influenced by the weight
parameter:
{{% for_choices i in [1,2,3,4,5] %}}
{{% case weight=40 %}}text1
{{% case weight=20 %}}text2
{{% case %}}text3
{{% endfor_choices %}}
In this case, text1 will be twice as probable as text2,
which in turn will be twice as probable as text3 (weight=10
is the default).
We can also add conditions blocking individual choices. So, for example, the following template
{{% for_choices i in [1,2,3] %}}
{{% case condition=(loop.first) %}}text1
{{% case %}}text2
{{% case %}}text3
{{% case condition=(loop.last) %}}text4
{{% endfor_choices %}}
can produce text1 only in the first iteration, and text4 only in the last iteration, while text2 and text3 can be output in any iterations. Therefore, the result can be for example:
text1
text2
text4
or:
text2
text2
text2
or:
text1
text3
text2
2.6. Variables¶
A variable can be assigned a value by the set
or capture
statements.
The set
statement is used to assign the result of an expression.
For example, the following template
{% set v = "abc" | upper %}
{{ v }}{{ v }}
produces:
ABCABC
The capture
statement is used to capture the contents of the enclosed block into a variable.
Therefore the following template
{% capture v %}some content{% endcapture %}
{{ v }} and {{ v }}
produces:
some content and some content
2.7. Macros¶
In cases when a certain template is used repeatedly, we can pre-define it as macro:
{% macro cmpAdverb(diff) %}
{% if diff > 0 %} less {% else %} more {% endif %}
{% endmacro %}
and then call the macro when necessary (it does not have to be in the beginning of the document, but it needs to be defined before it is used):
Year-to-year, gas costs {{region.price.diesel.y1Diff|abs}} cents {{cmpAdverb(region.price.diesel.y1Diff)}}.
→
Year-to-year, gas costs 30 cents less.
Year-to-year, gas costs 30 cents more.