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
xmlattr
andtojson
) - 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 |