├── AGENTS.md ├── benchmarks ├── src │ └── lib.rs ├── askama.toml ├── inputs │ ├── footer.html │ └── comparison │ │ ├── tera_footer.html │ │ ├── askama_footer.html │ │ ├── liquid_footer.html │ │ ├── minijinja_footer.html │ │ ├── handlebars_footer.html │ │ ├── tera.html │ │ └── handlebars.html └── rinja.toml ├── minijinja ├── LICENSE ├── README.md ├── doc-header.html ├── tests │ ├── parser-inputs │ │ ├── getattr.txt │ │ ├── map.txt │ │ ├── simple.txt │ │ ├── getitem.txt │ │ ├── err_binop_missing_rhs.txt │ │ ├── err_open_block.txt │ │ ├── err_open_variable_block.txt │ │ ├── ops.txt │ │ ├── string_unescape.txt │ │ ├── ifexpr.txt │ │ ├── list.txt │ │ ├── autoescape.txt │ │ ├── escape.txt │ │ ├── for_loop_unpack.txt │ │ ├── filter_block.txt │ │ ├── if_cond_simple.txt │ │ ├── tuples.txt │ │ ├── err_invalid_var_assignment.txt │ │ ├── err_wrong_block_name.txt │ │ ├── test.txt │ │ ├── if_cond_else.txt │ │ ├── in.txt │ │ ├── for_loop.txt │ │ ├── block.txt │ │ ├── filter.txt │ │ ├── extends.txt │ │ ├── with.txt │ │ ├── call.txt │ │ ├── if_cond.txt │ │ ├── string-implicit-concat.txt │ │ ├── macros.txt │ │ ├── set.txt │ │ ├── include.txt │ │ ├── max-recursion.txt │ │ ├── max-recursion-expr.txt │ │ └── imports.txt │ ├── inputs │ │ ├── int_div_by_zero.txt │ │ ├── int_rem_by_zero.txt │ │ ├── list.txt │ │ ├── map.txt │ │ ├── block_super_err.txt │ │ ├── err_bad_range.txt │ │ ├── err_bad_unary.txt │ │ ├── err_partial_float.txt │ │ ├── err_toplevel_break.txt │ │ ├── float_div_by_zero.txt │ │ ├── refs │ │ │ ├── a_plus_b.txt │ │ │ ├── self-include.txt │ │ │ ├── layout_with_var.txt │ │ │ ├── import-mixed.txt │ │ │ ├── simple_include.txt │ │ │ ├── call_macro.txt │ │ │ ├── self-extends.txt │ │ │ ├── super_with_html.html │ │ │ ├── var_setting_layout.txt │ │ │ ├── simple2_layout.txt │ │ │ ├── example_macro.txt │ │ │ ├── var_referencing_layout.txt │ │ │ ├── simple_layout.txt │ │ │ ├── include_with_var_and_macro.txt │ │ │ └── bad_basic_block.txt │ │ ├── err_bad_addition.txt │ │ ├── err_bad_fast_recurse.txt │ │ ├── err_bad_trailing_underscore.txt │ │ ├── err_toplevel_continue.txt │ │ ├── err_unexpected_character.txt │ │ ├── namespace_bad.txt │ │ ├── err_bad_args_unpack.txt │ │ ├── undefined.txt │ │ ├── err_self_extends.txt │ │ ├── err_self_include.txt │ │ ├── err_trailing_underscore_eol.txt │ │ ├── err_undefined_attr.txt │ │ ├── err_undefined_item.txt │ │ ├── err_bad_call.txt │ │ ├── err_bad_kwargs_unpack.txt │ │ ├── hello.txt │ │ ├── err_bad_call_block_call.txt │ │ ├── err_repeat_iterator_with_object.txt │ │ ├── err_repeat_true_iterator.txt │ │ ├── loop_over_undefined.txt │ │ ├── or.txt │ │ ├── err_repeat_iterator_with_string.txt │ │ ├── escaping.html │ │ ├── filter.txt │ │ ├── err_bad_call_block_list_call.txt │ │ ├── err_missing_nested_filter.txt │ │ ├── err_self_macro_call.txt │ │ ├── err_unterminated_string.txt │ │ ├── err_raw_block_missing_end.txt │ │ ├── err_bad_dotted_assign_forloop.txt │ │ ├── err_bad_dotted_assign_macro.txt │ │ ├── err_bad_dotted_assign_with.txt │ │ ├── err_block_twice.txt │ │ ├── if_cond.txt │ │ ├── loop_over_none.txt │ │ ├── err_bad_filter.txt │ │ ├── err_strict_undefined_print.txt │ │ ├── loop_over_non_iterable.txt │ │ ├── loop_over_string.txt │ │ ├── err_bad_recursion.txt │ │ ├── err_undefined_nested_attr.txt │ │ ├── concat.txt │ │ ├── err_block_in_macro.txt │ │ ├── err_bad_basic_block.txt │ │ ├── filter_block.html │ │ ├── block_super_super.txt │ │ ├── err_bad_block.txt │ │ ├── err_no_super_block.txt │ │ ├── err_strict_undefined_if.txt │ │ ├── err_unexpected_caller_macro.txt │ │ ├── filter_block.txt │ │ ├── include_choice_none.txt │ │ ├── include_missing.txt │ │ ├── self.txt │ │ ├── err_extends_twice.txt │ │ ├── err_too_large_integer.txt │ │ ├── err_duplicate_macro_arg.txt │ │ ├── err_too_many_macro_kwargs.txt │ │ ├── loop-recursion-error.txt │ │ ├── err_bad_nested_subtraction.txt │ │ ├── err_strict_undefined_for.txt │ │ ├── err_too_many_macro_args.txt │ │ ├── block.txt │ │ ├── block_scope.txt │ │ ├── err_too_many_macro_kwargs2.txt │ │ ├── extends_set.txt │ │ ├── if_cond_else.txt │ │ ├── import_all.txt │ │ ├── include_ignore_missing.txt │ │ ├── cmp.txt │ │ ├── err_in_include.txt │ │ ├── err_strict_undefined_for_filter.txt │ │ ├── include_ignore_choice.txt │ │ ├── loop_else.txt │ │ ├── macro_include.txt │ │ ├── err_bad_test.txt │ │ ├── block_scope_extends.txt │ │ ├── err_bad_test_arguments.txt │ │ ├── macro_calling_macro.txt │ │ ├── getattr.txt │ │ ├── include.txt │ │ ├── mul.txt │ │ ├── macro_hoisting.txt │ │ ├── tojson.txt │ │ ├── dict.txt │ │ ├── do_closure.txt │ │ ├── err_extends_actually_not.txt │ │ ├── extends.txt │ │ ├── loop.txt │ │ ├── do_macro_calling_macro.txt │ │ ├── inexpr.txt │ │ ├── loop_bad_unpacking.txt │ │ ├── loop_controls.txt │ │ ├── block_super.txt │ │ ├── err_bad_super.txt │ │ ├── escape.txt │ │ ├── call.txt │ │ ├── do_macro.txt │ │ ├── loop_else2.txt │ │ ├── macro_kwargs.txt │ │ ├── block_super.html │ │ ├── macro_import.txt │ │ ├── block_scope_super.txt │ │ ├── if_cond_elif.txt │ │ ├── ifexpr.txt │ │ ├── macro_extends.txt │ │ ├── macro_import2.txt │ │ ├── loop_break_one_shot_iter.txt │ │ ├── debug.txt │ │ ├── macro_basic.txt │ │ ├── getitem.txt │ │ ├── loop_break_one_shot_iter_peek.txt │ │ ├── math.txt │ │ ├── adding.txt │ │ ├── indexing.txt │ │ ├── autoescape.html │ │ ├── autoescape.txt │ │ ├── loop_filter.txt │ │ ├── literals.txt │ │ ├── functions.txt │ │ ├── loop_bad_unpacking_wrong_len.txt │ │ ├── loop_unpacking.txt │ │ ├── macro_closure_behavior.txt │ │ ├── in.txt │ │ ├── macro_caller_methods.txt │ │ ├── coerce.txt │ │ ├── namespace.txt │ │ ├── macro_caller.txt │ │ ├── loop_var.txt │ │ ├── with.txt │ │ ├── calls-and-literals.txt │ │ ├── slicing.txt │ │ └── macro_recursive.txt │ ├── lexer-inputs │ │ ├── basic.txt │ │ ├── parent-balance.txt │ │ ├── single_brace.txt │ │ ├── operators.txt │ │ ├── block-filter.txt │ │ ├── no-trim-blocks.loop.txt │ │ ├── keep-trailing-newlines.txt │ │ ├── loop.txt │ │ ├── things.txt │ │ ├── whitespace.txt │ │ ├── lstrip-blocks-keep-inline-space.txt │ │ ├── trim-blocks.loop.txt │ │ ├── attrs.txt │ │ ├── lstrip-blocks-raw.txt │ │ ├── lstrip-blocks-comment.txt │ │ ├── raw.txt │ │ ├── lstrip-blocks.txt │ │ ├── lstrip-blocks-preserve.txt │ │ ├── line-comment.txt │ │ ├── line-statement.txt │ │ └── literals.txt │ ├── fragment-inputs │ │ ├── refs │ │ │ ├── fragment_in_parent.txt │ │ │ ├── simple_layout_2.txt │ │ │ ├── simple_layout.txt │ │ │ └── var_referencing_layout.txt │ │ ├── fragment_from_parent.txt │ │ ├── fragment_simple_extend.txt │ │ ├── fragment_ref_parent.txt │ │ ├── fragment_simple.txt │ │ ├── fragment_super.txt │ │ └── fragment_super_super.txt │ ├── snapshots │ │ ├── test_templates__vm@list.txt.snap │ │ ├── test_templates__vm@map.txt.snap │ │ ├── test_templates__vm@float_div_by_zero.txt.snap │ │ ├── test_templates__vm@hello.txt.snap │ │ ├── test_templates__vm@undefined.txt.snap │ │ ├── test_templates__vm@concat.txt.snap │ │ ├── test_templates__vm@filter.txt.snap │ │ ├── test_templates__vm@loop_over_undefined.txt.snap │ │ ├── test_templates__vm@or.txt.snap │ │ ├── test_lexer__lexer@single_brace.txt.snap │ │ ├── test_templates__vm@loop_over_none.txt.snap │ │ ├── test_templates__vm@escaping.html.snap │ │ ├── test_lexer__lexer@keep-trailing-newlines.txt.snap │ │ ├── test_templates__vm@if_cond.txt.snap │ │ ├── test_compiler__const.snap │ │ ├── test_templates__vm@cmp.txt.snap │ │ ├── test_templates__vm@filter_block.html.snap │ │ ├── test_templates__vm@self.txt.snap │ │ ├── test_templates__vm@filter_block.txt.snap │ │ ├── test_templates__vm@if_cond_else.txt.snap │ │ ├── test_templates__vm@block.txt.snap │ │ ├── test_templates__vm@block_scope.txt.snap │ │ ├── test_templates__vm@loop_else.txt.snap │ │ ├── test_templates__vm@loop_over_string.txt.snap │ │ ├── test_templates__vm@extends_set.txt.snap │ │ ├── test_templates__vm@getattr.txt.snap │ │ ├── test_templates__vm@import_all.txt.snap │ │ ├── test_templates__vm@include_ignore_missing.txt.snap │ │ ├── test_templates__vm@macro_calling_macro.txt.snap │ │ ├── test_templates__vm@block_super_super.txt.snap │ │ ├── test_templates__vm@loop_controls.txt.snap │ │ ├── test_lexer__lexer@basic.txt.snap │ │ ├── test_templates__vm@err_extends_actually_not.txt.snap │ │ ├── test_templates__vm@inexpr.txt.snap │ │ ├── test_templates__vm@extends.txt.snap │ │ ├── test_templates__vm@if_cond_elif.txt.snap │ │ ├── test_templates__vm@loop_else2.txt.snap │ │ ├── test_compiler__bool_ops.snap │ │ ├── test_templates__vm@include.txt.snap │ │ ├── test_templates__vm@include_ignore_choice.txt.snap │ │ ├── test_templates__vm@macro_hoisting.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_from_parent.txt.snap │ │ ├── test_templates__vm@block_scope_extends.txt.snap │ │ ├── test_templates__vm@macro_include.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_simple_extend.txt.snap │ │ ├── test_templates__vm@ifexpr.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_simple.txt.snap │ │ ├── test_templates__vm@do_macro_calling_macro.txt.snap │ │ ├── test_templates__vm@block_super.txt.snap │ │ ├── test_templates__vm@do_closure.txt.snap │ │ ├── test_compiler__for_loop.snap │ │ ├── test_templates__vm@call.txt.snap │ │ ├── test_templates__vm@loop.txt.snap │ │ ├── test_templates__vm@mul.txt.snap │ │ ├── test_parser__parser@err_open_block.txt.snap │ │ ├── test_parser__parser@err_binop_missing_rhs.txt.snap │ │ ├── test_templates__vm@escape.txt.snap │ │ ├── test_templates__vm@macro_extends.txt.snap │ │ ├── test_lexer__lexer@lstrip-blocks-raw.txt.snap │ │ ├── test_templates__vm@do_macro.txt.snap │ │ ├── test_templates__vm@getitem.txt.snap │ │ ├── test_templates__vm@block_scope_super.txt.snap │ │ ├── test_parser__parser@err_open_variable_block.txt.snap │ │ ├── test_templates__vm@loop_break_one_shot_iter.txt.snap │ │ ├── test_templates__vm@macro_import.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_super.txt.snap │ │ ├── test_parser__parser@err_wrong_block_name.txt.snap │ │ ├── test_parser__parser@err_invalid_var_assignment.txt.snap │ │ ├── test_templates__vm@macro_basic.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_ref_parent.txt.snap │ │ ├── test_parser__parser@string_unescape.txt.snap │ │ ├── test_templates__vm@loop_unpacking.txt.snap │ │ ├── test_templates__vm_block_fragments@fragment_super_super.txt.snap │ │ ├── test_templates__vm@block_super.html.snap │ │ ├── test_templates__vm@macro_kwargs.txt.snap │ │ ├── test_lexer__lexer@parent-balance.txt.snap │ │ ├── test_templates__vm@loop_break_one_shot_iter_peek.txt.snap │ │ ├── test_compiler__if_branches.snap │ │ ├── test_templates__vm@autoescape.txt.snap │ │ ├── test_templates__vm@autoescape.html.snap │ │ ├── test_templates__vm@tojson.txt.snap │ │ ├── test_templates__vm@macro_import2.txt.snap │ │ ├── test_templates__vm@macro_closure_behavior.txt.snap │ │ ├── test_lexer__lexer@lstrip-blocks-keep-inline-space.txt.snap │ │ ├── test_templates__vm@in.txt.snap │ │ ├── test_lexer__lexer@lstrip-blocks-comment.txt.snap │ │ ├── test_templates__vm@loop_filter.txt.snap │ │ ├── test_templates__vm@adding.txt.snap │ │ ├── test_templates__vm@math.txt.snap │ │ ├── test_lexer__lexer@block-filter.txt.snap │ │ ├── test_templates__vm@indexing.txt.snap │ │ ├── test_templates__vm@dict.txt.snap │ │ ├── test_parser__parser@simple.txt.snap │ │ ├── test_templates__vm@namespace.txt.snap │ │ ├── test_templates__vm@with.txt.snap │ │ ├── test_lexer__lexer@whitespace.txt.snap │ │ ├── test_parser__parser@autoescape.txt.snap │ │ ├── test_parser__parser@max-recursion.txt.snap │ │ ├── test_lexer__lexer@trim-blocks.loop.txt.snap │ │ ├── test_lexer__lexer@no-trim-blocks.loop.txt.snap │ │ ├── test_templates__vm@literals.txt.snap │ │ ├── test_templates__vm@macro_recursive.txt.snap │ │ ├── test_parser__parser@getattr.txt.snap │ │ ├── test_templates__vm@coerce.txt.snap │ │ └── test_parser__parser@if_cond_simple.txt.snap │ ├── test_tests.rs │ └── test_parser.rs └── src │ └── compiler │ └── mod.rs ├── minijinja-embed ├── LICENSE ├── doc-header.html └── Cargo.toml ├── minijinja-autoreload ├── LICENSE └── doc-header.html ├── minijinja-contrib ├── LICENSE └── doc-header.html ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 2-feature.md │ └── 1-bug.md ├── dependabot.yml └── workflows │ ├── pyright.yml │ ├── typos.yml │ ├── clippy.yml │ ├── rustfmt.yml │ └── publish-crates.yml ├── fuzz ├── seeds │ ├── render │ │ ├── expr │ │ ├── expr-func │ │ ├── expr-float │ │ ├── expr-integer │ │ ├── expr-list │ │ ├── expr-getattr │ │ ├── if │ │ ├── with │ │ ├── expr-dict │ │ ├── extends │ │ ├── expr-filter │ │ ├── if-else │ │ ├── autoescape │ │ ├── block │ │ ├── if-elif-else │ │ ├── macro │ │ ├── loop │ │ └── call │ └── add_template │ │ ├── expr │ │ ├── expr-float │ │ ├── expr-func │ │ ├── expr-integer │ │ ├── expr-list │ │ ├── expr-getattr │ │ ├── if │ │ ├── extends │ │ ├── with │ │ ├── expr-dict │ │ ├── block │ │ ├── if-else │ │ ├── if-elif-else │ │ └── loop ├── .gitignore └── fuzz_targets │ └── add_template.rs ├── minijinja-cabi ├── .gitignore ├── Makefile ├── example │ └── Makefile ├── Cargo.toml ├── src │ └── lib.rs └── cbindgen.toml ├── minijinja-cli ├── examples │ ├── alias.j2 │ ├── dump.j2 │ ├── hello.qs │ ├── hello.yaml │ ├── include.txt │ ├── hello.toml │ ├── hello.j2 │ ├── hello.json │ ├── alias.yaml │ └── hello.json5 ├── Makefile └── src │ └── main.rs ├── minijinja-js ├── .gitignore ├── .cargo │ └── config.toml └── Makefile ├── .clippy.toml ├── examples ├── state-temps │ ├── src │ │ ├── en.txt │ │ └── de.txt │ ├── Cargo.toml │ └── README.md ├── autoreload │ ├── templates │ │ ├── include.txt │ │ └── template.txt │ ├── README.md │ └── Cargo.toml ├── custom-loader │ ├── templates │ │ ├── layout.txt │ │ └── hello.txt │ ├── README.md │ └── Cargo.toml ├── minimal │ ├── src │ │ ├── hello.txt │ │ └── main.rs │ ├── README.md │ └── Cargo.toml ├── path-loader │ ├── templates │ │ ├── hello.txt │ │ └── layout.txt │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── render-template │ ├── users.json │ ├── users.html │ ├── README.md │ └── Cargo.toml ├── debug │ ├── README.md │ ├── src │ │ ├── demo.txt │ │ └── main.rs │ └── Cargo.toml ├── macros │ ├── README.md │ ├── src │ │ ├── macros.html │ │ ├── template.html │ │ └── main.rs │ └── Cargo.toml ├── actix-web-demo │ ├── templates │ │ ├── index.html │ │ └── user.html │ ├── README.md │ └── Cargo.toml ├── call-block-function │ ├── src │ │ └── demo.txt │ ├── README.md │ └── Cargo.toml ├── render-macro │ ├── src │ │ └── main.rs │ ├── README.md │ └── Cargo.toml ├── deserialize │ ├── src │ │ └── example.txt │ ├── README.md │ └── Cargo.toml ├── load-lazy │ ├── src │ │ ├── template.html │ │ └── nav.json │ └── Cargo.toml ├── hello │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── render-value │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── generate-yaml │ ├── src │ │ └── template.yaml │ ├── Cargo.toml │ └── README.md ├── line-statements │ ├── README.md │ ├── src │ │ ├── hello.txt │ │ └── main.rs │ └── Cargo.toml ├── dynamic-context │ ├── src │ │ └── template.txt │ ├── Cargo.toml │ └── README.md ├── inheritance │ ├── src │ │ ├── index.html │ │ ├── layout.html │ │ └── main.rs │ ├── README.md │ └── Cargo.toml ├── embedding │ ├── src │ │ └── templates │ │ │ ├── index.html │ │ │ └── layout.html │ ├── build.rs │ ├── README.md │ └── Cargo.toml ├── filters │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── template.html ├── syntax-highlighting │ ├── README.md │ ├── src │ │ └── example.html │ └── Cargo.toml ├── load-resource │ ├── src │ │ ├── template.html │ │ └── nav.json │ ├── Cargo.toml │ └── README.md ├── object-using-async │ ├── README.md │ └── Cargo.toml ├── object-ref │ ├── README.md │ ├── src │ │ └── template.txt │ └── Cargo.toml ├── custom-error │ ├── README.md │ └── Cargo.toml ├── function-using-async │ ├── README.md │ └── Cargo.toml ├── build-script │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ └── example.rs.jinja ├── none-as-undefined │ ├── README.md │ └── Cargo.toml ├── eval-to-state │ ├── src │ │ └── templates │ │ │ ├── index.html │ │ │ └── layout.html │ ├── README.md │ └── Cargo.toml ├── invalid-value │ ├── README.md │ └── Cargo.toml ├── error │ └── Cargo.toml ├── streaming │ ├── Cargo.toml │ └── README.md ├── dsl │ └── Cargo.toml ├── dynamic-objects │ ├── Cargo.toml │ ├── src │ │ └── template.html │ └── README.md ├── merge-context │ ├── README.md │ └── Cargo.toml ├── undefined-tracking │ ├── README.md │ └── Cargo.toml ├── value-tracking │ ├── Cargo.toml │ └── README.md ├── expr │ ├── Cargo.toml │ └── README.md ├── self-referential-context │ ├── Cargo.toml │ └── README.md └── recursive-for │ ├── Cargo.toml │ └── README.md ├── minijinja-py ├── tests │ ├── templates │ │ ├── base.txt │ │ └── includes │ │ │ └── foo.txt │ └── test_security.py ├── .vscode │ └── settings.json ├── build.rs ├── .gitignore ├── src │ └── lib.rs ├── Makefile ├── python │ └── minijinja │ │ ├── _lowlevel.pyi │ │ └── _internal.py └── hello.py ├── artwork ├── logo.ai ├── logo.png └── logo-square.png ├── .gitignore ├── .devcontainer └── devcontainer.json ├── .vscode └── settings.json ├── scripts ├── wasmtime-wrapper.sh └── publish-all.sh ├── _typos.toml ├── Cargo.toml ├── .cargo └── config.toml └── doc-header.html /AGENTS.md: -------------------------------------------------------------------------------- 1 | CLAUDE.md -------------------------------------------------------------------------------- /benchmarks/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /minijinja/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /minijinja-embed/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /minijinja/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /minijinja-autoreload/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /minijinja-contrib/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [mitsuhiko] 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr: -------------------------------------------------------------------------------- 1 | {{ 1 + 4 / 9 }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-func: -------------------------------------------------------------------------------- 1 | {{ foo() }} 2 | -------------------------------------------------------------------------------- /minijinja-cabi/.gitignore: -------------------------------------------------------------------------------- 1 | example/hello 2 | -------------------------------------------------------------------------------- /minijinja-cli/examples/alias.j2: -------------------------------------------------------------------------------- 1 | {{ dict3 }} -------------------------------------------------------------------------------- /minijinja-cli/examples/dump.j2: -------------------------------------------------------------------------------- 1 | {{ debug() }} -------------------------------------------------------------------------------- /minijinja/doc-header.html: -------------------------------------------------------------------------------- 1 | ../doc-header.html -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-float: -------------------------------------------------------------------------------- 1 | {{ 1001.23 }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-integer: -------------------------------------------------------------------------------- 1 | {{ 1001 }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-list: -------------------------------------------------------------------------------- 1 | {{ [1, 2, 3] }} 2 | -------------------------------------------------------------------------------- /fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | corpus 3 | artifacts 4 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr: -------------------------------------------------------------------------------- 1 | {{ expression }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-float: -------------------------------------------------------------------------------- 1 | {{ 1001.23 }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-func: -------------------------------------------------------------------------------- 1 | {{ foo() }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-integer: -------------------------------------------------------------------------------- 1 | {{ 1001 }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-list: -------------------------------------------------------------------------------- 1 | {{ [1, 2, 3] }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-getattr: -------------------------------------------------------------------------------- 1 | {{ foo.bar.baz }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/if: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% endif %} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/with: -------------------------------------------------------------------------------- 1 | {% with expr %}...{% endwith %} -------------------------------------------------------------------------------- /minijinja-contrib/doc-header.html: -------------------------------------------------------------------------------- 1 | ../doc-header.html -------------------------------------------------------------------------------- /minijinja-embed/doc-header.html: -------------------------------------------------------------------------------- 1 | ../doc-header.html -------------------------------------------------------------------------------- /minijinja-js/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.clippy.toml: -------------------------------------------------------------------------------- 1 | doc-valid-idents = ["MiniJinja", ".."] 2 | -------------------------------------------------------------------------------- /benchmarks/askama.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | dirs = ["inputs"] 3 | -------------------------------------------------------------------------------- /benchmarks/inputs/footer.html: -------------------------------------------------------------------------------- 1 | Copyright {{ copyright }}! -------------------------------------------------------------------------------- /benchmarks/rinja.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | dirs = ["inputs"] 3 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-getattr: -------------------------------------------------------------------------------- 1 | {{ foo.bar.baz }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/if: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% endif %} 2 | -------------------------------------------------------------------------------- /minijinja-autoreload/doc-header.html: -------------------------------------------------------------------------------- 1 | ../doc-header.html -------------------------------------------------------------------------------- /examples/state-temps/src/en.txt: -------------------------------------------------------------------------------- 1 | GREETING=Hello 2 | GOODBYE=Bye -------------------------------------------------------------------------------- /fuzz/seeds/add_template/extends: -------------------------------------------------------------------------------- 1 | {% extends "template.html" %} -------------------------------------------------------------------------------- /fuzz/seeds/add_template/with: -------------------------------------------------------------------------------- 1 | {% with expr %}...{% endwith %} -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-dict: -------------------------------------------------------------------------------- 1 | {{ {"foo": "bar", "bar": 42} }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/extends: -------------------------------------------------------------------------------- 1 | {% extends "template.html" %} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/getattr.txt: -------------------------------------------------------------------------------- 1 | {{ foo.bar.baz }} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/map.txt: -------------------------------------------------------------------------------- 1 | {{ {"foo": "bar"} }} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/simple.txt: -------------------------------------------------------------------------------- 1 | Hello {{ world }}! 2 | -------------------------------------------------------------------------------- /examples/autoreload/templates/include.txt: -------------------------------------------------------------------------------- 1 | This is an included file. -------------------------------------------------------------------------------- /examples/state-temps/src/de.txt: -------------------------------------------------------------------------------- 1 | GREETING=Hallo 2 | GOODBYE=Tschau -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/getitem.txt: -------------------------------------------------------------------------------- 1 | {{ foo["bar"][42] }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/expr-dict: -------------------------------------------------------------------------------- 1 | {{ {"foo": "bar", "bar": 42} }} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/expr-filter: -------------------------------------------------------------------------------- 1 | {{ foo|join('|') }} 2 | {{ foo|upper }} 3 | -------------------------------------------------------------------------------- /fuzz/seeds/render/if-else: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% else %}...{% endif %} 2 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/int_div_by_zero.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10 // 0 }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/int_rem_by_zero.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10 % 0 }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/list.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ [1, 2, 3]|length }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/map.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ {"foo":"bar"}.foo }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/err_binop_missing_rhs.txt: -------------------------------------------------------------------------------- 1 | {{ foo / }} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/err_open_block.txt: -------------------------------------------------------------------------------- 1 | {% block foo bar 2 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/block: -------------------------------------------------------------------------------- 1 | {% block title %}Hello {{ title }}{% endblock %} -------------------------------------------------------------------------------- /fuzz/seeds/add_template/if-else: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% else %}...{% endif %} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/autoescape: -------------------------------------------------------------------------------- 1 | {% autoescape true %}...{% endautoescape %} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/block: -------------------------------------------------------------------------------- 1 | {% block title %}Hello {{ title }}{% endblock %} 2 | -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.qs: -------------------------------------------------------------------------------- 1 | name=World&list[0]=foo&list[1]=bar&list[2]=baz -------------------------------------------------------------------------------- /minijinja-py/tests/templates/base.txt: -------------------------------------------------------------------------------- 1 | {% include "includes/foo.txt" %} 2 | -------------------------------------------------------------------------------- /minijinja-py/tests/templates/includes/foo.txt: -------------------------------------------------------------------------------- 1 | I am from foo! {{ woot }}! 2 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_super_err.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ super() }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_range.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ range(100001) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_unary.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ foo(-[1, 2]) }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_partial_float.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 42e+ }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_toplevel_break.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% break %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/float_div_by_zero.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10.0 / 0.0 }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/a_plus_b.txt: -------------------------------------------------------------------------------- 1 | This template adds b to a: {{ a + b }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/self-include.txt: -------------------------------------------------------------------------------- 1 | {% include "self-include.txt" %} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/basic.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | Hello {{ name }}! 4 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/err_open_variable_block.txt: -------------------------------------------------------------------------------- 1 | Hello {{ world 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/ops.txt: -------------------------------------------------------------------------------- 1 | {{ foo and bar or baz == true }} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/string_unescape.txt: -------------------------------------------------------------------------------- 1 | {{ "foo\u2603bar" }} 2 | -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.yaml: -------------------------------------------------------------------------------- 1 | name: World 2 | count: 3 3 | list: [foo, bar, baz] -------------------------------------------------------------------------------- /minijinja-js/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_addition.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ [1, 2] + 23 }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_fast_recurse.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ loop([1, 2, 3]) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_trailing_underscore.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10_ }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_toplevel_continue.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% continue %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_unexpected_character.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ foo @ }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/namespace_bad.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {{ namespace(42) }} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/parent-balance.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ {"a": {"b": 1}} }} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/single_brace.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {foo} foo {bar} 4 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/ifexpr.txt: -------------------------------------------------------------------------------- 1 | {{ a if b else c }} 2 | {{ a if b }} 3 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/list.txt: -------------------------------------------------------------------------------- 1 | {{ [1, 2, foo] }} 2 | {{ [1, 2, 3,] }} 3 | -------------------------------------------------------------------------------- /artwork/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitsuhiko/minijinja/HEAD/artwork/logo.ai -------------------------------------------------------------------------------- /artwork/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitsuhiko/minijinja/HEAD/artwork/logo.png -------------------------------------------------------------------------------- /minijinja-cli/Makefile: -------------------------------------------------------------------------------- 1 | update-syntax-docs: 2 | uv run ./generate-syntax-docs.py 3 | -------------------------------------------------------------------------------- /minijinja-py/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } -------------------------------------------------------------------------------- /minijinja-py/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | pyo3_build_config::use_pyo3_cfgs(); 3 | } 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_args_unpack.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ get_args(*true) }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/undefined.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ none }} 4 | {{ undefined }} 5 | -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/tera_footer.html: -------------------------------------------------------------------------------- 1 | © Copyright {{ site.copyright }} by Foo -------------------------------------------------------------------------------- /fuzz/seeds/render/if-elif-else: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% elif expr %}...{% else %}...{% endif %} 2 | -------------------------------------------------------------------------------- /minijinja-cli/examples/include.txt: -------------------------------------------------------------------------------- 1 | Text from an included template 2 | {% set x = 42 %} 3 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_self_extends.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% extends "self-extends.txt" %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_self_include.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% include "self-include.txt" %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_trailing_underscore_eol.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10_ 4 | + 42 }} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_undefined_attr.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ undefined_value.attr }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_undefined_item.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3]} 2 | --- 3 | {{ seq[42][23] }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/layout_with_var.txt: -------------------------------------------------------------------------------- 1 | {% block body %}{{ var }}{% endblock %} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/autoescape.txt: -------------------------------------------------------------------------------- 1 | {% autoescape false %}foo{% endautoescape %} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/escape.txt: -------------------------------------------------------------------------------- 1 | {{'\'' ~ 'foo'}} 2 | {{'\'' ~ "foo"}} 3 | {{"\'"}} -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/askama_footer.html: -------------------------------------------------------------------------------- 1 | © Copyright {{ site.copyright }} by Foo 2 | -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/liquid_footer.html: -------------------------------------------------------------------------------- 1 | © Copyright {{ site.copyright|escape }} by Foo -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/minijinja_footer.html: -------------------------------------------------------------------------------- 1 | © Copyright {{ site.copyright }} by Foo -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_call.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | This is {{ an_unknown_function() }}! 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_kwargs_unpack.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ get_args(**[1, 2, 3]) }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/hello.txt: -------------------------------------------------------------------------------- 1 | { 2 | "name": "World" 3 | } 4 | --- 5 | Hello {{ name }}! 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/import-mixed.txt: -------------------------------------------------------------------------------- 1 | This is the body {{ x }} 2 | {%- set output = 42 %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/simple_include.txt: -------------------------------------------------------------------------------- 1 | Hello {{ variable }} from included template! 2 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/operators.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ (a + b) * (c - d) / e % f // g ~ h }} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/for_loop_unpack.txt: -------------------------------------------------------------------------------- 1 | {% for (a, b), c in seq %}...{% endfor %} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .vscode/*.log 3 | profile.json 4 | **/snapshots/*.new 5 | **/*.pending-snap 6 | -------------------------------------------------------------------------------- /artwork/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitsuhiko/minijinja/HEAD/artwork/logo-square.png -------------------------------------------------------------------------------- /examples/custom-loader/templates/layout.txt: -------------------------------------------------------------------------------- 1 | header 2 | {% block body %}{% endblock %} 3 | footer 4 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/if-elif-else: -------------------------------------------------------------------------------- 1 | {% if expr %}...{% elif expr %}...{% else %}...{% endif %} 2 | -------------------------------------------------------------------------------- /fuzz/seeds/render/macro: -------------------------------------------------------------------------------- 1 | {% macro name(a, b) %}{{ a }} | {{ b }}{% endmacro %} 2 | {{ name(1, 2) }} 3 | -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.toml: -------------------------------------------------------------------------------- 1 | name = "World" 2 | count = 3 3 | list = ["foo", "bar", "baz"] 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_call_block_call.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% call 42 %}...{% endcall %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_repeat_iterator_with_object.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {{ [1, 2, 3] * {} }} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_repeat_true_iterator.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {{ one_shot_iterator * 3 }} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_over_undefined.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | [{% for item in seq %}{% endfor %}] 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/or.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 42 or 23 }} 4 | {{ 0 or 23 }} 5 | {{ none or 23 }} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/call_macro.txt: -------------------------------------------------------------------------------- 1 | {% macro call(other, arg) %}{{ other(arg) }}{% endmacro %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/filter_block.txt: -------------------------------------------------------------------------------- 1 | {% filter foo|bar(1, 2)|baz %}...{% endfilter %} 2 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/if_cond_simple.txt: -------------------------------------------------------------------------------- 1 | {% if expr1 %} 2 | branch 1 3 | {% endif %} 4 | -------------------------------------------------------------------------------- /fuzz/seeds/add_template/loop: -------------------------------------------------------------------------------- 1 | {% for key, value in dict %} 2 | {{ key }}: {{ value }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_repeat_iterator_with_string.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {{ [1, 2, 3] * "3" }} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/escaping.html: -------------------------------------------------------------------------------- 1 | { 2 | "unsafe": "" 3 | } 4 | --- 5 |

{{ unsafe }}

6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/filter.txt: -------------------------------------------------------------------------------- 1 | { 2 | "value": "foo bar baz" 3 | } 4 | --- 5 | {{ value|upper }} 6 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/tuples.txt: -------------------------------------------------------------------------------- 1 | {{ [1, 2, 3] }} 2 | {{ (1, 2, 3) }} 3 | {{ (1,) }} 4 | {{ () }} 5 | -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/handlebars_footer.html: -------------------------------------------------------------------------------- 1 | © Copyright {{#with site}}{{ copyright }}{{/with}} by Foo -------------------------------------------------------------------------------- /minijinja-cabi/Makefile: -------------------------------------------------------------------------------- 1 | generate: 2 | @./generate.sh --verify 3 | 4 | hello: 5 | $(MAKE) -C example hello 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_call_block_list_call.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% call [1, 2, 3] %}...{% endcall %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_missing_nested_filter.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ "foo"|upper|missingFilter|lower }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_self_macro_call.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro x() %}{{ x() }}{% endmacro %} 4 | {{ x() }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_unterminated_string.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ "this string is missing a closing quote 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/self-extends.txt: -------------------------------------------------------------------------------- 1 | {% extends "self-extends.txt" %} 2 | {% block wat %}{% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/err_invalid_var_assignment.txt: -------------------------------------------------------------------------------- 1 | {% for loop in seq %} 2 | ... 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/err_wrong_block_name.txt: -------------------------------------------------------------------------------- 1 | {% block foo %} 2 | here 3 | {% endblock bar %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/test.txt: -------------------------------------------------------------------------------- 1 | {{ foo is even }} 2 | {{ foo is not even }} 3 | {{ not foo is even }} 4 | -------------------------------------------------------------------------------- /examples/minimal/src/hello.txt: -------------------------------------------------------------------------------- 1 | {% for name in names %} 2 | {{- loop.index }}. Hello {{ name }}! 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /minijinja-py/.gitignore: -------------------------------------------------------------------------------- 1 | .venv 2 | __pycache__ 3 | python/minijinja/_lowlevel.* 4 | !python/minijinja/_lowlevel.pyi 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_raw_block_missing_end.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% raw %}this raw block is missing an end tag 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/super_with_html.html: -------------------------------------------------------------------------------- 1 | {% block body %} 2 |

Default Content

3 | {% endblock %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/block-filter.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for item in seq -%} 4 | {{ item }}{% endfor %} 5 | -------------------------------------------------------------------------------- /fuzz/seeds/render/loop: -------------------------------------------------------------------------------- 1 | {% for key, value in dict %} 2 | {{ loop.index0 }} -> {{ key }}: {{ value }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_dotted_assign_forloop.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for foo.baz in [] %} 4 | ... 5 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_dotted_assign_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro foo(bar.baz) %} 4 | ... 5 | {% endmacro %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_dotted_assign_with.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% with foo.bar = 42 %} 4 | ... 5 | {% endwith %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_block_twice.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% block foo %}{% endblock %} 4 | {% block foo %}{% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/if_cond.txt: -------------------------------------------------------------------------------- 1 | { 2 | "value": 42 3 | } 4 | --- 5 | {% if value %} 6 | was true 7 | {% endif %} 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_over_none.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": null 3 | } 4 | --- 5 | [{% for item in seq %}{% endfor %}] 6 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/no-trim-blocks.loop.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for item in seq %} 4 | {{ item }} 5 | {% endfor %} -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Suggestion 3 | about: Want to report a suggestion for a feature? 4 | --- 5 | -------------------------------------------------------------------------------- /examples/custom-loader/templates/hello.txt: -------------------------------------------------------------------------------- 1 | {% extends "layout.txt" %} 2 | {% block body %}Hello {{ name }}!{% endblock %} 3 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/refs/fragment_in_parent.txt: -------------------------------------------------------------------------------- 1 | {% block fragment %} 2 | Should show up 3 | {% endblock %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_filter.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for item in 42|slice(4) %} 4 | - {{ item }} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_strict_undefined_print.txt: -------------------------------------------------------------------------------- 1 | {"$settings": {"undefined": "strict"}} 2 | --- 3 | {{ undefined_value }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_over_non_iterable.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": 42 3 | } 4 | --- 5 | [{% for item in seq %}{% endfor %}] 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_over_string.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for char in "abcdefg" -%} 4 | {{ char }} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/var_setting_layout.txt: -------------------------------------------------------------------------------- 1 | {% block test %}{% set var = "from super" %}inside: {{ var }}{% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/keep-trailing-newlines.txt: -------------------------------------------------------------------------------- 1 | { 2 | "keep_trailing_newline": true 3 | } 4 | --- 5 | Hello World! 6 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/if_cond_else.txt: -------------------------------------------------------------------------------- 1 | {% if expr1 %} 2 | branch 1 3 | {% else %} 4 | else 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/in.txt: -------------------------------------------------------------------------------- 1 | {{ value in sequence }} 2 | {{ value not in sequence }} 3 | {{ not value in sequence }} 4 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rust", 3 | "image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye" 4 | } -------------------------------------------------------------------------------- /minijinja-cabi/example/Makefile: -------------------------------------------------------------------------------- 1 | hello: hello.c 2 | cc -I../include ./hello.c -L../../target/release -lminijinja_cabi -o hello 3 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_recursion.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for x in [1, 2, 3] recursive %} 4 | {{ loop(x) }} 5 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_undefined_nested_attr.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3]} 2 | --- 3 | {{ seq.whatever }} 4 | {{ seq.whatever.else }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/simple2_layout.txt: -------------------------------------------------------------------------------- 1 | {% extends "simple_layout.txt" %} 2 | {% block title %}({{ super() }}){% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/for_loop.txt: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /examples/autoreload/templates/template.txt: -------------------------------------------------------------------------------- 1 | Hello World from iteration {{ iteration }}! 2 | {% include "include.txt" ignore missing %} 3 | -------------------------------------------------------------------------------- /examples/path-loader/templates/hello.txt: -------------------------------------------------------------------------------- 1 | {% extends "layout.txt" %} 2 | {% block body %} 3 | Hello {{ name }}! 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /examples/render-template/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "users": [ 3 | {"id": 1, "name": "Peter"}, 4 | {"id": 2, "name": "John"} 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/concat.txt: -------------------------------------------------------------------------------- 1 | { 2 | "a": "foo", 3 | "b": "bar" 4 | } 5 | --- 6 | {{ a ~ b }} 7 | {{ a + b }} 8 | {{ a[0] + a[1:] }} 9 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_block_in_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro two_args(a, b) %} 4 | {% block foo %}{% endblock %} 5 | {% endmacro %} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/loop.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/things.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ with_int(42, -42) }} 4 | {{ with_float(1.5, -1.5) }} 5 | {{ with_string("string") }} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/whitespace.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | foo {{- bar -}} baz {{ blah }} blub 4 | foo {#- comment -#} baz {# blah #} blub 5 | -------------------------------------------------------------------------------- /examples/debug/README.md: -------------------------------------------------------------------------------- 1 | # debug 2 | 3 | A simple example of how to use the `debug()` function: 4 | 5 | ```console 6 | $ cargo run 7 | ``` 8 | -------------------------------------------------------------------------------- /examples/macros/README.md: -------------------------------------------------------------------------------- 1 | # macros 2 | 3 | This example demonstrates how to use macros and imports. 4 | 5 | ```console 6 | $ cargo run 7 | ``` 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_basic_block.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% extends "bad_basic_block.txt" %} 4 | {% block title %}My Title{% endblock %} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/filter_block.html: -------------------------------------------------------------------------------- 1 | { 2 | "value": "foo < bar" 3 | } 4 | --- 5 | {% filter escape %}

{{ value }}

{% endfilter %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/example_macro.txt: -------------------------------------------------------------------------------- 1 | {% set d = "closure" -%} 2 | {% macro example(a, b, c="default") %}{{ [a, b, c, d] }}{% endmacro -%} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/lstrip-blocks-keep-inline-space.txt: -------------------------------------------------------------------------------- 1 | { 2 | "lstrip_blocks": true 3 | } 4 | --- 5 | [{% if true %} {% endif %}] 6 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/block.txt: -------------------------------------------------------------------------------- 1 | {% block title %}{% endblock %} 2 | {% block body %} 3 | foo 4 | {% endblock body %} 5 | -------------------------------------------------------------------------------- /examples/actix-web-demo/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 |

Hello {{ name }}!

3 | 4 | Go to user 1 -------------------------------------------------------------------------------- /examples/actix-web-demo/templates/user.html: -------------------------------------------------------------------------------- 1 | 2 |

User #{{ user_id }}

3 | 4 | back to index -------------------------------------------------------------------------------- /fuzz/seeds/render/call: -------------------------------------------------------------------------------- 1 | {% macro name(a, b) %}{{ a }} | {{ b }} | {{ caller(b) ||{% endmacro %} 2 | {% call(a) name(1, 2) %}...{{ a }}...{% endcall %} 3 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_super_super.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% extends "simple2_layout.txt" %} 4 | {% block title %}[{{ super() }}]{% endblock %} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_block.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% extends "simple_layout.txt" %} 4 | {% block title %}{{ missing_function() }}{% endblock %} 5 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_no_super_block.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% block body %} 4 | There is no super block. 5 | {{ super() }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_strict_undefined_if.txt: -------------------------------------------------------------------------------- 1 | {"$settings": {"undefined": "strict"}} 2 | --- 3 | {% if undefined_value %} 4 | ... 5 | {% endif %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_unexpected_caller_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro no_caller() %}{% endmacro %} 4 | {% call no_caller() %}...{% endcall %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/filter_block.txt: -------------------------------------------------------------------------------- 1 | { 2 | "egg": "Humpty Dumpty sat on a wall" 3 | } 4 | --- 5 | {% filter upper %}{{ egg }}{% endfilter %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/include_choice_none.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | Before 4 | {% include ["missing_template1.txt", "missing_template2.txt"] %} 5 | After 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/include_missing.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "missing_template.txt" 3 | } 4 | --- 5 | Before 6 | {% include template %} 7 | After 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/var_referencing_layout.txt: -------------------------------------------------------------------------------- 1 | {% for item in [1, 2, 3] %} 2 | {% block item_block %}{{ item }}{% endblock %} 3 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/self.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foobar" 3 | } 4 | --- 5 | 1:[{% block title %}{{ var }}{% endblock %}] 6 | 2:({{ self.title() }}) 7 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/trim-blocks.loop.txt: -------------------------------------------------------------------------------- 1 | { 2 | "trim_blocks": true 3 | } 4 | --- 5 | {% for item in seq %} 6 | {{ item }} 7 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/filter.txt: -------------------------------------------------------------------------------- 1 | {{ foo|bar(1, 2)|baz }} 2 | {{ foo|bar(1, 2,) }} 3 | {{ foo|bar(1, 2, a=1) }} 4 | {{ foo|bar(1, 2, a=1,) }} 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "devcontainers" 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | -------------------------------------------------------------------------------- /examples/call-block-function/src/demo.txt: -------------------------------------------------------------------------------- 1 | Before the loop 2 | {%- call(it) custom_loop(5) %} 3 | Iteration {{ it }}! 4 | {%- endcall %} 5 | After the loop -------------------------------------------------------------------------------- /examples/render-macro/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::render; 2 | 3 | fn main() { 4 | println!("{}", render!("Hello {{ name }}!", name => "John")); 5 | } 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_extends_twice.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_layout.txt" 3 | } 4 | --- 5 | {% extends template %} 6 | {% extends template %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_too_large_integer.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ 10234237582375823572357238572385723582375827582375238572385723857238572385723523758 }} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/simple_layout.txt: -------------------------------------------------------------------------------- 1 | {% block title %}default title{% endblock %} 2 | {% block body %}default body{% endblock %} 3 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/attrs.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {# useless comment #} 4 | {{ foo.bar[baz].blah }} 5 | {{ {"foo": "bar"}.test }} 6 | {{ [1, 2, 3].test }} -------------------------------------------------------------------------------- /examples/debug/src/demo.txt: -------------------------------------------------------------------------------- 1 | {%- with func=range %} 2 | {%- for item in func(iterations) %} 3 | {{- debug() -}} 4 | {%- endfor %} 5 | {%- endwith %} 6 | -------------------------------------------------------------------------------- /examples/deserialize/src/example.txt: -------------------------------------------------------------------------------- 1 | Path: {{ path }} 2 | Parent: {{ path|dirname }} 3 | Point as Point: {{ point }} 4 | Point as Tuple: {{ point|point_as_tuple }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_duplicate_macro_arg.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro two_args(a, b) %} 4 | {{ a }} and {{ b }} 5 | {% endmacro %} 6 | {{ two_args(1, a=2) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_too_many_macro_kwargs.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro two_args(a, b) %} 4 | {{ a }} and {{ b }} 5 | {% endmacro %} 6 | {{ two_args(c=42) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop-recursion-error.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [1, 2, 3] 3 | } 4 | --- 5 | {% for item in seq recursive %} 6 | {{ loop(seq) }} 7 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/extends.txt: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block title %}new title{% endblock %} 3 | {% block body %}new body{% endblock %} 4 | -------------------------------------------------------------------------------- /examples/load-lazy/src/template.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_nested_subtraction.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3]} 2 | --- 3 | {% for item in seq %} 4 | {{ ((item + 4) * (3 - [])) + 4 - 2 }} 5 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_strict_undefined_for.txt: -------------------------------------------------------------------------------- 1 | {"$settings": {"undefined": "strict"}} 2 | --- 3 | {% for item in undefined_value %} 4 | ... 5 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_too_many_macro_args.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro two_args(a, b) %} 4 | {{ a }} and {{ b }} 5 | {% endmacro %} 6 | {{ two_args(1, 2, 3) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/include_with_var_and_macro.txt: -------------------------------------------------------------------------------- 1 | {% set title = "The Title" %} 2 | {% macro helper(a, b) %}{{ [a, b, c] }}{% endmacro %} 3 | Should not show up -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/with.txt: -------------------------------------------------------------------------------- 1 | {% with a=foo, b=bar %} 2 | {{ a }}|{{ b }} 3 | {% endwith %} 4 | 5 | {% with a=foo %} 6 | {{ a }} 7 | {% endwith %} 8 | -------------------------------------------------------------------------------- /examples/hello/README.md: -------------------------------------------------------------------------------- 1 | # hello 2 | 3 | A simple example of how to render a single template from a string: 4 | 5 | ```console 6 | $ cargo run 7 | Hello John! 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/render-value/README.md: -------------------------------------------------------------------------------- 1 | # render-value 2 | 3 | An example that shows that a `Value` can be used directly as context. 4 | 5 | ```console 6 | $ cargo run 7 | ``` 8 | -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.j2: -------------------------------------------------------------------------------- 1 | {%- include "./include.txt" %} 2 | {%- for _ in range(count or 1) %} 3 | Hello {{ name }}! 4 | {%- endfor %} 5 | List: {{ list|join("|") }} -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "World", 3 | "count": 3, 4 | "list": [ 5 | "foo", 6 | "bar", 7 | "baz" 8 | ] 9 | } -------------------------------------------------------------------------------- /minijinja/tests/inputs/block.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% block title %}{% endblock %} 6 | {% block body %}{{ var }}{% endblock body %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_scope.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {{ var }} 6 | {% block test %}{% set var = "bar" %}{{ var }}{% endblock %} 7 | {{ var }} 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_too_many_macro_kwargs2.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro two_args(a, b) %} 4 | {{ a }} and {{ b }} 5 | {% endmacro %} 6 | {{ two_args(c=42, d=23) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/extends_set.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "layout_with_var.txt" 3 | } 4 | --- 5 | {% extends template %} 6 | {% set var = "the value from the child" %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/if_cond_else.txt: -------------------------------------------------------------------------------- 1 | { 2 | "value": false 3 | } 4 | --- 5 | {% if value %} 6 | was true 7 | {% else %} 8 | was false 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/import_all.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {% set x = 23 %} 5 | {% import 'import-mixed.txt' as module %} 6 | {{ module|tojson }} 7 | |||{{ module }}||| 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/include_ignore_missing.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "missing_template.txt" 3 | } 4 | --- 5 | Before 6 | {% include template ignore missing %} 7 | After 8 | -------------------------------------------------------------------------------- /examples/deserialize/README.md: -------------------------------------------------------------------------------- 1 | # deserialize 2 | 3 | Demonstrates how you can deserialize MiniJinja values 4 | into other types. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/cmp.txt: -------------------------------------------------------------------------------- 1 | { 2 | "one": 1, 3 | "two": 2, 4 | "three": 3 5 | } 6 | --- 7 | {% if two > one and two < three %} 8 | test 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_in_include.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3], "b": []} 2 | --- 3 | {% for a in seq %} 4 | This fails in the include: {% include "a_plus_b.txt" %} 5 | {% endfor %} -------------------------------------------------------------------------------- /examples/generate-yaml/src/template.yaml: -------------------------------------------------------------------------------- 1 | env: ${{ env }} 2 | title: ${{ title }} 3 | skip: ${{ true }} 4 | run: ${{ ["bash", "./script.sh"] }} 5 | yaml_value: ${{ yaml|safe }} 6 | -------------------------------------------------------------------------------- /examples/line-statements/README.md: -------------------------------------------------------------------------------- 1 | # hello 2 | 3 | A simple example of how to render a single template from a string: 4 | 5 | ```console 6 | $ cargo run 7 | Hello John! 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/path-loader/templates/layout.txt: -------------------------------------------------------------------------------- 1 | ----------------------------------------------- 2 | {% block body %}{% endblock %} 3 | ----------------------------------------------- 4 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/refs/simple_layout_2.txt: -------------------------------------------------------------------------------- 1 | {% extends "simple_layout.txt" %} 2 | I shouldn't appear from here. 3 | {% block fragment %}({{ super() }}){% endblock %} 4 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_strict_undefined_for_filter.txt: -------------------------------------------------------------------------------- 1 | {"$settings": {"undefined": "strict"}} 2 | --- 3 | {% for item in [undefined_value] if item %} 4 | ... 5 | {% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/include_ignore_choice.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_include.txt" 3 | } 4 | --- 5 | Before 6 | {% include ["missing_template.txt", template] %} 7 | After 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_else.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [] 3 | } 4 | --- 5 | {% for item in seq %} 6 | should not happen 7 | {% else %} 8 | else block! 9 | {% endfor %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_include.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {%- include "example_macro.txt" %} 4 | {%- set d = "should never show up" %} 5 | {{ example(1, 2, 3) }} 6 | {{ example(1, 2) }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/refs/bad_basic_block.txt: -------------------------------------------------------------------------------- 1 | {% block title %}default title{% endblock %} 2 | {% block body %} 3 | {{ missing_function() }} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /examples/dynamic-context/src/template.txt: -------------------------------------------------------------------------------- 1 | pid: {{ pid }} 2 | current_dir: {{ cwd }} 3 | env: 4 | {%- for key, value in env|dictsort %} 5 | {{ key }}: {{ value }} 6 | {%- endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_test.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3]} 2 | --- 3 | {% for item in seq %} 4 | {% if item is reallyEven %} 5 | {{ item }} 6 | {% endif %} 7 | {% endfor %} 8 | -------------------------------------------------------------------------------- /examples/inheritance/src/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block title %}{{ page.title|upper }} | {{ super() }}{% endblock %} 3 | {% block body %}{{ page.content }}{% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_scope_extends.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "var_referencing_layout.txt" 3 | } 4 | --- 5 | {% extends template %} 6 | {% block item_block %}[{{ item }}]{% endblock %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_test_arguments.txt: -------------------------------------------------------------------------------- 1 | {"seq": [1, 2, 3]} 2 | --- 3 | {% for item in seq %} 4 | {% if item is even(42) %} 5 | {{ item }} 6 | {% endif %} 7 | {% endfor %} 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_calling_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {%- from "call_macro.txt" import call %} 4 | {%- macro my_macro(value) %}[{{ value }}]{% endmacro %} 5 | {{- call(my_macro, 42) }} -------------------------------------------------------------------------------- /examples/embedding/src/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block title %}{{ page.title|upper }} | {{ super() }}{% endblock %} 3 | {% block body %}{{ page.content }}{% endblock %} -------------------------------------------------------------------------------- /examples/minimal/README.md: -------------------------------------------------------------------------------- 1 | # minimal 2 | 3 | An example using MiniJinja without default features. 4 | 5 | ```console 6 | $ cargo run 7 | 1. Hello John! 8 | 2. Hello Peter! 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/render-template/users.html: -------------------------------------------------------------------------------- 1 | 2 | User List 3 | 8 | -------------------------------------------------------------------------------- /minijinja-cli/examples/alias.yaml: -------------------------------------------------------------------------------- 1 | dict1: &dict1_anchor 2 | key1: value1 3 | 4 | dict2: &dict2_anchor 5 | key2: value2 6 | 7 | dict3: 8 | <<: [*dict1_anchor, *dict2_anchor] 9 | key3: value3 -------------------------------------------------------------------------------- /minijinja/tests/inputs/getattr.txt: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "name": "Peter", 4 | "is_active": true 5 | } 6 | } 7 | --- 8 | name: {{ user.name }} 9 | active: {{ user.is_active }} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/include.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_include.txt" 3 | } 4 | --- 5 | Before 6 | {% with variable=42 %} 7 | {% include template %} 8 | {% endwith %} 9 | After 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/mul.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {{ range(3) * 3 }} 5 | {{ "foo" * 3 }} 6 | {{ [1, 2] * 2 }} 7 | {{ [1, 2, 3, 4][:2] * 2 }} 8 | {{ 2 * [1, 2] }} 9 | {{ 2 * "foo" }} 10 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/call.txt: -------------------------------------------------------------------------------- 1 | {{ super() }} 2 | {{ loop.cycle(1, 2) }} 3 | {{ self.foo() }} 4 | {{ foo(1, 2, a=3, b=4) }} 5 | {{ trailing(1, 2,) }} 6 | {{ trailing_kwarg(1, 2, a=3,) }} 7 | -------------------------------------------------------------------------------- /examples/inheritance/src/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% block title %}some website{% endblock %} 4 | {% block body %}{% endblock %} 5 | 3 | # for item in seq 4 | ## again another comment here. Removed entirely 5 |
  • {{ item }} 6 | # endfor 7 | 8 | -------------------------------------------------------------------------------- /examples/macros/src/macros.html: -------------------------------------------------------------------------------- 1 | {% macro render_input(name, value, type="text") -%} 2 | 3 | {%- endmacro %} 4 | {% set alias = render_input %} -------------------------------------------------------------------------------- /examples/path-loader/README.md: -------------------------------------------------------------------------------- 1 | # path-loader 2 | 3 | Demonstrates the `loader` feature for loading templates from disk with 4 | the `path_loader` function. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/syntax-highlighting/README.md: -------------------------------------------------------------------------------- 1 | # syntax-highlighting 2 | 3 | An example that shows how to register a function for syntax highlighting with syntect. 4 | 5 | ```console 6 | $ cargo run 7 | ``` 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/dict.txt: -------------------------------------------------------------------------------- 1 | { 2 | "d": {"a": 1, "b": 2} 3 | } 4 | --- 5 | {{ dict(d) }} 6 | {{ dict(x=1, y=2) }} 7 | {{ dict(d, c=3)}} 8 | {% for _ in [1] %}{{ dict(loop, extra=2)|dictsort }}{% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/do_closure.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro other_macro() %}23{% endmacro %} 4 | {% macro foo() %}[{% do other_macro() %}]{% endmacro %} 5 | Should not show output of other_macro: {{ foo() }} -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_extends_actually_not.txt: -------------------------------------------------------------------------------- 1 | { 2 | "not_true": false 3 | } 4 | --- 5 | before 6 | {% if not_true %} 7 | {% extends "something.html" %} 8 | {% endif %} 9 | and after 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/extends.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_layout.txt" 3 | } 4 | --- 5 | {% extends template %} 6 | {% block title %}new title{% endblock %} 7 | {% block body %}new body{% endblock %} 8 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/if_cond.txt: -------------------------------------------------------------------------------- 1 | {% if expr1 %} 2 | branch 1 3 | {% elif expr2 %} 4 | branch 2 5 | {% elif expr3 %} 6 | branch 3 7 | {% else %} 8 | else 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /examples/embedding/src/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% block title %}some website{% endblock %} 4 | {% block body %}{% endblock %} 5 | 3 | {%- for item in nav %} 4 |
  • {{ item.title }} 5 | {%- endfor %} 6 | 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | 1, 4 | 2, 5 | 3 6 | ] 7 | } 8 | --- 9 | 14 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/lstrip-blocks-raw.txt: -------------------------------------------------------------------------------- 1 | { 2 | "lstrip_blocks": true, 3 | "trim_blocks": true 4 | } 5 | --- 6 | -------------------------------------------------------------------------------- /minijinja-cli/examples/hello.json5: -------------------------------------------------------------------------------- 1 | /* json5 supports comments */ 2 | { 3 | "name": "World", 4 | "count": 3, 5 | "list": [ 6 | "foo", 7 | "bar", 8 | "baz" 9 | ] 10 | } -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/fragment_simple_extend.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "simple_layout.txt" %} 6 | 7 | {% block fragment %} 8 | This should appear 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.allFeatures": true, 3 | "python.formatting.provider": "black", 4 | "python.REPL.enableREPLSmartSend": false, 5 | "rust-analyzer.check.command": "clippy" 6 | } -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/fragment_ref_parent.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "var_referencing_layout.txt" %} 6 | 7 | {% block item_block %} 8 | [{{ item }}] 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/do_macro_calling_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {%- from "call_macro.txt" import call %} 4 | {%- macro my_macro(value) %}[{{ value }}]{% endmacro %} 5 | nothing should show: {% do call(my_macro, 42) %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/inexpr.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | 1, 4 | 2, 5 | 3 6 | ] 7 | } 8 | --- 9 | {{ 1 in seq }} 10 | {{ "missing" in seq }} 11 | {{ 1 not in seq }} 12 | {{ "missing" not in seq }} 13 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_bad_unpacking.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | 1, 4 | 2, 5 | 3 6 | ] 7 | } 8 | --- 9 | 14 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_controls.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% for item in range(10) -%} 4 | {%- if item is odd %}{% continue %}{% endif %} 5 | {%- if item > 5 %}{% break %}{% endif %} 6 | {{- item }} 7 | {%- endfor %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/string-implicit-concat.txt: -------------------------------------------------------------------------------- 1 | {{ "foo" }} 2 | {{ "foo" "bar" }} 3 | {{ "foo" "bar" "baz" }} 4 | {{ "foo" "\u2603bar" "baz" }} 5 | {{ "foo\u2603bar" "baz" }} 6 | {{ "foo\nbar" "bar\nbaz" }} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_super.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_layout.txt" 3 | } 4 | --- 5 | {% extends template %} 6 | {% block title %}[{{ super() }}]{% endblock %} 7 | {% block body %}{{ super()|upper }}{% endblock %} 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/err_bad_super.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% extends "bad_basic_block.txt" %} 4 | {% block title %}My Title{% endblock %} 5 | {% block body %} 6 | Changed stuff goes here. {{ super() }} 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/escape.txt: -------------------------------------------------------------------------------- 1 | { 2 | "x": "hello" 3 | } 4 | --- 5 | {{'\'' ~ 'foo'}} 6 | {{'\'' ~ x ~ '\''}} 7 | {{"\'" ~ x ~ '\''}} 8 | {{"\'" ~ x ~ '\''}} 9 | {{" 10 | hello world"}} 11 | {{"hello 12 | world"}} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/lstrip-blocks-comment.txt: -------------------------------------------------------------------------------- 1 | { 2 | "lstrip_blocks": true, 3 | "trim_blocks": true 4 | } 5 | --- 6 | -------------------------------------------------------------------------------- /examples/object-using-async/README.md: -------------------------------------------------------------------------------- 1 | # object-using-async 2 | 3 | Shows how a tokio handle's `block_on` method can be used to wait for async 4 | operations from within a template. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /fuzz/fuzz_targets/add_template.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | use libfuzzer_sys::fuzz_target; 3 | 4 | fuzz_target!(|input: &str| { 5 | minijinja::Environment::new() 6 | .add_template("fuzz.txt", input) 7 | .ok(); 8 | }); 9 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/call.txt: -------------------------------------------------------------------------------- 1 | { 2 | "upper": 10 3 | } 4 | --- 5 | {% with f = range %}{% for x in f(upper) %}[{{ x }}]{% endfor %}{% endwith %} 6 | {% for k, v in dict(a=1, b=2, c=3)|dictsort %}[{{ k }}:{{ v }}]{% endfor %} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/do_macro.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro dialog(title) %}Dialog is {{ title }}{% endmacro %} 4 | 5 | Should be empty: {% do dialog(title="Hello World") %} 6 | Should show: {{ dialog(title="Hello World") }} 7 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_else2.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | 1, 4 | 2, 5 | 3 6 | ] 7 | } 8 | --- 9 | {%- for item in seq %} 10 | - {{ item }} 11 | {%- else %} 12 | should not happen 13 | {%- endfor %} 14 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_kwargs.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro foo(a, b, c, d) %}{{ [a, b, c, d] }}{% endmacro -%} 4 | {{ foo(1, 2, 3) }} 5 | {{ foo({"blub": "blah"}) }} 6 | {{ foo(a=1, b=2, c=3) }} 7 | {{ foo(a=1, b=2, c=3, d=4) }} -------------------------------------------------------------------------------- /scripts/wasmtime-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | cd $SCRIPT_DIR/.. 4 | wasmtime run --max-wasm-stack=4194304 --env INSTA_WORKSPACE_ROOT=/ --mapdir "/::$(pwd)" -- "$@" 5 | -------------------------------------------------------------------------------- /examples/object-ref/README.md: -------------------------------------------------------------------------------- 1 | # object-ref 2 | 3 | An example that shows how to use MiniJinja's object system to efficiently 4 | to pass complex dynamic values without cloning to templates. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@list.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ [1, 2, 3]|length }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/list.txt 6 | --- 7 | 3 8 | 9 | -------------------------------------------------------------------------------- /examples/custom-error/README.md: -------------------------------------------------------------------------------- 1 | # custom-error 2 | 3 | This example demonstrates how custom errors can be emitted in templates and 4 | then detected later to customize the rendering of errors. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/render-macro/README.md: -------------------------------------------------------------------------------- 1 | # render-macro 2 | 3 | A simple example of how to render a single template from a string and render it 4 | with the `render!` macro. 5 | 6 | ```console 7 | $ cargo run 8 | Hello John! 9 | ``` 10 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/fragment_simple.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% block title %}Shouldn't show up{% endblock %} 6 | {% block fragment %}{{ var }}{% endblock fragment %} 7 | Also shouldn't show up 8 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_super.html: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "super_with_html.html" %} 6 | {% block body %} 7 |

    New Content

    8 | {{ super() }} 9 | {{ super()|upper }} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_import.txt: -------------------------------------------------------------------------------- 1 | {"c": "The C Variable"} 2 | --- 3 | {% from "include_with_var_and_macro.txt" import title, helper, missing -%} 4 | missing: {{ missing }} 5 | title: {{ title }} 6 | helper: {{ helper("a", "b") }} 7 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@map.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ {\"foo\":\"bar\"}.foo }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/map.txt 6 | --- 7 | bar 8 | 9 | -------------------------------------------------------------------------------- /minijinja-js/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: install build test 4 | 5 | .PHONY: install 6 | install: 7 | npm install 8 | 9 | .PHONY: build 10 | build: 11 | npm run build 12 | 13 | .PHONY: test 14 | test: build 15 | npm test 16 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/block_scope_super.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "var_setting_layout.txt" %} 6 | {% block test %}before: {% set var = "from self" %}{{ var }} 7 | {{ super() }} 8 | after: {{ var }}{% endblock %} 9 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/if_cond_elif.txt: -------------------------------------------------------------------------------- 1 | { 2 | "value": false, 3 | "other_value": false 4 | } 5 | --- 6 | {% if value %} 7 | first branch 8 | {% elif other_value %} 9 | second branch 10 | {% else %} 11 | else 12 | {% endif %} 13 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/fragment_super.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "simple_layout.txt" %} 6 | 7 | {% block fragment %} 8 | This should appear 9 | {{ super() }} 10 | {{ super()|upper }} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/refs/simple_layout.txt: -------------------------------------------------------------------------------- 1 | Shouldn't show up 2 | {% block fragment %} 3 | From parent 4 | {% endblock %} 5 | Also shouldn't show up 6 | 7 | {% block other %} 8 | This too shouldn't appear 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/ifexpr.txt: -------------------------------------------------------------------------------- 1 | { 2 | "something_true": true 3 | } 4 | --- 5 | {{ 42 if something_true else 23 }} 6 | {{ 42 if not something_true else 23 }} 7 | {{ 42 if not something_true }} 8 | {{ (42 if not something_true) is undefined }} 9 | -------------------------------------------------------------------------------- /examples/embedding/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // we only need to bundle the templates with the 3 | // feature is enabled. 4 | #[cfg(feature = "bundled")] 5 | { 6 | minijinja_embed::embed_templates!("src/templates"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/function-using-async/README.md: -------------------------------------------------------------------------------- 1 | # function-using-async 2 | 3 | Shows how a tokio handle's `block_on` method can be used to wait for async 4 | operations from within a template in a callback function. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@float_div_by_zero.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ 10.0 / 0.0 }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/float_div_by_zero.txt 6 | --- 7 | inf 8 | 9 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/fragment_super_super.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": "foo" 3 | } 4 | --- 5 | {% extends "simple_layout_2.txt" %} 6 | 7 | {% block fragment %} 8 | This should appear 9 | {{ super() }} 10 | {{ super()|upper }} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_extends.txt: -------------------------------------------------------------------------------- 1 | { 2 | "template": "simple_layout.txt" 3 | } 4 | --- 5 | {%- extends template %} 6 | {%- macro foo() %}inside foo{% endmacro %} 7 | {%- block title %}{{ foo() }}{% endblock %} 8 | {%- block body %}new body{% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/macros.txt: -------------------------------------------------------------------------------- 1 | {% macro foo() %}...{% endmacro %} 2 | {% macro foo(a, b) %}...{% endmacro %} 3 | {% macro foo(a, b=42) %}...{% endmacro %} 4 | {% macro foo(a, b,) %}...{% endmacro %} 5 | {% macro foo(a, b=42,) %}...{% endmacro %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/set.txt: -------------------------------------------------------------------------------- 1 | {% set variable = value %} 2 | {% set (a, b) = (1, 2) %} 3 | {% set variable2 %} 4 | this is the {{ body }} 5 | {% endset %} 6 | {% set variable3 | upper %} 7 | this is the {{ body }} with filter 8 | {% endset %} 9 | -------------------------------------------------------------------------------- /examples/inheritance/README.md: -------------------------------------------------------------------------------- 1 | # inheritance 2 | 3 | This is a simple example of how to use template inheritance. This example uses 4 | serde-derive for a custom context and includes the template source at runtime. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/load-lazy/src/nav.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "href": "/", 4 | "title": "Index" 5 | }, 6 | { 7 | "href": "/downloads", 8 | "title": "Downloads" 9 | }, 10 | { 11 | "href": "/contact", 12 | "title": "Contact" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /examples/object-ref/src/template.txt: -------------------------------------------------------------------------------- 1 | version: {{ config.version }} 2 | nested: {{ config.nested }} 3 | cwd: {{ utils.get_cwd() }} 4 | {%- for item in items %} 5 | - {{ item }} 6 | {%- endfor %} 7 | 8 | string out: 9 | | {{ items }} 10 | | {{ config }} 11 | -------------------------------------------------------------------------------- /minijinja/src/compiler/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(missing_docs)] 2 | /// This module contains the internals of the compiler. 3 | pub mod ast; 4 | pub mod codegen; 5 | pub mod instructions; 6 | pub mod lexer; 7 | pub mod meta; 8 | pub mod parser; 9 | pub mod tokens; 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_import2.txt: -------------------------------------------------------------------------------- 1 | {"c": "The C Variable"} 2 | --- 3 | {% import "include_with_var_and_macro.txt" as helpers -%} 4 | {{ dict(helpers) }} 5 | missing: {{ helpers.missing }} 6 | title: {{ helpers.title }} 7 | helper: {{ helpers.helper("a", "b") }} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@hello.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "Hello {{ name }}!" 4 | info: 5 | name: World 6 | input_file: minijinja/tests/inputs/hello.txt 7 | --- 8 | Hello World! 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@undefined.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ none }}\n{{ undefined }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/undefined.txt 6 | --- 7 | none 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/build-script/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "build-script" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [build-dependencies] 8 | minijinja = { path = "../../minijinja", default-features = false, features = ["serde", "builtins"] } 9 | -------------------------------------------------------------------------------- /examples/load-resource/src/nav.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "href": "/", 4 | "title": "Index" 5 | }, 6 | { 7 | "href": "/downloads", 8 | "title": "Downloads" 9 | }, 10 | { 11 | "href": "/contact", 12 | "title": "Contact" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /examples/none-as-undefined/README.md: -------------------------------------------------------------------------------- 1 | # none-as-undefined 2 | 3 | This example shows how MiniJinja can be reconfigured to 4 | treat `None` like `undefined` when printing or handling 5 | with the `default` filter. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_break_one_shot_iter.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | normal iteration does not lose items: 4 | {% for item in one_shot_iterator %}{{ item }}{% if item == 1 %}{% break %}{% endif %}{% endfor %} 5 | {%- for item in one_shot_iterator %}{{ item }}{% endfor %} 6 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@concat.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ a ~ b }}\n{{ a + b }}\n{{ a[0] + a[1:] }}" 4 | info: 5 | a: foo 6 | b: bar 7 | --- 8 | foobar 9 | foobar 10 | foo 11 | 12 | -------------------------------------------------------------------------------- /examples/eval-to-state/src/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% macro utility() %}Global var is {{ global_variable}}{% endmacro %} 3 | {% block title %}Index{% endblock %} 4 | {% block body %} 5 | Hello from index.html 6 | {{ utility() }} 7 | {% endblock %} -------------------------------------------------------------------------------- /minijinja/tests/inputs/debug.txt: -------------------------------------------------------------------------------- 1 | { 2 | "upper": 1 3 | } 4 | --- 5 | {% with f = range %}{% for x in f(upper) %}{{ debug() }}{% endfor %}{% endwith %} 6 | --- 7 | {{ debug(none) }} 8 | --- 9 | {{ debug(true, false, 42) }} 10 | --- 11 | {{ debug([debug, 42]) }} 12 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/raw.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | before {% raw %} this is a {{ raw }} {% block %} {% endraw %} after 4 | 5 | before {%- raw %} this is a {{ raw }} {% block %} {% endraw -%} after 6 | 7 | before {%- raw -%} this is a {{ raw }} {% block %} {%- endraw -%} after -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@filter.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ value|upper }}" 4 | info: 5 | value: foo bar baz 6 | input_file: minijinja/tests/inputs/filter.txt 7 | --- 8 | FOO BAR BAZ 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_over_undefined.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "[{% for item in seq %}{% endfor %}]" 4 | info: {} 5 | input_file: minijinja/tests/inputs/loop_over_undefined.txt 6 | --- 7 | [] 8 | 9 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_basic.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro add(a, b) %}{{ a }}|{{ b }}{% endmacro -%} 4 | {{ add(1, 2) }} 5 | {{ add(a=1, b=2) }} 6 | {{ add(b=2, a=1) }} 7 | {{ add(1, b=2) }} 8 | {{ add.name }} 9 | {{ add.arguments }} 10 | {{ add.caller }} 11 | {{ add }} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@or.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ 42 or 23 }}\n{{ 0 or 23 }}\n{{ none or 23 }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/or.txt 6 | --- 7 | 42 8 | 23 9 | 23 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@single_brace.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "{foo} foo {bar}" 4 | input_file: minijinja/tests/lexer-inputs/single_brace.txt 5 | --- 6 | TemplateData("{foo} foo {bar}") 7 | "{foo} foo {bar}" 8 | 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_over_none.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "[{% for item in seq %}{% endfor %}]" 4 | info: 5 | seq: ~ 6 | input_file: minijinja/tests/inputs/loop_over_none.txt 7 | --- 8 | [] 9 | 10 | -------------------------------------------------------------------------------- /examples/invalid-value/README.md: -------------------------------------------------------------------------------- 1 | # invalid-value 2 | 3 | Demonstrates the behavior of the engine with regards to invalid values. Invalid 4 | values are values that crate a serde error during conversion. MiniJinja will 5 | defer that error until the value is interacted with at runtime. 6 | -------------------------------------------------------------------------------- /minijinja-cabi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "minijinja-cabi" 3 | version = "2.14.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | minijinja = { version = "2.14.0", path = "../minijinja", features = ["loader", "custom_syntax"] } 11 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/getitem.txt: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | "first_item", 4 | "middle_item", 5 | "last_item" 6 | ], 7 | "user": { 8 | "name": "Peter" 9 | } 10 | } 11 | --- 12 | first: {{ items[0] }} 13 | last: {{ items[-1] }} 14 | name: {{ user["name"] }} 15 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@escaping.html.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "

    {{ unsafe }}

    " 4 | info: 5 | unsafe: "" 6 | input_file: minijinja/tests/inputs/escaping.html 7 | --- 8 |

    <foo>

    9 | 10 | -------------------------------------------------------------------------------- /examples/actix-web-demo/README.md: -------------------------------------------------------------------------------- 1 | # actix-web-demo 2 | 3 | A simple example that shows how to use MiniJinja with actix-web and 4 | how the request object can be accessed in the context of a template 5 | (for instance to generate URLs.). 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/build-script/src/main.rs: -------------------------------------------------------------------------------- 1 | // include the generated file 2 | include!(concat!(env!("OUT_DIR"), "/example.rs")); 3 | 4 | fn main() { 5 | println!("build cwd: {BUILD_CWD}"); 6 | for point in POINTS { 7 | println!("({}, {})", point.x, point.y); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@keep-trailing-newlines.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: Hello World! 4 | input_file: minijinja/tests/lexer-inputs/keep-trailing-newlines.txt 5 | --- 6 | TemplateData("Hello World!\n") 7 | "Hello World!\n" 8 | 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@if_cond.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% if value %}\n was true\n{% endif %}" 4 | info: 5 | value: 42 6 | input_file: minijinja/tests/inputs/if_cond.txt 7 | --- 8 | 9 | was true 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/call-block-function/README.md: -------------------------------------------------------------------------------- 1 | # call-block-function 2 | 3 | An example that shows how the `{% call %}` block tag can be used 4 | with a custom function. It implements a custom loop function 5 | that invokes a call block multiple times. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/debug/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "debug" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/error/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "error" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/hello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/filters/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "filters" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "macros" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_break_one_shot_iter_peek.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | peeking loses items: 4 | {% for item in one_shot_iterator %}{{ item }}(next: {{ loop.nextitem }}){% if item == 0 %}{% break %}{% endif %}{% endfor %} 5 | {%- for item in one_shot_iterator %}{{ item }}(next: {{ loop.nextitem }}){% endfor %} -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/include.txt: -------------------------------------------------------------------------------- 1 | {% include "foo.txt" %} 2 | {% include "foo.txt" with context %} 3 | {% include "foo.txt" without context %} 4 | {% include "foo.txt" ignore missing with context %} 5 | {% include "foo.txt" ignore missing without context %} 6 | {% include "foo.txt" ignore missing %} 7 | -------------------------------------------------------------------------------- /examples/eval-to-state/README.md: -------------------------------------------------------------------------------- 1 | # eval-to-state 2 | 3 | An example that shows how to use `eval_to_state` and the resulting `State` 4 | object. Together these APIs can be used to render single blocks, invoke macros, 5 | access exports of a template and more. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/object-ref/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "object-ref" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/streaming/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "streaming" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/syntax-highlighting/src/example.html: -------------------------------------------------------------------------------- 1 | 2 | Syntax Highlight Example 3 |

    Syntax Highlight Example

    4 | {% set SYNTAX_THEME = "base16-ocean.light" %} 5 | {% call highlight('rust') %} 6 | fn main() { 7 | println!("Hello World!"); 8 | } 9 | {% endcall %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/lstrip-blocks.txt: -------------------------------------------------------------------------------- 1 | { 2 | "lstrip_blocks": true, 3 | "trim_blocks": true 4 | } 5 | --- 6 |
      7 | {% for item in seq %} 8 |
    • {{ item }}
    • 9 | {% endfor %} 10 |
    11 | 12 |
      13 | {% for item in seq %} 14 | {{ item }} 15 | {% endfor %} 16 |
    -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_compiler__const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_compiler.rs 3 | expression: "&c.finish()" 4 | --- 5 | ( 6 | [ 7 | 00000 | LoadConst("a") [line 0], 8 | 00001 | LoadConst(42), 9 | 00002 | StringConcat, 10 | ], 11 | {}, 12 | ) 13 | -------------------------------------------------------------------------------- /examples/custom-error/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "custom-error" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/dsl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dsl" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { version = "2.14.0", path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/render-macro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "render-macro" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/render-value/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "render-value" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/state-temps/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "state-temps" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/math.txt: -------------------------------------------------------------------------------- 1 | { 2 | "var": 5 3 | } 4 | --- 5 | should be -2.5: {{ 1.5 * 2.5 * 2 / 3 - var }} 6 | should be -3.0: {{ 1.5 * 2.5 * 2 // 3 - var }} 7 | should be 2.0: {{ 4 / 2 }} 8 | should be 2: {{ 4 // 2 }} 9 | should be 0: {{ 1 - 1 }} 10 | should be 0: {{1-1}} 11 | should be -1: {{ -1 }} 12 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/max-recursion.txt: -------------------------------------------------------------------------------- 1 | {{ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] }} -------------------------------------------------------------------------------- /examples/dynamic-context/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dynamic-context" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/dynamic-objects/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dynamic-objects" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/merge-context/README.md: -------------------------------------------------------------------------------- 1 | # merge-context 2 | 3 | This example shows how `context!` can also be used to merge extra variables 4 | into a context. In this example some per-render global variables are injected to influence how the `datetimeformat` filter formats dates. 5 | 6 | ```console 7 | $ cargo run 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/undefined-tracking/README.md: -------------------------------------------------------------------------------- 1 | # undefined-tracking 2 | 3 | Demonstrates how dynamic objects can be used to track undefined values. 4 | This is the inverse of the `value-tracking` example. It prints out a list 5 | of all undefined variables after rendering. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/value-tracking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "value-tracking" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/expr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "expr" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde_json = "1.0.68" 12 | -------------------------------------------------------------------------------- /examples/function-using-async/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "function-using-async" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [dependencies] 8 | minijinja = { version = "2.14.0", path = "../../minijinja" } 9 | tokio = { version = "1.30.0", features = ["macros", "rt", "rt-multi-thread"] } 10 | -------------------------------------------------------------------------------- /examples/object-using-async/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "object-using-async" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [dependencies] 8 | minijinja = { version = "2.14.0", path = "../../minijinja" } 9 | tokio = { version = "1.37.0", features = ["macros", "rt", "rt-multi-thread"] } 10 | -------------------------------------------------------------------------------- /examples/state-temps/README.md: -------------------------------------------------------------------------------- 1 | # state-temps 2 | 3 | This example demonstrates how temps can be utilized for hidden state. This 4 | example uses the state to cache dynamically loaded translations between 5 | repeated calls during rendering. 6 | 7 | ```console 8 | $ LANG=de cargo run 9 | $ LANG=en cargo run 10 | ``` 11 | -------------------------------------------------------------------------------- /examples/undefined-tracking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "undefined-tracking" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/adding.txt: -------------------------------------------------------------------------------- 1 | { 2 | "name": "World" 3 | } 4 | --- 5 | Strings: 6 | {{ 'to' + name + 'you' }}! 7 | {{ 'to' + 'you' }}! 8 | 9 | Sequences: 10 | {{ [1] + [2] }} 11 | {{ [1, 2, 3][:2] + [4, 5] }} 12 | 13 | Adding: 14 | {{ 1 + 2 }} 15 | 16 | Minus: 17 | {{ 2 - 1 }} 18 | 19 | Divide: 20 | {{ 100 / 2 }} -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/lstrip-blocks-preserve.txt: -------------------------------------------------------------------------------- 1 | { 2 | "lstrip_blocks": true, 3 | "trim_blocks": true 4 | } 5 | --- 6 |
      7 | {%+ for item in seq +%} 8 |
    • {{ item }}
    • 9 | {%+ endfor +%} 10 |
    11 | 12 |
      13 | {%+ for item in seq +%} 14 | {{ item }} 15 | {%+ endfor +%} 16 |
    -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@cmp.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% if two > one and two < three %}\n test\n{% endif %}" 4 | info: 5 | one: 1 6 | three: 3 7 | two: 2 8 | input_file: minijinja/tests/inputs/cmp.txt 9 | --- 10 | 11 | test 12 | 13 | 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@filter_block.html.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% filter escape %}

    {{ value }}

    {% endfilter %}" 4 | info: 5 | value: foo < bar 6 | input_file: minijinja/tests/inputs/filter_block.html 7 | --- 8 |

    foo < bar

    9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@self.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "1:[{% block title %}{{ var }}{% endblock %}]\n2:({{ self.title() }})" 4 | info: 5 | var: foobar 6 | input_file: minijinja/tests/inputs/self.txt 7 | --- 8 | 1:[foobar] 9 | 2:(foobar) 10 | 11 | -------------------------------------------------------------------------------- /examples/call-block-function/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "call-block-function" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/custom-loader/README.md: -------------------------------------------------------------------------------- 1 | # custom-loader 2 | 3 | This example demonstrates how templates can be loaded at runtime from 4 | the file system (in this case from the `templates` folder) with a manual 5 | loader implementation. 6 | 7 | ```console 8 | $ cargo run 9 | header 10 | Hello World! 11 | footer 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /examples/streaming/README.md: -------------------------------------------------------------------------------- 1 | # streaming 2 | 3 | This is an example that demonstrates how a one-shot iterator can be used 4 | to stream a template as data comes in. You could imagine that this includes 5 | the response of a very slow LLM or some pub-sub system pushing up items. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/indexing.txt: -------------------------------------------------------------------------------- 1 | { 2 | "hello": "Hällo Wörld", 3 | "intrange": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 4 | } 5 | --- 6 | {{ hello[0] }} 7 | {{ hello[3] }} 8 | {{ hello[-1] }} 9 | {{ hello[999] is undefined }} 10 | {{ intrange[0] }} 11 | {{ intrange[3] }} 12 | {{ intrange[-1] }} 13 | {{ intrange[999] is undefined }} -------------------------------------------------------------------------------- /examples/eval-to-state/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eval-to-state" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { version = "2.14.0", path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/load-lazy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "load-lazy" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde_json = "1.0.87" 12 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/autoescape.html: -------------------------------------------------------------------------------- 1 | { 2 | "unsafe": "" 3 | } 4 | --- 5 | {{ unsafe }} 6 | {% autoescape true %}{{ unsafe }}{% endautoescape %} 7 | {% autoescape false %}{{ unsafe }}{% endautoescape %} 8 | {% autoescape "html" %}{{ unsafe }}{% endautoescape %} 9 | {% autoescape "none" %}{{ unsafe }}{% endautoescape %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/autoescape.txt: -------------------------------------------------------------------------------- 1 | { 2 | "unsafe": "" 3 | } 4 | --- 5 | {{ unsafe }} 6 | {% autoescape true %}{{ unsafe }}{% endautoescape %} 7 | {% autoescape false %}{{ unsafe }}{% endautoescape %} 8 | {% autoescape "html" %}{{ unsafe }}{% endautoescape %} 9 | {% autoescape "none" %}{{ unsafe }}{% endautoescape %} 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@filter_block.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% filter upper %}{{ egg }}{% endfilter %}" 4 | info: 5 | egg: Humpty Dumpty sat on a wall 6 | input_file: minijinja/tests/inputs/filter_block.txt 7 | --- 8 | HUMPTY DUMPTY SAT ON A WALL 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@if_cond_else.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% if value %}\n was true\n{% else %}\n was false\n{% endif %}" 4 | info: 5 | value: false 6 | input_file: minijinja/tests/inputs/if_cond_else.txt 7 | --- 8 | 9 | was false 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/custom-loader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "custom-loader" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["loader"] } 11 | -------------------------------------------------------------------------------- /examples/self-referential-context/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "self-referential-context" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | -------------------------------------------------------------------------------- /examples/load-resource/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "load-resource" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde_json = "1.0.87" 12 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_filter.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | 1, 4 | 2, 5 | 3, 6 | 4, 7 | 5, 8 | 6, 9 | 7, 10 | 8, 11 | 9, 12 | 10 13 | ] 14 | } 15 | --- 16 | {%- for item in seq if item is even and loop is undefined %} 17 | - {{ item }} ({{ loop.index }} / {{ loop.length }}) 18 | {%- endfor %} 19 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% block title %}{% endblock %}\n{% block body %}{{ var }}{% endblock body %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/inputs/block.txt 7 | --- 8 | 9 | foo 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_scope.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ var }}\n{% block test %}{% set var = \"bar\" %}{{ var }}{% endblock %}\n{{ var }}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/inputs/block_scope.txt 7 | --- 8 | foo 9 | bar 10 | foo 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_else.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% for item in seq %}\n should not happen\n{% else %}\n else block!\n{% endfor %}" 4 | info: 5 | seq: [] 6 | input_file: minijinja/tests/inputs/loop_else.txt 7 | --- 8 | 9 | else block! 10 | 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_over_string.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% for char in \"abcdefg\" -%}\n {{ char }}\n{% endfor %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/loop_over_string.txt 6 | --- 7 | a 8 | b 9 | c 10 | d 11 | e 12 | f 13 | g 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/line-statements/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "line-statements" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["custom_syntax"] } 11 | -------------------------------------------------------------------------------- /minijinja/tests/fragment-inputs/refs/var_referencing_layout.txt: -------------------------------------------------------------------------------- 1 | Shouldn't show up 2 | {% block fragment %} 3 | {% for item in [1, 2, 3] %} 4 | {% block item_block %}{{ item }}{% endblock %} 5 | {% endfor %} 6 | {% endblock %} 7 | Also shouldn't show up 8 | 9 | {% block other %} 10 | This too shouldn't appear 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/line-comment.txt: -------------------------------------------------------------------------------- 1 | { 2 | "line_statement_prefix": "#", 3 | "line_comment_prefix": "##" 4 | } 5 | --- 6 | ## this is a comment 7 | ## that shall disappear entirely 8 |
      9 | # for item in seq 10 |
    • {{ item }}
    • ## this is another line comment 11 | 12 | # endfor 13 |
    14 | ## trailing comment -------------------------------------------------------------------------------- /scripts/publish-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | cd $SCRIPT_DIR/.. 6 | 7 | cargo publish -p minijinja 8 | cargo publish -p minijinja-autoreload 9 | cargo publish -p minijinja-embed 10 | cargo publish -p minijinja-contrib 11 | cargo publish -p minijinja-cli 12 | -------------------------------------------------------------------------------- /examples/generate-yaml/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "generate-yaml" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["json", "custom_syntax"] } 11 | -------------------------------------------------------------------------------- /examples/hello/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment}; 2 | 3 | fn main() { 4 | let mut env = Environment::new(); 5 | 6 | env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); 7 | let template = env.get_template("hello.txt").unwrap(); 8 | println!("{}", template.render(context!(name => "John")).unwrap()); 9 | } 10 | -------------------------------------------------------------------------------- /examples/minimal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "minimal" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["serde"], default-features = false } 11 | -------------------------------------------------------------------------------- /examples/render-template/README.md: -------------------------------------------------------------------------------- 1 | # render-template 2 | 3 | This demonstrates how MiniJinja can load a single template and JSON file from disk to 4 | render a template. 5 | 6 | ```console 7 | $ cargo run -- -c users.json -t users.html 8 | 9 | User List 10 |
      11 |
    • 1: Peter 12 |
    • 2: John 13 |
    14 | ``` -------------------------------------------------------------------------------- /minijinja/tests/inputs/literals.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ true }} 4 | {{ false }} 5 | {{ null }} 6 | {{ 1.0 }} 7 | {{ 2 }} 8 | {{ [1, 2, 3] }} 9 | {{ {"foo": "bar"} }} 10 | {{ -9223372036854775808 }} 11 | {{ -170141183460469231731687303715884105728 }} 12 | {{ 170141183460469231731687303715884105727 }} 13 | {{ 340282366920938463463374607431768211455 }} 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@extends_set.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends template %}\n{% set var = \"the value from the child\" %}" 4 | info: 5 | template: layout_with_var.txt 6 | input_file: minijinja/tests/inputs/extends_set.txt 7 | --- 8 | the value from the child 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@getattr.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "name: {{ user.name }}\nactive: {{ user.is_active }}" 4 | info: 5 | user: 6 | is_active: true 7 | name: Peter 8 | input_file: minijinja/tests/inputs/getattr.txt 9 | --- 10 | name: Peter 11 | active: true 12 | 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@import_all.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% set x = 23 %}\n{% import 'import-mixed.txt' as module %}\n{{ module|tojson }}\n|||{{ module }}|||" 4 | info: {} 5 | input_file: minijinja/tests/inputs/import_all.txt 6 | --- 7 | {"output":42} 8 | |||This is the body 23||| 9 | -------------------------------------------------------------------------------- /examples/path-loader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "path-loader" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["loader"] } 11 | once_cell = "1.13.1" 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@include_ignore_missing.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "Before\n{% include template ignore missing %}\nAfter" 4 | info: 5 | template: missing_template.txt 6 | input_file: minijinja/tests/inputs/include_ignore_missing.txt 7 | --- 8 | Before 9 | 10 | After 11 | 12 | -------------------------------------------------------------------------------- /examples/actix-web-demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actix-web-demo" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | actix-web = "4.9.0" 11 | minijinja = { path = "../../minijinja", features = ["loader"] } 12 | -------------------------------------------------------------------------------- /examples/value-tracking/README.md: -------------------------------------------------------------------------------- 1 | # value-tracking 2 | 3 | Demonstrates how dynamic objects can be used to track resolved values 4 | from the context at runtime. After rendering the template, a hash set 5 | is filled with all the variables that were looked up from the context 6 | or the environment globals. 7 | 8 | ```console 9 | $ cargo run 10 | ``` 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_calling_macro.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- from \"call_macro.txt\" import call %}\n{%- macro my_macro(value) %}[{{ value }}]{% endmacro %}\n{{- call(my_macro, 42) }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_calling_macro.txt 6 | --- 7 | [42] 8 | 9 | -------------------------------------------------------------------------------- /examples/dynamic-context/README.md: -------------------------------------------------------------------------------- 1 | # dynamic-context 2 | 3 | This example shows how a dynamic `Object` can be used as context so that 4 | values are looked up as values are referenced by the template. 5 | 6 | Also see [load-lazy](../load-lazy) for an example where a 7 | single value's attributes are lazy loaded. 8 | 9 | ```console 10 | $ cargo run 11 | ``` 12 | -------------------------------------------------------------------------------- /examples/render-template/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "render-template" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | argh = "0.1.6" 11 | minijinja = { path = "../../minijinja" } 12 | serde_json = "1.0.68" 13 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/functions.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | short-range: {{ range(10) }} 4 | range-is-iterable: {{ range(10) is iterable }} 5 | range-is-not-a-sequence: {{ range(10) is not sequence }} 6 | negative-range: {{ range(-5, 5) }} 7 | negative-start: {{ range(-3, 3, 2) }} 8 | negative-step: {{ range(5, -5, -2) }} 9 | negative-step-off: {{ range(5, -4, -2) }} 10 | -------------------------------------------------------------------------------- /_typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = ["minijinja-contrib/src/html_entities.rs"] 3 | 4 | [default] 5 | extend-ignore-identifiers-re = ["workd", "entit", "FoO", "mis", "flate"] 6 | 7 | [default.extend-words] 8 | # these are false positives in data/examples 9 | ridiculus = "ridiculus" 10 | facilisi = "facilisi" 11 | Facilisi = "Facilisi" 12 | nam = "nam" 13 | -------------------------------------------------------------------------------- /examples/deserialize/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "deserialize" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde = { version = "1.0.159", features = ["derive"] } 12 | -------------------------------------------------------------------------------- /examples/invalid-value/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "invalid-value" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde = { version = "1.0.159", features = ["derive"] } 12 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/max-recursion-expr.txt: -------------------------------------------------------------------------------- 1 | {{ (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( 52 + 23 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) }} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_super_super.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"simple2_layout.txt\" %}\n{% block title %}[{{ super() }}]{% endblock %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/block_super_super.txt 6 | --- 7 | [(default title)] 8 | default body 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_controls.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% for item in range(10) -%}\n {%- if item is odd %}{% continue %}{% endif %}\n {%- if item > 5 %}{% break %}{% endif %}\n {{- item }}\n{%- endfor %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/loop_controls.txt 6 | --- 7 | 024 8 | -------------------------------------------------------------------------------- /minijinja-cabi/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | #![allow(missing_debug_implementations)] 3 | #![allow(unreachable_pub)] 4 | #![allow(clippy::missing_safety_doc)] 5 | 6 | #[macro_use] 7 | mod macros; 8 | mod utils; 9 | 10 | mod env; 11 | mod error; 12 | mod value; 13 | 14 | pub use self::env::*; 15 | pub use self::error::*; 16 | pub use self::value::*; 17 | -------------------------------------------------------------------------------- /minijinja-cli/src/main.rs: -------------------------------------------------------------------------------- 1 | mod cli; 2 | mod command; 3 | mod config; 4 | mod output; 5 | #[cfg(feature = "repl")] 6 | mod repl; 7 | 8 | fn main() { 9 | match cli::execute() { 10 | Ok(code) => std::process::exit(code), 11 | Err(err) => { 12 | cli::print_error(&err); 13 | std::process::exit(1); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/autoreload/README.md: -------------------------------------------------------------------------------- 1 | # autoreload 2 | 3 | An example that shows how to use [`minijinja-autoreload`](https://docs.rs/minijinja-autoreload) 4 | to simplify using auto reloading with MiniJinja. While the example is running you can edit 5 | the templates in the [templates](templates) folder to see them change in real time. 6 | 7 | ```console 8 | $ cargo run 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/none-as-undefined/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "none-as-undefined" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde = { version = "1.0.130", features = ["derive"] } 12 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_bad_unpacking_wrong_len.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | [ 4 | 1, 5 | 2, 6 | 3 7 | ], 8 | [ 9 | 2, 10 | 3, 11 | 4 12 | ], 13 | [ 14 | 3, 15 | 4, 16 | 5 17 | ] 18 | ] 19 | } 20 | --- 21 |
      22 | {% for a, b in seq %} 23 |
    • {{ a }}: {{ b }} 24 | {% endfor %} 25 |
    26 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_unpacking.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | [ 4 | "+", 5 | [ 6 | 1, 7 | 2 8 | ] 9 | ], 10 | [ 11 | "-", 12 | [ 13 | 3, 14 | 4 15 | ] 16 | ] 17 | ] 18 | } 19 | --- 20 |
      21 | {% for op, (a, b) in seq %} 22 |
    • {{ a }} {{ op }} {{ b }} = ? 23 | {% endfor %} 24 |
    25 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@basic.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "Hello {{ name }}!" 4 | input_file: minijinja/tests/lexer-inputs/basic.txt 5 | --- 6 | TemplateData("Hello ") 7 | "Hello " 8 | VariableStart 9 | "{{" 10 | Ident("name") 11 | "name" 12 | VariableEnd 13 | "}}" 14 | TemplateData("!") 15 | "!" 16 | 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@err_extends_actually_not.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "before\n{% if not_true %}\n {% extends \"something.html\" %}\n{% endif %}\nand after" 4 | info: 5 | not_true: false 6 | input_file: minijinja/tests/inputs/err_extends_actually_not.txt 7 | --- 8 | before 9 | 10 | and after 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_closure_behavior.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {%- macro before_closure() %}{{ closure }}{% endmacro %} 4 | {%- set closure = 1 %} 5 | {%- macro after_closure() %}{{ closure }}{% endmacro %} 6 | {%- set closure = 2 %} 7 | {%- macro after_closure_reset() %}{{ closure }}{% endmacro %} 8 | {{ before_closure() }} 9 | {{ after_closure() }} 10 | {{ after_closure_reset() }} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@inexpr.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ 1 in seq }}\n{{ \"missing\" in seq }}\n{{ 1 not in seq }}\n{{ \"missing\" not in seq }}" 4 | info: 5 | seq: 6 | - 1 7 | - 2 8 | - 3 9 | input_file: minijinja/tests/inputs/inexpr.txt 10 | --- 11 | true 12 | false 13 | false 14 | true 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/pyright.yml: -------------------------------------------------------------------------------- 1 | name: Pyright 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | pyright: 7 | name: Pyright 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-python@v4 12 | with: 13 | python-version: '3.9' 14 | - name: Run pyright 15 | run: make python-type-check 16 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@extends.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends template %}\n{% block title %}new title{% endblock %}\n{% block body %}new body{% endblock %}" 4 | info: 5 | template: simple_layout.txt 6 | input_file: minijinja/tests/inputs/extends.txt 7 | --- 8 | new title 9 | new body 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@if_cond_elif.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% if value %}\n first branch\n{% elif other_value %}\n second branch\n{% else %}\n else\n{% endif %}" 4 | info: 5 | other_value: false 6 | value: false 7 | input_file: minijinja/tests/inputs/if_cond_elif.txt 8 | --- 9 | 10 | else 11 | 12 | 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_else2.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- for item in seq %}\n - {{ item }}\n{%- else %}\n should not happen\n{%- endfor %}" 4 | info: 5 | seq: 6 | - 1 7 | - 2 8 | - 3 9 | input_file: minijinja/tests/inputs/loop_else2.txt 10 | --- 11 | 12 | - 1 13 | - 2 14 | - 3 15 | 16 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["minijinja", "examples/*", "benchmarks", "minijinja-*"] 3 | exclude = ["examples/README.md"] 4 | resolver = "2" 5 | 6 | [profile.release] 7 | strip = true 8 | 9 | [profile.dev.package.insta] 10 | opt-level = 3 11 | 12 | # The profile that 'cargo dist' will build with 13 | [profile.dist] 14 | inherits = "release" 15 | lto = "thin" 16 | panic = "abort" 17 | -------------------------------------------------------------------------------- /examples/autoreload/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "autoreload" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["loader"] } 11 | minijinja-autoreload = { path = "../../minijinja-autoreload" } 12 | -------------------------------------------------------------------------------- /examples/inheritance/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "inheritance" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | serde = { version = "1.0.130", features = ["derive"] } 12 | serde_json = "1.0.68" 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_compiler__bool_ops.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_compiler.rs 3 | expression: "&c.finish()" 4 | --- 5 | ( 6 | [ 7 | 00000 | Lookup("first") [line 0], 8 | 00001 | JumpIfFalseOrPop(5), 9 | 00002 | Lookup("second"), 10 | 00003 | JumpIfTrueOrPop(5), 11 | 00004 | Lookup("third"), 12 | ], 13 | {}, 14 | ) 15 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@include.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "Before\n{% with variable=42 %}\n {% include template %}\n{% endwith %}\nAfter" 4 | info: 5 | template: simple_include.txt 6 | input_file: minijinja/tests/inputs/include.txt 7 | --- 8 | Before 9 | 10 | Hello 42 from included template! 11 | 12 | After 13 | 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@include_ignore_choice.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "Before\n{% include [\"missing_template.txt\", template] %}\nAfter" 4 | info: 5 | template: simple_include.txt 6 | input_file: minijinja/tests/inputs/include_ignore_choice.txt 7 | --- 8 | Before 9 | Hello from included template! 10 | After 11 | 12 | -------------------------------------------------------------------------------- /examples/merge-context/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "merge-context" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | minijinja-contrib = { path = "../../minijinja-contrib", features = ["datetime"] } 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_hoisting.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% macro first(param) %}first: {{ second(param )}}{% endmacro %}\n{% macro second(param) %}second: {{ param }}{% endmacro %}\n{{ first(42) }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_hoisting.txt 6 | --- 7 | 8 | 9 | first: second: 42 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_from_parent.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"fragment_in_parent.txt\" %}\n{% block other %}\nShouldn't show up\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_from_parent.txt 7 | --- 8 | 9 | Should show up 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/eval-to-state/src/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | {% block title %}{% endblock %} | My Site 3 | 9 | {%- set global_variable = 42 %} 10 |
    11 | {% block body %}{% endblock %} 12 |
    -------------------------------------------------------------------------------- /examples/minimal/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment}; 2 | 3 | fn main() { 4 | let mut env = Environment::new(); 5 | env.add_template("hello.txt", include_str!("hello.txt")) 6 | .unwrap(); 7 | let tmpl = env.get_template("hello.txt").unwrap(); 8 | println!( 9 | "{}", 10 | tmpl.render(context!(names => ["John", "Peter"])).unwrap() 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_scope_extends.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends template %}\n{% block item_block %}[{{ item }}]{% endblock %}" 4 | info: 5 | template: var_referencing_layout.txt 6 | input_file: minijinja/tests/inputs/block_scope_extends.txt 7 | --- 8 | 9 | [1] 10 | 11 | [2] 12 | 13 | [3] 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/filters/src/template.html: -------------------------------------------------------------------------------- 1 | 2 | {{ page_title|title }} 3 |

    {{ page_title|title }}

    4 | 9 |
    10 |   {{ "-*- "|repeat(10) }}
    11 | 
    12 |
    13 | © Copyright {{ year }} 14 |
    -------------------------------------------------------------------------------- /examples/recursive-for/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "recursive-for" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja", features = ["debug", "internal_debug"] } 11 | serde = { version = "1.0.130", features = ["derive"] } 12 | -------------------------------------------------------------------------------- /examples/recursive-for/README.md: -------------------------------------------------------------------------------- 1 | # recursive-for 2 | 3 | An example demonstrating the recursive for feature: 4 | 5 | ```jinja 6 | 12 | ``` 13 | 14 | ```console 15 | $ cargo run 16 | ``` 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_include.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- include \"example_macro.txt\" %}\n{%- set d = \"should never show up\" %}\n{{ example(1, 2, 3) }}\n{{ example(1, 2) }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_include.txt 6 | --- 7 | 8 | [1, 2, 3, "closure"] 9 | [1, 2, "default", "closure"] 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_simple_extend.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"simple_layout.txt\" %}\n\n{% block fragment %}\nThis should appear\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_simple_extend.txt 7 | --- 8 | 9 | This should appear 10 | 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/line-statement.txt: -------------------------------------------------------------------------------- 1 | { 2 | "line_statement_prefix": "#" 3 | } 4 | --- 5 |
      6 | # for item in seq 7 |
    • {{ item }}
    • 8 | # endfor 9 |
    10 | 11 |
      12 | # for item in [( 13 | 1, 2 14 | ), (3, 4)] 15 |
    • {{ item 16 | }}
    • # not a line statement {{ var }} # not a line statement 17 | # endfor 18 |
    19 | 20 | # block foo 21 | # endblock -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@ifexpr.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ 42 if something_true else 23 }}\n{{ 42 if not something_true else 23 }}\n{{ 42 if not something_true }}\n{{ (42 if not something_true) is undefined }}" 4 | info: 5 | something_true: true 6 | input_file: minijinja/tests/inputs/ifexpr.txt 7 | --- 8 | 42 9 | 23 10 | 11 | true 12 | 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_simple.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% block title %}Shouldn't show up{% endblock %}\n{% block fragment %}{{ var }}{% endblock fragment %}\nAlso shouldn't show up" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_simple.txt 7 | --- 8 | foo 9 | 10 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/in.txt: -------------------------------------------------------------------------------- 1 | { 2 | "word": "bird", 3 | "the_sentence": "bird is the word", 4 | "the_words": [ 5 | "bird", 6 | "not bird" 7 | ], 8 | "the_map": { 9 | "bird": "the word" 10 | } 11 | } 12 | --- 13 | {{ word in the_sentence }} 14 | {{ word in the_words }} 15 | {{ word in the_map }} 16 | {{ word not in the_sentence }} 17 | {{ word not in the_words }} 18 | {{ word not in the_map }} 19 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@do_macro_calling_macro.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- from \"call_macro.txt\" import call %}\n{%- macro my_macro(value) %}[{{ value }}]{% endmacro %}\nnothing should show: {% do call(my_macro, 42) %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/do_macro_calling_macro.txt 6 | --- 7 | 8 | nothing should show: 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/typos.yml: -------------------------------------------------------------------------------- 1 | name: Typos Check 2 | on: 3 | pull_request: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | run: 8 | name: Spell Check with Typos 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout Actions Repository 12 | uses: actions/checkout@v4 13 | 14 | - name: Check spelling 15 | uses: crate-ci/typos@master 16 | with: 17 | config: ./_typos.toml 18 | -------------------------------------------------------------------------------- /examples/self-referential-context/README.md: -------------------------------------------------------------------------------- 1 | # self-referential-context 2 | 3 | A context wrapper that acts self-referential. This allows variables passed to 4 | `render` to be also reachable via a `CONTEXT` alias. In short: a template 5 | can render a variable `name` via `{{ name }}` or also `{{ CONTEXT.name }}`. 6 | This would permit things such as `{{ CONTEXT|tojson }}`. 7 | 8 | ```console 9 | $ cargo run 10 | ``` 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_super.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends template %}\n{% block title %}[{{ super() }}]{% endblock %}\n{% block body %}{{ super()|upper }}{% endblock %}" 4 | info: 5 | template: simple_layout.txt 6 | input_file: minijinja/tests/inputs/block_super.txt 7 | --- 8 | [default title] 9 | DEFAULT BODY 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@do_closure.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% macro other_macro() %}23{% endmacro %}\n{% macro foo() %}[{% do other_macro() %}]{% endmacro %}\nShould not show output of other_macro: {{ foo() }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/do_closure.txt 6 | --- 7 | 8 | 9 | Should not show output of other_macro: [] 10 | 11 | -------------------------------------------------------------------------------- /examples/build-script/src/example.rs.jinja: -------------------------------------------------------------------------------- 1 | // This file is auto generated from a MiniJinja template 2 | 3 | struct {{ struct_name|safe }} { 4 | pub x: f32, 5 | pub y: f32, 6 | } 7 | 8 | const BUILD_CWD: &str = {{ build_cwd }}; 9 | const POINTS: [{{ struct_name|safe }}; {{ points|length }}] = [ 10 | {% for x, y in points %} 11 | {{ struct_name|safe }} { x: {{ x }}, y: {{ y }} }, 12 | {% endfor %} 13 | ]; 14 | -------------------------------------------------------------------------------- /examples/embedding/README.md: -------------------------------------------------------------------------------- 1 | # embedding 2 | 3 | This example shows how to embed templates in the binary 4 | configured by a feature flag. This example uses 5 | [`minijinja-embed`](https://docs.rs/minijinja-embed). 6 | 7 | Load the templates at runtime: 8 | 9 | ```console 10 | $ cargo run 11 | ``` 12 | 13 | Load the templates at compiled time into the binary: 14 | 15 | ``` 16 | $ cargo run --features=bundled 17 | ``` 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_compiler__for_loop.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_compiler.rs 3 | expression: "&c.finish()" 4 | --- 5 | ( 6 | [ 7 | 00000 | Lookup("items") [line 0], 8 | 00001 | PushLoop(1), 9 | 00002 | Iterate(5), 10 | 00003 | Emit, 11 | 00004 | Jump(2), 12 | 00005 | PopLoopFrame, 13 | 00006 | EmitRaw("!"), 14 | ], 15 | {}, 16 | ) 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@call.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% with f = range %}{% for x in f(upper) %}[{{ x }}]{% endfor %}{% endwith %}\n{% for k, v in dict(a=1, b=2, c=3)|dictsort %}[{{ k }}:{{ v }}]{% endfor %}" 4 | info: 5 | upper: 10 6 | input_file: minijinja/tests/inputs/call.txt 7 | --- 8 | [0][1][2][3][4][5][6][7][8][9] 9 | [a:1][b:2][c:3] 10 | 11 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "
      \n{% for item in seq %}\n
    • {{ item }}
    • \n{% endfor %}\n
    " 4 | info: 5 | seq: 6 | - 1 7 | - 2 8 | - 3 9 | input_file: minijinja/tests/inputs/loop.txt 10 | --- 11 |
      12 | 13 |
    • 1
    • 14 | 15 |
    • 2
    • 16 | 17 |
    • 3
    • 18 | 19 |
    20 | 21 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@mul.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ range(3) * 3 }}\n{{ \"foo\" * 3 }}\n{{ [1, 2] * 2 }}\n{{ [1, 2, 3, 4][:2] * 2 }}\n{{ 2 * [1, 2] }}\n{{ 2 * \"foo\" }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/mul.txt 6 | --- 7 | [0, 1, 2, 0, 1, 2, 0, 1, 2] 8 | foofoofoo 9 | [1, 2, 1, 2] 10 | [1, 2, 1, 2] 11 | [1, 2, 1, 2] 12 | foofoo 13 | -------------------------------------------------------------------------------- /examples/render-value/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment, Value}; 2 | 3 | fn main() { 4 | let env = Environment::new(); 5 | 6 | // this just demonstrates that `context!` creates a `Value` 7 | let ctx: Value = context! { 8 | name => "Peter" 9 | }; 10 | 11 | // Which can be directly passed to `render_str`. 12 | println!("{}", env.render_str("Hello {{ name }}!", ctx).unwrap()); 13 | } 14 | -------------------------------------------------------------------------------- /examples/syntax-highlighting/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syntax-highlighting" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | minijinja = { path = "../../minijinja" } 11 | syntect = { version = "5.2.0", default-features = false, features = ["default-fancy", "default-syntaxes"] } 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@err_open_block.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{% block foo bar" 4 | input_file: minijinja/tests/parser-inputs/err_open_block.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "unexpected identifier, expected end of block", 10 | name: "err_open_block.txt", 11 | line: 1, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /.github/workflows/clippy.yml: -------------------------------------------------------------------------------- 1 | name: Clippy 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: Swatinem/rust-cache@v2 12 | - uses: dtolnay/rust-toolchain@master 13 | with: 14 | toolchain: stable 15 | components: clippy, rustfmt 16 | - name: Run clippy 17 | run: make lint 18 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_caller_methods.txt: -------------------------------------------------------------------------------- 1 | {"closure": "original closure"} 2 | --- 3 | {% macro info(a, b) %} 4 | closure: {{ closure }} 5 | name: {{ caller.name }} 6 | args: {{ caller.arguments }} 7 | caller: {{ caller.caller }} 8 | a: {{ a }} 9 | b: {{ b }} 10 | result: {{ caller(a, b) }} 11 | {% endmacro %} 12 | 13 | {% set closure = "other closure" %} 14 | {% call(a, b) info(1, 2) %}{{ [a, b, closure] }}{% endcall %} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@err_binop_missing_rhs.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{{ foo / }}" 4 | input_file: minijinja/tests/parser-inputs/err_binop_missing_rhs.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "unexpected end of variable block", 10 | name: "err_binop_missing_rhs.txt", 11 | line: 1, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.wasm32-wasip1] 2 | runner = ["./scripts/wasmtime-wrapper.sh"] 3 | 4 | [target.aarch64-unknown-linux-gnu] 5 | linker = "aarch64-linux-gnu-gcc" 6 | 7 | [target.aarch64-unknown-linux-musl] 8 | linker = "rust-lld" 9 | 10 | [target.i686-unknown-linux-gnu] 11 | linker = "i686-linux-gnu-gcc" 12 | 13 | [target.'cfg(all(target_env = "msvc", target_os = "windows"))'] 14 | rustflags = ["-C", "target-feature=+crt-static"] 15 | -------------------------------------------------------------------------------- /examples/expr/README.md: -------------------------------------------------------------------------------- 1 | # expr 2 | 3 | This demonstrates how MiniJinja can be used to evaluate expressions. It accepts a single 4 | argument which is an expression that should be evaluated and the result is printed in JSON 5 | format to stdout. A single variable is provided to the script (`env`) which contains the 6 | environment variables. 7 | 8 | ```console 9 | $ cargo run -- 'env.HOME ~ "/.bashrc"' 10 | "/Users/mitsuhiko/.bashrc" 11 | ``` -------------------------------------------------------------------------------- /minijinja/tests/inputs/coerce.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ "World"[0] == "W" }} 4 | {{ "W" == "W" }} 5 | {{ 1.0 == 1 }} 6 | {{ 1 != 2 }} 7 | {{ none == none }} 8 | {{ none != undefined }} 9 | {{ undefined == undefined }} 10 | {{ true == true }} 11 | {{ 1 == true }} 12 | {{ 0 == false }} 13 | {{ 1 != 0 }} 14 | {{ "a" < "b" }} 15 | {{ "a"[0] < "b" }} 16 | {{ false < true }} 17 | {{ 0 < true }} 18 | {{ [0, 0] == [0, 0] }} 19 | {{ ["a"] == ["a"[0]] }} 20 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/namespace.txt: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | --- 4 | {%- set ns = namespace() %} 5 | {%- set ns.foo = 0 %} 6 | {%- for count in range(10) %} 7 | {%- set ns.foo = ns.foo + count %} 8 | {%- endfor %} 9 | {{- ns }} 10 | --- 11 | {% set ns.foo = namespace() %} 12 | {%- set ns.foo.bar = 42 %} 13 | {{- ns }} 14 | --- 15 | {% set ns = namespace(found=true) %} 16 | {{- ns }} 17 | --- 18 | {% set ns = namespace({"found": true}) %} 19 | {{- ns }} -------------------------------------------------------------------------------- /.github/workflows/rustfmt.yml: -------------------------------------------------------------------------------- 1 | name: Rustfmt 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: Swatinem/rust-cache@v2 12 | - uses: dtolnay/rust-toolchain@master 13 | with: 14 | toolchain: stable 15 | components: clippy, rustfmt 16 | - name: Run rustfmt 17 | run: make format-check 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@escape.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{'\\'' ~ 'foo'}}\n{{'\\'' ~ x ~ '\\''}}\n{{\"\\'\" ~ x ~ '\\''}}\n{{\"\\'\" ~ x ~ '\\''}}\n{{\"\nhello world\"}}\n{{\"hello\nworld\"}}" 4 | info: 5 | x: hello 6 | input_file: minijinja/tests/inputs/escape.txt 7 | --- 8 | 'foo 9 | 'hello' 10 | 'hello' 11 | 'hello' 12 | 13 | hello world 14 | hello 15 | world 16 | 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_extends.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- extends template %}\n{%- macro foo() %}inside foo{% endmacro %}\n{%- block title %}{{ foo() }}{% endblock %}\n{%- block body %}new body{% endblock %}" 4 | info: 5 | template: simple_layout.txt 6 | input_file: minijinja/tests/inputs/macro_extends.txt 7 | --- 8 | inside foo 9 | new body 10 | 11 | -------------------------------------------------------------------------------- /examples/dynamic-objects/src/template.html: -------------------------------------------------------------------------------- 1 | {%- with next_class = cycler(["odd", "even"]) %} 2 |
      3 | {%- for char in seq %} 4 |
    • {{ char }}
    • 5 | {%- endfor %} 6 |
    7 | {%- endwith %} 8 | 9 | {% for item in real_iter %} 10 | - {{ item }} ({{ loop.index }} from {{ loop.length|default("?") }}) 11 | {%- endfor %} 12 | 13 | A projected map: {{ a_element|safe }} 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@lstrip-blocks-raw.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "
      \n {% raw %}\n
    • {{ item }}
    • \n {% endraw %}\n
    " 4 | input_file: minijinja/tests/lexer-inputs/lstrip-blocks-raw.txt 5 | --- 6 | TemplateData("
      \n") 7 | "
        \n" 8 | TemplateData("
      • {{ item }}
      • \n") 9 | "\n
      • {{ item }}
      • \n " 10 | TemplateData("
      ") 11 | "
    " 12 | 13 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@do_macro.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% macro dialog(title) %}Dialog is {{ title }}{% endmacro %}\n\nShould be empty: {% do dialog(title=\"Hello World\") %}\nShould show: {{ dialog(title=\"Hello World\") }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/do_macro.txt 6 | --- 7 | 8 | 9 | Should be empty: 10 | Should show: Dialog is Hello World 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@getitem.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "first: {{ items[0] }}\nlast: {{ items[-1] }}\nname: {{ user[\"name\"] }}" 4 | info: 5 | items: 6 | - first_item 7 | - middle_item 8 | - last_item 9 | user: 10 | name: Peter 11 | input_file: minijinja/tests/inputs/getitem.txt 12 | --- 13 | first: first_item 14 | last: last_item 15 | name: Peter 16 | 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_scope_super.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"var_setting_layout.txt\" %}\n{% block test %}before: {% set var = \"from self\" %}{{ var }}\n{{ super() }}\nafter: {{ var }}{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/inputs/block_scope_super.txt 7 | --- 8 | before: from self 9 | inside: from super 10 | after: from self 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@err_open_variable_block.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "Hello {{ world" 4 | input_file: minijinja/tests/parser-inputs/err_open_variable_block.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "unexpected end of input, expected end of variable block", 10 | name: "err_open_variable_block.txt", 11 | line: 1, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_break_one_shot_iter.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "normal iteration does not lose items:\n{% for item in one_shot_iterator %}{{ item }}{% if item == 1 %}{% break %}{% endif %}{% endfor %}\n{%- for item in one_shot_iterator %}{{ item }}{% endfor %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/loop_break_one_shot_iter.txt 6 | --- 7 | normal iteration does not lose items: 8 | 012 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_import.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% from \"include_with_var_and_macro.txt\" import title, helper, missing -%}\nmissing: {{ missing }}\ntitle: {{ title }}\nhelper: {{ helper(\"a\", \"b\") }}" 4 | info: 5 | c: The C Variable 6 | input_file: minijinja/tests/inputs/macro_import.txt 7 | --- 8 | missing: 9 | title: The Title 10 | helper: ["a", "b", "The C Variable"] 11 | 12 | -------------------------------------------------------------------------------- /minijinja/tests/test_tests.rs: -------------------------------------------------------------------------------- 1 | use similar_asserts::assert_eq; 2 | 3 | use minijinja::{args, Environment, State}; 4 | 5 | #[test] 6 | fn test_basics() { 7 | fn test(_: &State, a: u32, b: u32) -> bool { 8 | assert_eq!(a, 23); 9 | a == b 10 | } 11 | 12 | let mut env = Environment::new(); 13 | env.add_test("test", test); 14 | let state = env.empty_state(); 15 | assert!(state.perform_test("test", args!(23, 23)).unwrap()); 16 | } 17 | -------------------------------------------------------------------------------- /examples/macros/src/template.html: -------------------------------------------------------------------------------- 1 | 2 | Demo 3 | {%- import "macros.html" as all_macros %} 4 | {%- from "macros.html" import render_input %} 5 |
    6 |
    7 |
    Username
    8 |
    {{ render_input("username", username) }}
    9 |
    Password
    10 |
    {{ render_input("password", type="password") }}
    11 |
    12 |
    13 | -------------------------------------------------------------------------------- /examples/path-loader/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, path_loader, Environment}; 2 | use once_cell::sync::Lazy; 3 | 4 | static ENV: Lazy> = Lazy::new(|| { 5 | let mut env = Environment::new(); 6 | env.set_loader(path_loader("templates")); 7 | env 8 | }); 9 | 10 | fn main() { 11 | let tmpl = ENV.get_template("hello.txt").unwrap(); 12 | let ctx = context!(name => "World"); 13 | println!("{}", tmpl.render(ctx).unwrap()); 14 | } 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Something does not seem right 4 | --- 5 | 6 | ## Description 7 | 8 | [What happened] 9 | 10 | ## Reproduction steps 11 | 12 | 1. [First step] 13 | 2. [Second step] 14 | 3. etc. 15 | 16 | Additional helpful information: 17 | 18 | - Version of minijinja: 19 | - Version of rustc: 20 | - Operating system and version: 21 | 22 | ## What did you expect 23 | 24 | [What you think should have happened] 25 | 26 | 27 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_super.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"simple_layout.txt\" %}\n\n{% block fragment %}\nThis should appear\n{{ super() }}\n{{ super()|upper }}\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_super.txt 7 | --- 8 | 9 | This should appear 10 | 11 | From parent 12 | 13 | 14 | FROM PARENT 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_caller.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {% macro render_dialog(title, class='dialog') -%} 4 |
    5 |

    {{ title }}

    6 |
    7 | {{ caller() }} 8 |
    9 |
    10 | {%- endmacro %} 11 | 12 | {% call render_dialog('Hello World') %} 13 | This is a simple dialog rendered by using a macro and 14 | a call block. 15 | {% endcall %} 16 | 17 | caller: {{ render_dialog.caller }} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@err_wrong_block_name.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{% block foo %}\n here\n{% endblock bar %}" 4 | input_file: minijinja/tests/parser-inputs/err_wrong_block_name.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "mismatching name on block. Got `bar`, expected `foo`", 10 | name: "err_wrong_block_name.txt", 11 | line: 3, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/loop_var.txt: -------------------------------------------------------------------------------- 1 | { 2 | "seq": [ 3 | "a", 4 | "b", 5 | "c", 6 | "d" 7 | ] 8 | } 9 | --- 10 | {% for item in seq %} 11 | {{ item }} ({{ loop.index }} of {{ loop.length }}) 12 | first={{ loop.first }} 13 | last={{ loop.last }} 14 | revindex={{ loop.revindex }} 15 | revindex0={{ loop.revindex0 }} 16 | cycle={{ loop.cycle("odd", "even") }} 17 | previtem={{ loop.previtem }} 18 | nextitem={{ loop.nextitem }} 19 | {% endfor %} 20 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@err_invalid_var_assignment.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{% for loop in seq %}\n ...\n{% endfor %}" 4 | input_file: minijinja/tests/parser-inputs/err_invalid_var_assignment.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "cannot assign to reserved variable name loop", 10 | name: "err_invalid_var_assignment.txt", 11 | line: 1, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_basic.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% macro add(a, b) %}{{ a }}|{{ b }}{% endmacro -%}\n{{ add(1, 2) }}\n{{ add(a=1, b=2) }}\n{{ add(b=2, a=1) }}\n{{ add(1, b=2) }}\n{{ add.name }}\n{{ add.arguments }}\n{{ add.caller }}\n{{ add }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_basic.txt 6 | --- 7 | 1|2 8 | 1|2 9 | 1|2 10 | 1|2 11 | add 12 | ["a", "b"] 13 | false 14 | 15 | 16 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_ref_parent.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"var_referencing_layout.txt\" %}\n\n{% block item_block %}\n [{{ item }}]\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_ref_parent.txt 7 | --- 8 | 9 | 10 | 11 | [1] 12 | 13 | 14 | 15 | [2] 16 | 17 | 18 | 19 | [3] 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@string_unescape.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{{ \"foo\\u2603bar\" }}" 4 | input_file: minijinja/tests/parser-inputs/string_unescape.txt 5 | --- 6 | Ok( 7 | Template { 8 | children: [ 9 | EmitExpr { 10 | expr: Const { 11 | value: "foo☃bar", 12 | } @ 1:3-1:17, 13 | } @ 1:0-1:17, 14 | ], 15 | } @ 0:0-1:20, 16 | ) 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_unpacking.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "
      \n{% for op, (a, b) in seq %}\n
    • {{ a }} {{ op }} {{ b }} = ?\n{% endfor %}\n
    " 4 | info: 5 | seq: 6 | - - + 7 | - - 1 8 | - 2 9 | - - "-" 10 | - - 3 11 | - 4 12 | input_file: minijinja/tests/inputs/loop_unpacking.txt 13 | --- 14 |
      15 | 16 |
    • 1 + 2 = ? 17 | 18 |
    • 3 - 4 = ? 19 | 20 |
    21 | 22 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm_block_fragments@fragment_super_super.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"simple_layout_2.txt\" %}\n\n{% block fragment %}\nThis should appear\n{{ super() }}\n{{ super()|upper }}\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/fragment-inputs/fragment_super_super.txt 7 | --- 8 | 9 | This should appear 10 | ( 11 | From parent 12 | ) 13 | ( 14 | FROM PARENT 15 | ) 16 | 17 | 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@block_super.html.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% extends \"super_with_html.html\" %}\n{% block body %}\n

    New Content

    \n {{ super() }}\n {{ super()|upper }}\n{% endblock %}" 4 | info: 5 | var: foo 6 | input_file: minijinja/tests/inputs/block_super.html 7 | --- 8 | 9 |

    New Content

    10 | 11 |

    Default Content

    12 | 13 | 14 | <P>DEFAULT CONTENT</P> 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/embedding/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedding" 3 | version = "0.1.0" 4 | edition = "2018" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [features] 10 | bundled = [] 11 | 12 | [dependencies] 13 | minijinja = { path = "../../minijinja", features = ["loader"] } 14 | minijinja-embed = { path = "../../minijinja-embed" } 15 | 16 | [build-dependencies] 17 | minijinja-embed = { path = "../../minijinja-embed" } 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_kwargs.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% macro foo(a, b, c, d) %}{{ [a, b, c, d] }}{% endmacro -%}\n{{ foo(1, 2, 3) }}\n{{ foo({\"blub\": \"blah\"}) }}\n{{ foo(a=1, b=2, c=3) }}\n{{ foo(a=1, b=2, c=3, d=4) }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_kwargs.txt 6 | --- 7 | [1, 2, 3, undefined] 8 | [{"blub": "blah"}, undefined, undefined, undefined] 9 | [1, 2, 3, undefined] 10 | [1, 2, 3, 4] 11 | 12 | -------------------------------------------------------------------------------- /examples/debug/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment}; 2 | 3 | fn main() { 4 | let mut env = Environment::new(); 5 | env.add_template("demo.txt", include_str!("demo.txt")) 6 | .unwrap(); 7 | let template = env.get_template("demo.txt").unwrap(); 8 | println!( 9 | "{}", 10 | template 11 | .render(context! { 12 | name => "Peter Lustig", 13 | iterations => 1 14 | }) 15 | .unwrap() 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@parent-balance.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "{{ {\"a\": {\"b\": 1}} }}" 4 | input_file: minijinja/tests/lexer-inputs/parent-balance.txt 5 | --- 6 | VariableStart 7 | "{{" 8 | BraceOpen 9 | "{" 10 | Str("a") 11 | "\"a\"" 12 | Colon 13 | ":" 14 | BraceOpen 15 | "{" 16 | Str("b") 17 | "\"b\"" 18 | Colon 19 | ":" 20 | Int(1) 21 | "1" 22 | BraceClose 23 | "}" 24 | BraceClose 25 | "}" 26 | VariableEnd 27 | "}}" 28 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_break_one_shot_iter_peek.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "peeking loses items:\n{% for item in one_shot_iterator %}{{ item }}(next: {{ loop.nextitem }}){% if item == 0 %}{% break %}{% endif %}{% endfor %}\n{%- for item in one_shot_iterator %}{{ item }}(next: {{ loop.nextitem }}){% endfor %}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/loop_break_one_shot_iter_peek.txt 6 | --- 7 | peeking loses items: 8 | 0(next: 1)2(next: ) 9 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_compiler__if_branches.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_compiler.rs 3 | expression: "&c.finish()" 4 | --- 5 | ( 6 | [ 7 | 00000 | Lookup("false") [line 0], 8 | 00001 | JumpIfFalse(4), 9 | 00002 | EmitRaw("nope1"), 10 | 00003 | Jump(9), 11 | 00004 | Lookup("nil"), 12 | 00005 | JumpIfFalse(8), 13 | 00006 | EmitRaw("nope1"), 14 | 00007 | Jump(9), 15 | 00008 | EmitRaw("yes"), 16 | ], 17 | {}, 18 | ) 19 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@autoescape.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ unsafe }}\n{% autoescape true %}{{ unsafe }}{% endautoescape %}\n{% autoescape false %}{{ unsafe }}{% endautoescape %}\n{% autoescape \"html\" %}{{ unsafe }}{% endautoescape %}\n{% autoescape \"none\" %}{{ unsafe }}{% endautoescape %}" 4 | info: 5 | unsafe: "" 6 | input_file: minijinja/tests/inputs/autoescape.txt 7 | --- 8 | 9 | <foo> 10 | 11 | <foo> 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/load-resource/README.md: -------------------------------------------------------------------------------- 1 | # load-resource 2 | 3 | This example loads data at runtime through a function call from JSON files. 4 | 5 | ```jinja 6 | {% set nav = load_data("nav.json") %} 7 | 12 | ``` 13 | 14 | ```console 15 | $ cargo run 16 | 21 | ``` 22 | -------------------------------------------------------------------------------- /minijinja-py/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | 3 | mod environment; 4 | mod error_support; 5 | mod state; 6 | mod typeconv; 7 | 8 | #[pymodule(gil_used = false)] 9 | fn _lowlevel(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { 10 | m.add_class::()?; 11 | m.add_class::()?; 12 | m.add_class::()?; 13 | m.add_function(wrap_pyfunction!(error_support::get_panic_info, m)?)?; 14 | crate::error_support::init_panic_hook(); 15 | Ok(()) 16 | } 17 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/with.txt: -------------------------------------------------------------------------------- 1 | { 2 | "foo": 42, 3 | "bar": 23, 4 | "other": 11, 5 | "tuple": [ 6 | 1, 7 | 2, 8 | [ 9 | 3 10 | ] 11 | ], 12 | "tuple2": [ 13 | [ 14 | 1 15 | ], 16 | 2, 17 | 3 18 | ] 19 | } 20 | --- 21 | {% with a=foo, b=bar %} 22 | {{ a }}|{{ b }}|{{ other }} 23 | {% endwith %} 24 | 25 | {% with (a, b, (c,)) = tuple %} 26 | {{ a }}|{{ b }}|{{ c }} 27 | {% endwith %} 28 | 29 | {% with ((a,), b, c) = tuple2 %} 30 | {{ a }}|{{ b }}|{{ c }} 31 | {% endwith %} 32 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@autoescape.html.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ unsafe }}\n{% autoescape true %}{{ unsafe }}{% endautoescape %}\n{% autoescape false %}{{ unsafe }}{% endautoescape %}\n{% autoescape \"html\" %}{{ unsafe }}{% endautoescape %}\n{% autoescape \"none\" %}{{ unsafe }}{% endautoescape %}" 4 | info: 5 | unsafe: "" 6 | input_file: minijinja/tests/inputs/autoescape.html 7 | --- 8 | <foo> 9 | <foo> 10 | 11 | <foo> 12 | 13 | 14 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@tojson.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ [1, 2, 3]|tojson }}\n{{ [1, 2, 3]|tojson(true) }}\n{{ [1, 2, 3]|tojson(indent=4) }}\n{{ [1, 2, 3]|tojson(1) }}\n{{ [1, 2, 3]|tojson(8) }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/tojson.txt 6 | --- 7 | [1,2,3] 8 | [ 9 | 1, 10 | 2, 11 | 3 12 | ] 13 | [ 14 | 1, 15 | 2, 16 | 3 17 | ] 18 | [ 19 | 1, 20 | 2, 21 | 3 22 | ] 23 | [ 24 | 1, 25 | 2, 26 | 3 27 | ] 28 | -------------------------------------------------------------------------------- /examples/macros/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment}; 2 | 3 | fn main() { 4 | let mut env = Environment::new(); 5 | env.add_template("macros.html", include_str!("macros.html")) 6 | .unwrap(); 7 | env.add_template("template.html", include_str!("template.html")) 8 | .unwrap(); 9 | 10 | let template = env.get_template("template.html").unwrap(); 11 | let context = context! { 12 | username => "John Doe" 13 | }; 14 | 15 | println!("{}", template.render(&context).unwrap()); 16 | } 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_import2.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% import \"include_with_var_and_macro.txt\" as helpers -%}\n{{ helpers }}\nmissing: {{ helpers.missing }}\ntitle: {{ helpers.title }}\nhelper: {{ helpers.helper(\"a\", \"b\") }}" 4 | info: 5 | c: The C Variable 6 | input_file: minijinja/tests/inputs/macro_import2.txt 7 | --- 8 | {"helper": , "title": "The Title"} 9 | missing: 10 | title: The Title 11 | helper: ["a", "b", "The C Variable"] 12 | 13 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/calls-and-literals.txt: -------------------------------------------------------------------------------- 1 | { 2 | "one": 1, 3 | "two": 2, 4 | "nine": 9 5 | } 6 | --- 7 | {{ get_args(1, 2, 3, 4, 5, 6, 7, 8, 9) }} 8 | {{ get_args(1, 2, 3, *[4, 5, 6], 7, 8, 9) }} 9 | {{ get_args(one, 2, 3, 4, 5, 6, 7, 8, 9) }} 10 | {{ get_args(1, 2, 3, *[4, 5, 6], 7, 8, nine) }} 11 | {{ get_args(1, 2, one=1, two=two) }} 12 | {{ get_args(1, 2, one=1, **dict(two=two)) }} 13 | {{ get_args(1, *[2], one=1, **dict(two=two)) }} 14 | {{ get_args(1, 2, *[3], *[4], **{8: 8, 9: 9})}} 15 | {{ get_args(1, 2, *[3], *[4], **{8: 8, nine: nine})}} -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_closure_behavior.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- macro before_closure() %}{{ closure }}{% endmacro %}\n{%- set closure = 1 %}\n{%- macro after_closure() %}{{ closure }}{% endmacro %}\n{%- set closure = 2 %}\n{%- macro after_closure_reset() %}{{ closure }}{% endmacro %}\n{{ before_closure() }}\n{{ after_closure() }}\n{{ after_closure_reset() }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/macro_closure_behavior.txt 6 | --- 7 | 8 | 2 9 | 2 10 | 2 11 | 12 | -------------------------------------------------------------------------------- /minijinja-cabi/cbindgen.toml: -------------------------------------------------------------------------------- 1 | language = "C" 2 | header = """/* 3 | * MiniJinja for C 4 | * 5 | * Copyright 2024 Armin Ronacher. MIT License. 6 | */""" 7 | include_guard = "_minijinja_h_included" 8 | pragma_once = true 9 | no_includes = true 10 | sys_includes = ["stdint.h", "stddef.h", "stdbool.h"] 11 | cpp_compat = true 12 | documentation_style = "c" 13 | documentation_length = "short" 14 | after_includes = """ 15 | 16 | #ifndef MINIJINJA_API 17 | # define MINIJINJA_API 18 | #endif 19 | """ 20 | 21 | [fn] 22 | prefix = "MINIJINJA_API" 23 | sort_by = "Name" 24 | -------------------------------------------------------------------------------- /minijinja-py/tests/test_security.py: -------------------------------------------------------------------------------- 1 | from minijinja import Environment 2 | 3 | 4 | def test_private_attrs(): 5 | class MyClass: 6 | def __init__(self): 7 | self.public = 42 8 | self._private = 23 9 | 10 | env = Environment() 11 | rv = env.eval_expr("[x.public, x._private]", x=MyClass()) 12 | assert rv == [42, None] 13 | 14 | 15 | def test_dict_is_always_public(): 16 | env = Environment() 17 | rv = env.eval_expr("[x.public, x._private]", x={"public": 42, "_private": 23}) 18 | assert rv == [42, 23] 19 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@lstrip-blocks-keep-inline-space.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "[{% if true %} {% endif %}]" 4 | input_file: minijinja/tests/lexer-inputs/lstrip-blocks-keep-inline-space.txt 5 | --- 6 | TemplateData("[") 7 | "[" 8 | BlockStart 9 | "{%" 10 | Ident("if") 11 | "if" 12 | Ident("true") 13 | "true" 14 | BlockEnd 15 | "%}" 16 | TemplateData(" ") 17 | " " 18 | BlockStart 19 | "{%" 20 | Ident("endif") 21 | "endif" 22 | BlockEnd 23 | "%}" 24 | TemplateData("]") 25 | "]" 26 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@in.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ word in the_sentence }}\n{{ word in the_words }}\n{{ word in the_map }}\n{{ word not in the_sentence }}\n{{ word not in the_words }}\n{{ word not in the_map }}" 4 | info: 5 | the_map: 6 | bird: the word 7 | the_sentence: bird is the word 8 | the_words: 9 | - bird 10 | - not bird 11 | word: bird 12 | input_file: minijinja/tests/inputs/in.txt 13 | --- 14 | true 15 | true 16 | true 17 | false 18 | false 19 | false 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/publish-crates.yml: -------------------------------------------------------------------------------- 1 | name: Publish Crates 2 | 3 | on: 4 | push: 5 | tags: 6 | - '**[0-9]+.[0-9]+.[0-9]+*' 7 | pull_request: 8 | 9 | jobs: 10 | publish-crates: 11 | name: Publish to crates.io 12 | runs-on: ubuntu-latest 13 | env: 14 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 15 | if: ${{ !github.event.pull_request }} 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: swatinem/rust-cache@v2 19 | - name: Publish 20 | run: | 21 | ./scripts/publish-all.sh 22 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@lstrip-blocks-comment.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "
      \n {# for item in seq #}\n
    • {{ item }}
    • \n {# endfor #}\n
    " 4 | input_file: minijinja/tests/lexer-inputs/lstrip-blocks-comment.txt 5 | --- 6 | TemplateData("
      \n") 7 | "
        \n" 8 | TemplateData("
      • ") 9 | "
      • " 10 | VariableStart 11 | "{{" 12 | Ident("item") 13 | "item" 14 | VariableEnd 15 | "}}" 16 | TemplateData("
      • \n") 17 | "\n" 18 | TemplateData("
      ") 19 | "
    " 20 | 21 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@loop_filter.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- for item in seq if item is even and loop is undefined %}\n- {{ item }} ({{ loop.index }} / {{ loop.length }})\n{%- endfor %}" 4 | info: 5 | seq: 6 | - 1 7 | - 2 8 | - 3 9 | - 4 10 | - 5 11 | - 6 12 | - 7 13 | - 8 14 | - 9 15 | - 10 16 | input_file: minijinja/tests/inputs/loop_filter.txt 17 | --- 18 | 19 | - 2 (1 / 5) 20 | - 4 (2 / 5) 21 | - 6 (3 / 5) 22 | - 8 (4 / 5) 23 | - 10 (5 / 5) 24 | 25 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@adding.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "Strings:\n{{ 'to' + name + 'you' }}!\n{{ 'to' + 'you' }}!\n\nSequences:\n{{ [1] + [2] }}\n{{ [1, 2, 3][:2] + [4, 5] }}\n\nAdding:\n{{ 1 + 2 }}\n\nMinus:\n{{ 2 - 1 }}\n\nDivide:\n{{ 100 / 2 }}" 4 | info: 5 | name: World 6 | input_file: minijinja/tests/inputs/adding.txt 7 | --- 8 | Strings: 9 | toWorldyou! 10 | toyou! 11 | 12 | Sequences: 13 | [1, 2] 14 | [1, 2, 4, 5] 15 | 16 | Adding: 17 | 3 18 | 19 | Minus: 20 | 1 21 | 22 | Divide: 23 | 50.0 24 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@math.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "should be -2.5: {{ 1.5 * 2.5 * 2 / 3 - var }}\nshould be -3.0: {{ 1.5 * 2.5 * 2 // 3 - var }}\nshould be 2.0: {{ 4 / 2 }}\nshould be 2: {{ 4 // 2 }}\nshould be 0: {{ 1 - 1 }}\nshould be 0: {{1-1}}\nshould be -1: {{ -1 }}" 4 | info: 5 | var: 5 6 | input_file: minijinja/tests/inputs/math.txt 7 | --- 8 | should be -2.5: -2.5 9 | should be -3.0: -3.0 10 | should be 2.0: 2.0 11 | should be 2: 2 12 | should be 0: 0 13 | should be 0: 0 14 | should be -1: -1 15 | 16 | -------------------------------------------------------------------------------- /minijinja-embed/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "minijinja-embed" 3 | version = "2.14.0" 4 | edition = "2018" 5 | license = "Apache-2.0" 6 | authors = ["Armin Ronacher "] 7 | description = "template embedding support for MiniJinja" 8 | homepage = "https://github.com/mitsuhiko/minijinja" 9 | repository = "https://github.com/mitsuhiko/minijinja" 10 | keywords = ["jinja", "jinja2", "templates", "autoreload"] 11 | readme = "README.md" 12 | rust-version = "1.70" 13 | 14 | [package.metadata.docs.rs] 15 | rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "doc-header.html"] 16 | -------------------------------------------------------------------------------- /minijinja-py/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: develop test 3 | 4 | .venv: 5 | python3 -mvenv .venv 6 | .venv/bin/pip install --upgrade pip 7 | .venv/bin/pip install maturin pytest markupsafe black pyright 8 | 9 | .PHONY: test 10 | develop: .venv 11 | .venv/bin/maturin develop 12 | 13 | .PHONY: develop-release 14 | develop-release: .venv 15 | .venv/bin/maturin develop --release 16 | 17 | .PHONY: test 18 | test: .venv 19 | .venv/bin/pytest 20 | 21 | .PHONY: format 22 | format: .venv 23 | .venv/bin/black tests python 24 | 25 | .PHONY: type-check 26 | type-check: .venv 27 | .venv/bin/pyright python 28 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@block-filter.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "{% for item in seq -%}\n {{ item }}{% endfor %}" 4 | input_file: minijinja/tests/lexer-inputs/block-filter.txt 5 | --- 6 | BlockStart 7 | "{%" 8 | Ident("for") 9 | "for" 10 | Ident("item") 11 | "item" 12 | Ident("in") 13 | "in" 14 | Ident("seq") 15 | "seq" 16 | BlockEnd 17 | "-%}" 18 | VariableStart 19 | "{{" 20 | Ident("item") 21 | "item" 22 | VariableEnd 23 | "}}" 24 | BlockStart 25 | "{%" 26 | Ident("endfor") 27 | "endfor" 28 | BlockEnd 29 | "%}" 30 | 31 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@indexing.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ hello[0] }}\n{{ hello[3] }}\n{{ hello[-1] }}\n{{ hello[999] is undefined }}\n{{ intrange[0] }}\n{{ intrange[3] }}\n{{ intrange[-1] }}\n{{ intrange[999] is undefined }}" 4 | info: 5 | hello: Hello World 6 | intrange: 7 | - 0 8 | - 1 9 | - 2 10 | - 3 11 | - 4 12 | - 5 13 | - 6 14 | - 7 15 | - 8 16 | - 9 17 | input_file: minijinja/tests/inputs/indexing.txt 18 | --- 19 | H 20 | l 21 | d 22 | true 23 | 0 24 | 3 25 | 9 26 | true 27 | 28 | -------------------------------------------------------------------------------- /examples/generate-yaml/README.md: -------------------------------------------------------------------------------- 1 | # generate-yaml 2 | 3 | This demonstrates how MiniJinja can be used to generate YAML files with automatic escaping. 4 | It renders a YAML template and fills in some values which are automatically formatted to 5 | be valid JSON and YAML syntax. 6 | 7 | ```jinja 8 | env: {{ env }} 9 | title: {{ title }} 10 | skip: {{ true }} 11 | run: {{ ["bash", "./script.sh"] }} 12 | yaml_value: {{ yaml|safe }} 13 | ``` 14 | 15 | ```console 16 | $ cargo run 17 | env: {"PATH": "/tmp"} 18 | title: "Hello World!" 19 | skip: true 20 | run: ["bash","./script.sh"] 21 | yaml_value: [1, 2, 3] 22 | ``` 23 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/slicing.txt: -------------------------------------------------------------------------------- 1 | { 2 | "hello": "Hällo Wörld", 3 | "intrange": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 4 | } 5 | --- 6 | {{ hello[:] }} 7 | {{ hello[1:] }} 8 | {{ hello[1:-1] }} 9 | {{ hello[::2] }} 10 | {{ hello[2:10] }} 11 | {{ hello[2:10:2] }} 12 | {{ intrange[:] }} 13 | {{ intrange[1:] }} 14 | {{ intrange[1:-1] }} 15 | {{ intrange[::2] }} 16 | {{ intrange[2:10] }} 17 | {{ intrange[2:10:2] }} 18 | {{ intrange[2:10][0] }} 19 | {{ intrange[2:10][2:][0] }} 20 | {{ intrange[::-1] }} 21 | {{ intrange[::-2] }} 22 | {{ intrange[4:2:-1] }} 23 | {{ intrange[4:2:-2] }} 24 | {{ intrange[-5::-1] }} 25 | {{ intrange[-5:2:-1] }} 26 | -------------------------------------------------------------------------------- /examples/dynamic-objects/README.md: -------------------------------------------------------------------------------- 1 | # dynamic-objects 2 | 3 | This example demonstrates how to pass dynamic runtime objects to the 4 | engine for custom behavior. 5 | 6 | ```jinja 7 | {%- with next_class = cycler(["odd", "even"]) %} 8 |
      9 | {%- for char in seq %} 10 |
    • {{ char }}
    • 11 | {%- endfor %} 12 |
    13 | {%- endwith %}"#, 14 | ``` 15 | 16 | ```console 17 | $ cargo run 18 |
      19 |
    • a
    • 20 |
    • b
    • 21 |
    • c
    • 22 |
    • d
    • 23 |
    24 | ``` 25 | -------------------------------------------------------------------------------- /minijinja-py/python/minijinja/_lowlevel.pyi: -------------------------------------------------------------------------------- 1 | from typing import Any, Optional 2 | from minijinja import Environment 3 | 4 | class State: 5 | """A reference to the current state.""" 6 | 7 | @property 8 | def env(self) -> Environment: ... 9 | @property 10 | def name(self) -> str: ... 11 | @property 12 | def auto_escape(self) -> Optional[str]: ... 13 | @property 14 | def current_block(self) -> Optional[str]: ... 15 | def lookup(self, name: str) -> Any: ... 16 | def get_temp(self, name: str, default: Optional[Any] = None) -> Any: ... 17 | def set_temp(self, name: str, value: Any) -> Any: ... 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@dict.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ dict(d) }}\n{{ dict(x=1, y=2) }}\n{{ dict(d, c=3)}}\n{% for _ in [1] %}{{ dict(loop, extra=2)|dictsort }}{% endfor %}" 4 | info: 5 | d: 6 | a: 1 7 | b: 2 8 | input_file: minijinja/tests/inputs/dict.txt 9 | --- 10 | {"a": 1, "b": 2} 11 | {"x": 1, "y": 2} 12 | {"a": 1, "b": 2, "c": 3} 13 | [["depth", 1], ["depth0", 0], ["extra", 2], ["first", true], ["index", 1], ["index0", 0], ["last", true], ["length", 1], ["nextitem", undefined], ["previtem", undefined], ["revindex", 1], ["revindex0", 0]] 14 | 15 | -------------------------------------------------------------------------------- /minijinja/tests/lexer-inputs/literals.txt: -------------------------------------------------------------------------------- 1 | {} 2 | --- 3 | {{ true }} 4 | {{ false }} 5 | {{ null }} 6 | {{ 1.0 }} 7 | {{ 1_000.0 }} 8 | {{ 2 }} 9 | {{ 2_000 }} 10 | {{ [1, 2, 3] }} 11 | {{ {"foo": "bar"} }} 12 | {{ -9223372036854775808 }} 13 | {{ -9_223_372_036_854_775_808 }} 14 | {{ -170141183460469231731687303715884105728 }} 15 | {{ 170141183460469231731687303715884105727 }} 16 | {{ 340282366920938463463374607431768211455 }} 17 | {{ 0b1111 }} 18 | {{ 0B1001 }} 19 | {{ 0o777 }} 20 | {{ 0O777 }} 21 | {{ 0O7_77 }} 22 | {{ 0xdeadbeef }} 23 | {{ 0XDEADBEEF }} 24 | {{ 0XDEAD_BEEF }} 25 | {{ 1e2 }} 26 | {{ 1e_2 }} 27 | {{ 1_1e+_2 }} 28 | {{ 1_1e-_2 }} 29 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@simple.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "Hello {{ world }}!" 4 | input_file: minijinja/tests/parser-inputs/simple.txt 5 | --- 6 | Ok( 7 | Template { 8 | children: [ 9 | EmitRaw { 10 | raw: "Hello ", 11 | } @ 1:0-1:6, 12 | EmitExpr { 13 | expr: Var { 14 | id: "world", 15 | } @ 1:9-1:14, 16 | } @ 1:6-1:14, 17 | EmitRaw { 18 | raw: "!", 19 | } @ 1:17-1:18, 20 | ], 21 | } @ 0:0-1:18, 22 | ) 23 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@namespace.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- set ns = namespace() %}\n{%- set ns.foo = 0 %}\n{%- for count in range(10) %}\n {%- set ns.foo = ns.foo + count %}\n{%- endfor %}\n{{- ns }}\n---\n{% set ns.foo = namespace() %}\n{%- set ns.foo.bar = 42 %}\n{{- ns }}\n---\n{% set ns = namespace(found=true) %}\n{{- ns }}\n---\n{% set ns = namespace({\"found\": true}) %}\n{{- ns }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/namespace.txt 6 | --- 7 | {"foo": 45} 8 | --- 9 | {"foo": {"bar": 42}} 10 | --- 11 | {"found": true} 12 | --- 13 | {"found": true} 14 | 15 | -------------------------------------------------------------------------------- /doc-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | -------------------------------------------------------------------------------- /minijinja-py/python/minijinja/_internal.py: -------------------------------------------------------------------------------- 1 | # This file contains functions that the rust module imports. 2 | from . import TemplateError, safe 3 | 4 | 5 | def make_error(info): 6 | # Internal utility function used by the rust binding to create a template error 7 | # with info object. We cannot directly create an error on the Rust side because 8 | # we want to subclass the runtime error, but on the limited abi it's not possible 9 | # to create subclasses (yet!) 10 | err = TemplateError(info.description) 11 | err._info = info 12 | return err 13 | 14 | 15 | # used by the rust runtime to mark something as safe 16 | mark_safe = safe 17 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@with.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{% with a=foo, b=bar %}\n {{ a }}|{{ b }}|{{ other }}\n{% endwith %}\n\n{% with (a, b, (c,)) = tuple %}\n {{ a }}|{{ b }}|{{ c }}\n{% endwith %}\n\n{% with ((a,), b, c) = tuple2 %}\n {{ a }}|{{ b }}|{{ c }}\n{% endwith %}" 4 | info: 5 | bar: 23 6 | foo: 42 7 | other: 11 8 | tuple: 9 | - 1 10 | - 2 11 | - - 3 12 | tuple2: 13 | - - 1 14 | - 2 15 | - 3 16 | input_file: minijinja/tests/inputs/with.txt 17 | --- 18 | 19 | 42|23|11 20 | 21 | 22 | 23 | 1|2|3 24 | 25 | 26 | 27 | 1|2|3 28 | 29 | 30 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@whitespace.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "foo {{- bar -}} baz {{ blah }} blub\nfoo {#- comment -#} baz {# blah #} blub" 4 | input_file: minijinja/tests/lexer-inputs/whitespace.txt 5 | --- 6 | TemplateData("foo") 7 | "foo" 8 | VariableStart 9 | "{{-" 10 | Ident("bar") 11 | "bar" 12 | VariableEnd 13 | "-}}" 14 | TemplateData("baz ") 15 | "baz " 16 | VariableStart 17 | "{{" 18 | Ident("blah") 19 | "blah" 20 | VariableEnd 21 | "}}" 22 | TemplateData(" blub\nfoo") 23 | " blub\nfoo" 24 | TemplateData("baz ") 25 | "baz " 26 | TemplateData(" blub") 27 | " blub" 28 | 29 | -------------------------------------------------------------------------------- /minijinja/tests/test_parser.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "unstable_machinery")] 2 | use minijinja::machinery::parse; 3 | 4 | #[test] 5 | fn test_parser() { 6 | insta::glob!("parser-inputs/*.txt", |path| { 7 | let contents = std::fs::read_to_string(path).unwrap(); 8 | let filename = path.file_name().unwrap().to_str().unwrap(); 9 | let ast = parse(&contents, filename, Default::default(), Default::default()); 10 | insta::with_settings!({ 11 | description => contents.trim_end(), 12 | omit_expression => true, 13 | }, { 14 | insta::assert_debug_snapshot!(&ast); 15 | }); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@autoescape.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{% autoescape false %}foo{% endautoescape %}" 4 | input_file: minijinja/tests/parser-inputs/autoescape.txt 5 | --- 6 | Ok( 7 | Template { 8 | children: [ 9 | AutoEscape { 10 | enabled: Const { 11 | value: false, 12 | } @ 1:14-1:19, 13 | body: [ 14 | EmitRaw { 15 | raw: "foo", 16 | } @ 1:22-1:25, 17 | ], 18 | } @ 1:3-1:41, 19 | ], 20 | } @ 0:0-1:44, 21 | ) 22 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@max-recursion.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{{ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] }}" 4 | input_file: minijinja/tests/parser-inputs/max-recursion.txt 5 | --- 6 | Err( 7 | Error { 8 | kind: SyntaxError, 9 | detail: "template exceeds maximum recursion limits", 10 | name: "max-recursion.txt", 11 | line: 1, 12 | }, 13 | ) 14 | -------------------------------------------------------------------------------- /examples/line-statements/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, syntax::SyntaxConfig, Environment}; 2 | 3 | fn main() { 4 | let mut env = Environment::new(); 5 | env.set_syntax( 6 | SyntaxConfig::builder() 7 | .line_statement_prefix("#") 8 | .line_comment_prefix("##") 9 | .build() 10 | .unwrap(), 11 | ); 12 | env.add_template("hello.txt", include_str!("hello.txt")) 13 | .unwrap(); 14 | let template = env.get_template("hello.txt").unwrap(); 15 | println!( 16 | "{}", 17 | template 18 | .render(context!(seq => vec!["foo", "bar"])) 19 | .unwrap() 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@trim-blocks.loop.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "{% for item in seq %}\n {{ item }}\n{% endfor %}" 4 | input_file: minijinja/tests/lexer-inputs/trim-blocks.loop.txt 5 | --- 6 | BlockStart 7 | "{%" 8 | Ident("for") 9 | "for" 10 | Ident("item") 11 | "item" 12 | Ident("in") 13 | "in" 14 | Ident("seq") 15 | "seq" 16 | BlockEnd 17 | "%}" 18 | TemplateData(" ") 19 | " " 20 | VariableStart 21 | "{{" 22 | Ident("item") 23 | "item" 24 | VariableEnd 25 | "}}" 26 | TemplateData("\n") 27 | "\n" 28 | BlockStart 29 | "{%" 30 | Ident("endfor") 31 | "endfor" 32 | BlockEnd 33 | "%}" 34 | 35 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_lexer__lexer@no-trim-blocks.loop.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_lexer.rs 3 | description: "{% for item in seq %}\n {{ item }}\n{% endfor %}" 4 | input_file: minijinja/tests/lexer-inputs/no-trim-blocks.loop.txt 5 | --- 6 | BlockStart 7 | "{%" 8 | Ident("for") 9 | "for" 10 | Ident("item") 11 | "item" 12 | Ident("in") 13 | "in" 14 | Ident("seq") 15 | "seq" 16 | BlockEnd 17 | "%}" 18 | TemplateData("\n ") 19 | "\n " 20 | VariableStart 21 | "{{" 22 | Ident("item") 23 | "item" 24 | VariableEnd 25 | "}}" 26 | TemplateData("\n") 27 | "\n" 28 | BlockStart 29 | "{%" 30 | Ident("endfor") 31 | "endfor" 32 | BlockEnd 33 | "%}" 34 | 35 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@literals.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ true }}\n{{ false }}\n{{ null }}\n{{ 1.0 }}\n{{ 2 }}\n{{ [1, 2, 3] }}\n{{ {\"foo\": \"bar\"} }}\n{{ -9223372036854775808 }}\n{{ -170141183460469231731687303715884105728 }}\n{{ 170141183460469231731687303715884105727 }}\n{{ 340282366920938463463374607431768211455 }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/literals.txt 6 | --- 7 | true 8 | false 9 | 10 | 1.0 11 | 2 12 | [1, 2, 3] 13 | {"foo": "bar"} 14 | -9223372036854775808 15 | 170141183460469231731687303715884105728 16 | 170141183460469231731687303715884105727 17 | 340282366920938463463374607431768211455 18 | 19 | -------------------------------------------------------------------------------- /examples/inheritance/src/main.rs: -------------------------------------------------------------------------------- 1 | use minijinja::{context, Environment}; 2 | use serde::Serialize; 3 | 4 | #[derive(Serialize)] 5 | pub struct Page { 6 | title: String, 7 | content: String, 8 | } 9 | 10 | fn main() { 11 | let mut env = Environment::new(); 12 | env.add_template("layout.html", include_str!("layout.html")) 13 | .unwrap(); 14 | env.add_template("index.html", include_str!("index.html")) 15 | .unwrap(); 16 | 17 | let template = env.get_template("index.html").unwrap(); 18 | let page = Page { 19 | title: "Some title".into(), 20 | content: "Lorum Ipsum".into(), 21 | }; 22 | println!("{}", template.render(context!(page)).unwrap()); 23 | } 24 | -------------------------------------------------------------------------------- /minijinja-py/hello.py: -------------------------------------------------------------------------------- 1 | from minijinja import Environment 2 | 3 | INDEX = """{% extends "layout.html" %} 4 | {% block title %}{{ page.title }}{% endblock %} 5 | {% block body %} 6 |
      7 | {%- for item in items %} 8 |
    • {{ item }} 9 | {%- endfor %} 10 |
    11 | {% endblock %} 12 | """ 13 | LAYOUT = """ 14 | {% block title %}{% endblock %} 15 | 16 | {% block body %}{% endblock %} 17 | 18 | """ 19 | 20 | env = Environment(templates={ 21 | "index.html": INDEX, 22 | "layout.html": LAYOUT, 23 | }) 24 | 25 | print(env.render_template( 26 | 'index.html', 27 | page={"title": "The Page Title"}, 28 | items=["Peter", "Paul", "Mary"] 29 | )) 30 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@macro_recursive.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{%- macro nest(children) -%}\n \n {%- for child in children -%}\n {{ nest(child.children) }}\n {%- endfor -%}\n \n{%- endmacro -%}\n{{ nest(top_level) }}" 4 | info: 5 | top_level: 6 | - children: 7 | - children: [] 8 | - children: [] 9 | - children: 10 | - children: [] 11 | input_file: minijinja/tests/inputs/macro_recursive.txt 12 | --- 13 | 14 | 15 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@getattr.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{{ foo.bar.baz }}" 4 | input_file: minijinja/tests/parser-inputs/getattr.txt 5 | --- 6 | Ok( 7 | Template { 8 | children: [ 9 | EmitExpr { 10 | expr: GetAttr { 11 | expr: GetAttr { 12 | expr: Var { 13 | id: "foo", 14 | } @ 1:3-1:6, 15 | name: "bar", 16 | } @ 1:3-1:10, 17 | name: "baz", 18 | } @ 1:6-1:14, 19 | } @ 1:0-1:14, 20 | ], 21 | } @ 0:0-1:17, 22 | ) 23 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_templates__vm@coerce.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_templates.rs 3 | description: "{{ \"World\"[0] == \"W\" }}\n{{ \"W\" == \"W\" }}\n{{ 1.0 == 1 }}\n{{ 1 != 2 }}\n{{ none == none }}\n{{ none != undefined }}\n{{ undefined == undefined }}\n{{ true == true }}\n{{ 1 == true }}\n{{ 0 == false }}\n{{ 1 != 0 }}\n{{ \"a\" < \"b\" }}\n{{ \"a\"[0] < \"b\" }}\n{{ false < true }}\n{{ 0 < true }}\n{{ [0, 0] == [0, 0] }}\n{{ [\"a\"] == [\"a\"[0]] }}" 4 | info: {} 5 | input_file: minijinja/tests/inputs/coerce.txt 6 | --- 7 | true 8 | true 9 | true 10 | true 11 | true 12 | true 13 | true 14 | true 15 | true 16 | true 17 | true 18 | true 19 | true 20 | true 21 | false 22 | true 23 | true 24 | -------------------------------------------------------------------------------- /minijinja/tests/snapshots/test_parser__parser@if_cond_simple.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: minijinja/tests/test_parser.rs 3 | description: "{% if expr1 %}\n branch 1\n{% endif %}" 4 | input_file: minijinja/tests/parser-inputs/if_cond_simple.txt 5 | --- 6 | Ok( 7 | Template { 8 | children: [ 9 | IfCond { 10 | expr: Var { 11 | id: "expr1", 12 | } @ 1:6-1:11, 13 | true_body: [ 14 | EmitRaw { 15 | raw: "\n branch 1\n", 16 | } @ 1:14-3:0, 17 | ], 18 | false_body: [], 19 | } @ 1:3-3:8, 20 | ], 21 | } @ 0:0-3:11, 22 | ) 23 | -------------------------------------------------------------------------------- /minijinja/tests/inputs/macro_recursive.txt: -------------------------------------------------------------------------------- 1 | { 2 | "top_level": [ 3 | { 4 | "children": [ 5 | { 6 | "children": [] 7 | }, 8 | { 9 | "children": [] 10 | } 11 | ] 12 | }, 13 | { 14 | "children": [ 15 | { 16 | "children": [] 17 | } 18 | ] 19 | } 20 | ] 21 | } 22 | --- 23 | {%- macro nest(children) -%} 24 | 25 | {%- for child in children -%} 26 | {{ nest(child.children) }} 27 | {%- endfor -%} 28 | 29 | {%- endmacro -%} 30 | {{ nest(top_level) }} 31 | -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/tera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ title }} | Hello 4 | 5 | 6 |
    7 |

    Hello

    8 | 15 |
    16 |
    17 |
      18 | {% for item in items %} 19 |
    • {{ loop.index }}: {{ item|upper }}
    • 20 | {% endfor %} 21 |
    22 |
    23 |
    24 | {% include "footer.html" %} 25 |
    26 | 27 | -------------------------------------------------------------------------------- /minijinja/tests/parser-inputs/imports.txt: -------------------------------------------------------------------------------- 1 | {% from "foo.html" import a, b %} 2 | {% from "foo.html" import a %} 3 | {% from "foo.html" import a as b %} 4 | {% from "foo.html" import a as b, b as c %} 5 | {% from "foo.html" import a, b, %} 6 | {% from "foo.html" import a, %} 7 | {% from "foo.html" import a as b, %} 8 | {% from "foo.html" import a as b, b as c, %} 9 | {% from "foo.html" import a as b, b as c with context %} 10 | {% from "foo.html" import a as b, b as c without context %} 11 | {% from "foo.html" import a as b, b as c, with context %} 12 | {% from "foo.html" import a as b, b as c, without context %} 13 | {% import "foo.html" as x %} 14 | {% import "foo.html" as x with context %} 15 | {% import "foo.html" as x without context %} 16 | -------------------------------------------------------------------------------- /benchmarks/inputs/comparison/handlebars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ title }} | Hello 4 | 5 | 6 |
    7 |

    Hello

    8 | 17 |
    18 |
    19 |
      20 | {{#each items }} 21 |
    • {{@index}}: {{ upper this }}
    • 22 | {{/each}} 23 |
    24 |
    25 | 28 | 29 | --------------------------------------------------------------------------------