Templating (field mapping and conversion)¶
Cloudpipes uses jinja2 templating language for pipe and pipe filter fields. This allows to do complex transformation on data when passing information between channels. The simplest way to use a template template is to just drag an drop a field from the exchange picker.
For example dragging the name
field:
results in the following template in the Name field of the Pipe:
Tou can either drag and drop fields, or just type the jinja2 syntax yourself.
You can add text to the template like:
{{a.name}} Some Text After the name
Or even combine two fields into one like this:
{{a.name}}
{{a.description}}
Assuming the a.name
is “Hello World!” and a.description
is “Hi there!” the last template will result in:
Hello World!
Hi there!
You can read more on the general jinja2 syntax in the official documentation here. The sections below describe some features which are useful for Cloudpipes pipelines, and some of the Cloudpipes-specific jinja objects and filters.
Filters¶
Filters are used to transform the output.
You can use pipe character |
in the curly braces after the value to apply a filter. For example you can use the
built-in jija2 filter upper
to make a string uppercase:
{{a.name}}
{{a.name|upper}}
This results in:
Hello World!
HELLO WORLD!
Cloudpipes support all the built-in jinja2 filters, for which you can read in the official documentation. The following sections give of both Cloudpipes-specific filters and built-in filters, useful for building your pipelines.
Numbers - calculation and conversion¶
You can do simple arithmetic in templates like:
Incremented by 1 is: {{a.count + 1}}
Discounted value is: {{a.sum - (a.sum * a.discount_percents / 100)}}
Some channels return numbers as text fields, which will result in an error if you try to use them for calculations. For
these you can use the int
and float
filters, which convert text to and integer or floating-point number:
text to integer plus one is: {{a.text_integer|int + 1}}
text to float times 1.35 is: {{a.text_float|float * 1/35}}
Date and Time arithmetic¶
HTML fields and extracting text from HTML¶
Markdown fields¶
Some channels expect HTML in some of their fields. If you see the M
symbol this means that we have added markdown
support to this field, and any markdown will be automatically converted to HTML:
You can read more about markdown syntax here
Remove HTML tags¶
Some channels return fields which contain HTML tags. If you want to transfer these fields to a channel which does not
support HTML, you may want to extract just the text. There are two filter text
, which just removes all html tags
and formatting, and html2text
, which converts the text to markdown, which can be use in Markdown fields. Since
markdown is also relatively human-readable you may want to use html2text
anyway to keep some of the formatting.
As a rule of thumb use text
for single-line fields and html2text
for html fields with more than one line.
Body no formatting:
{{a.body|text}}
Markdown (formatted) body:
{{a.body|html2text}}
Escape HTML¶
Some channels expect HTML input in their fields, but some characters are invalid in HTML unless escaped. To convert
the characters &, <, >, ‘, and ” in string s to HTML-safe sequences use the escape
filter. For example imagine
a.name
is “Johnson & Son”. If you use just {{a.name}}
in an HTML field, you may receive an error about bad
encoding of the & character. In order to avoid this error you can use:
{{a.name|escape}}
Which will result in:
Johnson & Son
Appending to list field in an Update pipe¶
Some pipes have list fields such a tags, which you don’t want to replace completely in your update pipe, but
you prefer to append to the existing list. For example if you have a resource which has Tags
field and you want
to add a new tags, if you just write the new tag in the field it will replace all existing tags:
new_tag
In order to “add” the tag to the existing ones you can use the append
filter like this:
{{a.tags|append('new_tag')}}
You can also append multiple tags like:
{{a.tags|append('new_tag1', 'new_tag2')}}
Template If-Then-Else¶
Jinja supports if-then-else flow-control (click here for their documentation). You can use if-else to conditionally put one value or another:
{% if a.first_name %}
{{a.last_name}}
{% else %}
{{a.first_name}}
{% endif %}
This will put a.first_name
in the field if it set (non-empty), otherwise it will put a.last_name
Summarize Search Result to a single field¶
You can use jinja for-each loop
to summarize information of a search pipe to a single field. Here is an example from our
Daily digest from a Gmail label blueprint
(more about blueprints here). In order to summarize the information from the search you need to
remove the Pipeline for-each loop by clicking on the X
in the editor:
You can then use the for-each loop in the body of the Send an Email pipe, and combine it with markdown syntax to achieve a formatted summary of all results from the Search Pipe:
This will create an email which contains all the emails found from the Gmail pipe. The template code for the Body field is:
# {{a|count}} messages received for the last day #
{% for m in a %}
## {{m.subject}}
### from: {{m.from}}
### to: {{m.to}}
{{m.body}}
***
{% endfor %}
Notice that in this case a
is the full export of the search pipe, which means that it is a list. We use the
count
filter to find out how many elements there are in the list
{{a|count}} messages received for the last day
.
In the iteration over message we create a temporary variable m
: {% for m in a %}
, so in any further references
to the a single message we use m
instead of a
, like {{m.body}}
.
Clear a field in an Update pipe¶
Cloudpipes ignores fields with empty values in pipe’s mapping, i.e. it does not send them to the remote service, to avoid clearing a remote field accidentally. This however is a problem when you want to explicitly clear this field in an Update pipe. For example the following pipe won’t do anything to change the Trello card’s description:
Instead to clear the description you need to specify the special template value {{CLEAR}}
like this:
You can combine the clear value with conditions:
{% if a.priority != 'no priority' %}{{a.priority}}{% else %}{{CLEAR}}{% endif %}
In this case one channel has explicit value of “no priority” when nothing is selected, and the other expects empty string for priority when nothing is selected.