Jinja2C++ Compatibility
Table of contents
Current Jinja2 support
Currently, Jinja2C++ supports the limited number of Jinja2 features. By the way, Jinja2C++ is planned to be full jinja2 specification-conformant. The current support is limited to:
- expressions. You can use every style of expressions: simple, filtered, conditional, and so on.
- amost all Jinja2 filters (except of
xmlattrandtojson) - big number of testers (eq, defined, ge, gt, iterable, le, lt, mapping, ne, number, sequence, string, undefined, in, even, odd, lower, upper)
- limited number of functions (range, loop.cycle)
- ‘if’ statement (with ‘elif’ and ‘else’ branches)
- ‘for’ statement (with ‘else’ branch and ‘if’ part support)
- ‘set’ statement (both single-line and block version)
- ‘extends’/’block’ statements
- ‘include’ statement
- ‘import’/’from’ statements
- ‘macro’/’call’ statements
- ‘with’ statement
- ‘raw’ statement
- ‘do’ extension statement
- ‘filter’ extension statement
- recursive loops
- space control
Jinja2 specifiecation implementation notes:
Comparison with other implementations
| Feature | Jinja2C++ | Jinja2CppLight | pantor::inja | Python Jinja2 |
|---|---|---|---|---|
| More information | see [1] | see [2] | see [3] | |
| {{ / }} | yes | yes | yes | yes |
| {% / %} | yes | yes | yes | yes |
| {# / #} | yes | yes | yes | yes |
| Single-line statements | no | no | yes | yes |
| raw/endraw | yes | no | no | yes |
| Whitespace control | yes | no | yes | yes |
| Statements | ||||
| set | yes | no | no | yes |
| block set | yes | no | no | yes |
| if / endif | yes | yes | yes | yes |
| else | yes | no | yes | yes |
| elif | yes | no | no | yes |
| for / endfor | yes | yes | yes | yes |
| recursive for loop | yes | no | no | yes |
| conditional for loop | yes | no | no | yes |
| extends / block | yes | no | no | yes |
| import | yes | no | no | yes |
| include | yes | no | yes | yes |
| macro / endmacro | yes | no | no | yes |
| call | yes | no | no | yes |
| filter | yes | no | no | yes |
| do (extension) | yes | no | no | yes |
| with (extension) | yes | no | no | yes |
| i18n (extension) | no | no | no | yes |
| continue/break (extension) | no | no | no | yes |
| autoescape (extension) | no | no | no | yes |
| Expressions | ||||
| String literals | yes | yes | yes | yes |
| Integer numbers | yes | yes | yes | yes |
| Floating numbers | yes | yes | yes | yes |
Lists ([1, 3, 4]) | yes | no | no | yes |
Tuples ((1, "one", 3.14)) | yes | no | no | yes |
Dicts ({'dict': 'of', 'key': 'and', 'value': 'pairs'}) | yes | no | no | yes |
True / False | yes | no | no | yes |
+ operator | yes | no | no | yes |
- operator | yes | no | no | yes |
/ operator | yes | no | no | yes |
// operator | yes | no | no | yes |
% operator | yes | no | no | yes |
* operator | yes | no | no | yes |
** operator | yes | no | no | yes |
== operator | yes | yes | yes | yes |
!= operator | yes | yes | yes | yes |
> / < / >= / <= operators | yes | yes | yes | yes |
and / or / not logical operators | yes | no | yes | yes |
in operator | yes | no | yes | yes |
is operator | yes | no | no | yes |
| (filter application operator) | yes | no | no | yes |
~ (string concatenation operator) | yes | no | no | yes |
() (call operator) | yes | no | yes | yes |
. (attribute access) | yes | no | yes | yes |
[] (attribute access) | yes | no | no | yes |
[] (arrays slicing) | no | no | no | yes |
| Filters | ||||
| abs | yes | no | no | yes |
| attr | yes | no | no | yes |
| batch | yes | no | no | yes |
| capitalize | yes | no | no | yes |
| center | no | no | no | yes |
| default | yes | no | yes (as function) | yes |
| dictsort | yes | no | no | yes |
| escape | yes | no | no | yes |
| filesizeformat | no | no | no | yes |
| first | yes | no | yes (as function) | yes |
| float | yes | no | yes (as function) | yes |
| forceescape | no | no | no | yes |
| format | yes | no | no | yes |
| groupby | yes | no | no | yes |
| indent | no | no | no | yes |
| int | yes | no | yes (as function) | yes |
| join | yes | no | no | yes |
| last | yes | no | yes (as function) | yes |
| length | yes | no | yes (as function) | yes |
| list | yes | no | no | yes |
| lower | yes | no | yes (as function) | yes |
| map | yes | no | no | yes |
| max | yes | no | no | yes |
| min | yes | no | no | yes |
| pprint | yes | no | no | yes |
| random | yes | no | no | yes |
| reject | yes | no | no | yes |
| rejectattr | yes | no | no | yes |
| replace | yes | no | no | yes |
| reverse | yes | no | no | yes |
| round | yes | no | yes (as function) | yes |
| safe | no | no | no | yes |
| select | yes | no | no | yes |
| selectattr | yes | no | no | yes |
| slice | yes | no | no | yes |
| sort | yes | no | yes (as function) | yes |
| string | yes | no | yes (as function) | yes |
| striptags | no | no | no | yes |
| sum | yes | no | no | yes |
| title | yes | no | no | yes |
| tojson | no | no | no | yes |
| trim | yes | no | no | yes |
| truncate | yes | no | no | yes |
| unique | yes | no | no | yes |
| upper | yes | no | yes (as function) | yes |
| urlencode | yes | no | no | yes |
| urlize | yes | no | no | yes |
| wordcount | yes | no | no | yes |
| wordwrap | yes | no | no | yes |
| Testers | ||||
| callable | no | no | no | yes |
| defined | yes | no | yes (as function) | yes |
| devisibleby | no | no | yes (as function) | yes |
| eq | yes | no | no | yes |
| escaped | no | no | no | yes |
| even | yes | no | yes (as function) | yes |
| ge | yes | no | no | yes |
| gt | yes | no | no | yes |
| in | yes | no | no | yes |
| iterable | yes | no | no | yes |
| le | yes | no | no | yes |
| lower | yes | no | no | yes |
| lt | yes | no | no | yes |
| mapping | yes | no | yes (as function) | yes |
| ne | yes | no | no | yes |
| none | no | no | no | yes |
| number | yes | no | yes (as function) | yes |
| odd | yes | no | no | yes |
| sameas | no | no | no | yes |
| sequence | yes | no | yes (as function) | yes |
| string | yes | no | yes (as function) | yes |
| undefined | yes | no | no | yes |
| upper | yes | no | no | yes |
| Global functions and classes | ||||
| range | yes | no | yes (as function) | yes |
| lipsum | no | no | no | yes |
| dict | no | no | no | yes |
| cycler | no | no | no | yes |
| joiner | no | no | no | yes |
| namespace | no | no | no | yes |
References
- [1] https://github.com/hughperkins/Jinja2CppLight
- [2] https://github.com/pantor/inja
- [3] https://jinja.palletsprojects.com/en/2.10.x/
Jinja2C++ performance
| Template | Python | Jinja2C++ (MSVC build) | Jinja2C++ (MinGW Build) |
|---|---|---|---|
Hello World from Parser! (1 mln. iterations) | 4.333 sec | 1.883 sec | 0.831 sec |
{{ message }} from Parser! message=’Hello World!’ (1 mln. iterations) | 5.083 | 2.188 | 1.082 |
{{ message }} from Parser! message=100500 (1 mln. iterations) | 5.126 | 2.211 | 1.087 |
{{ message | upper }} from Parser! message=’Hello World!’ (1 mln. iterations) | 5.583 | 3.559 | 1.850 |
{{ message }} from Parser! - {{number}} message=’Hello World!’, number=100500 (1 mln. iterations) | 5.800 | 2.594 | 1.504 |
{% for i in range(20)%} {{i}} {%endfor%} (20 thsd. iterations) | 2.485 | 2.917 | 1.966 |
{% for i in range(num)%} {{i}} {%endfor%} num=20 (20 thsd. iterations) | 2.575 | 2.768 | 2.040 |
{% for i in range(20)%} {{i ~ "-" ~ loop.index}} {%endfor%} (20 thsd. iterations) | 11.720 | 6.334 | 4.340 |
{% for i in range(20) if i is odd %} {{i}} {%endfor%} (20 thsd. iterations) | 2.620 | 3.710 | 2.733 |