-
Notifications
You must be signed in to change notification settings - Fork 28
View
hunt framework view module is runtime render template engine, easy to use, like twig / jinja2.
example:
my-template.html:
<div>Hello, {{ name }}!</div>
DLang code:
@Action
string test()
{
view.assign("name", "Brian");
return view.render("my-template");
}
result:
<div>Hello, Brian!</div>
- Statements
{%
...%}
- Expressions
{{
...}}
- Comments
{#
...#}
- Line statements
#
, comments##
- Variable itself:
foo
- Variable's field:
foo.bar
orfoo['bar']
- Variables array:
foos[2]
- Integer number:
42
- Floating number
42.2
- String:
"Some string"
,'Another string'
- Boolean:
true
/false
,True
/False
- Array:
[1, 'string', false]
- List:
(1, 'string', false)
note: internal list representation still is array - Dictionary:
{'a': 10, 'b': true}
or{a: 10, b: true}
note: keys in dictionary can only be strings - Math Operators:
**
,*
,/
,//
,%
,+
,-
- Logic operators:
(
...)
,not
,and
,or
- Comparison operators:
==
,!=
,>=
,<=
,>
,<
- Other operators:
in
,is
,|
,~
,...(...)
- Ternary if:
... if ... else ...
- If:
if
/elif
/else
/endif
- For:
for
/else
/endfor
- Macros:
macro
/endmacro
- Call:
call
/endcall
- Set:
set
- Filter:
filter
- Extending:
extends
,block
/endblock
- Import:
import
- Include:
include
- With:
with
/endwith
note: without assignment
Space control with -
operator allowed only for statements: {%- ... -%}
Most of global functions / tests / filters are not implemented at the moment. Must be done later.
- Implemented functions:
range
,length
/count
,namespace
- Implemented test:
defined
,undefined
,number
,list
,dict
- Implemented filters:
default
/d
,escape
/e
,upper
,sort
,keys
Unlike original Jinja it is possible to set variables inside a block and have them show up outside of it. This means that the following example will work as expected.
{% set iterated = false %}
{% for item in seq %} ## non-empty sequence
{{ item }}
{% set iterated = true %}
{% endfor %}
{% if not iterated %} did not iterate {% endif %} ## will not be printed (iterated == true)
It is possible to set variable field and member of array:
{% set foo = {} %}
{% set foo.bar = 10 %}
{{ foo.bar }} ## 10
{% set foos = [1, 2, 3] %}
{% set foos[2] = 30 %}
{{ foos }} ## [1, 2, 30]
It is possible to use Uniform Function Call Syntax for variables like in D:
{% set foo = [1, 1, 1, 1, 1] %}
{{ range(length(foo)) }} ## [0, 1, 2, 3, 4]
{{ foo.length.range }} ## [0, 1, 2, 3, 4]
You can return value from user defined macros due to return
keyword in endmacro
statement:
{% macro sum(numbers) %}
{% sum = 0 %}
{% for num in numbers %}
{% sum = sum + num %}
{% endfor %}
{% endmacro return sum %}
{{ sum([1, 2, 3, 4]) * 10 }} ## 100
Since macros can return value, you can use them as functions / filters / tests:
{% macro sum(numbers) %}
{% sum = 0 %}
{% for num in numbers %}
{% sum = sum + num %}
{% endfor %}
{% endmacro return sum %}
{{ [0, 1, 2, 4] | sum | e }} ## 7
{% macro large(l) %}
{% endmacro return l is list and l.length > 10 %}
{{ 'yes' if [0, 1, 2] is large else 'no' }} ## no
It is possible to define macro inside another macro and inner macro has link to external contexts.
{% set a = 1 %}
{% macro m1 %} ## variables `a`, `b` are available inside
{% set b = 2 %}
{% macro m2 %} ## variables `a`, `b`, `c` are available inside
{% set c = 3 %}
{% endmcaro %}
{% endmcaro %}
{% set counter = 0 -%}
{%- macro inc() -%}
{% set counter = counter + 1 %}
{%- endmacro return counter -%}
{{ inc() }} ## 1
{{ inc() }} ## 2
{{ inc() }} ## 3
{{ inc() }} ## 4
Loop over each item in a sequence. For example, to display a list of users provided in a variable called users:
<h1>Members</h1>
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
As variables in templates retain their object properties, it is possible to iterate over containers like dict:
<dl>
{% for key, value in my_dict.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
Inside of a for-loop block, you can access some special variables:
Variable | Description |
---|---|
loop.index | The current iteration of the loop. (1 indexed) |
loop.index0 | The current iteration of the loop. (0 indexed) |
loop.revindex | The number of iterations from the end of the loop (1 indexed) |
loop.revindex0 | The number of iterations from the end of the loop (0 indexed) |
loop.first | True if first iteration. |
loop.last | True if last iteration. |
loop.length | The number of items in the sequence. |
loop.depth | Indicates how deep in a recursive loop the rendering currently is. Starts at level 1 |
loop.depth0 | Indicates how deep in a recursive loop the rendering currently is. Starts at level 0 |
loop.previtem | The item from the previous iteration of the loop. Undefined during the first iteration. |
loop.nextitem | The item from the following iteration of the loop. Undefined during the last iteration. |