美文网首页Ansible-Developer
Jinja 模版设计语法

Jinja 模版设计语法

作者: Michael_林 | 来源:发表于2017-10-22 13:56 被阅读2次

    声明: 本文中的部分内容未经过测试,因此不能保证正确,不同版本的Jinja支持的特性不一样.

    Jinja 模版设计

    什么是Jinja模版?

    Jinja模版是一个文本文件,通过它可以生成任何文本格式的文件,例如.html、.xml、.csv等等。一个Jinja模版并不需要有一个特定的扩展名,完全可以自定义或是不定义.
    Jinja模版包含了变量、表达式、标签,当模版被渲染时,变量和/或者表达式会被替换为特定的指,标签用来控制模版的逻辑。模版的语法受Django和python的极大启发.

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>
    
        <h1>My Webpage</h1>
        {{ a_variable }}
    
        {# a comment #}
    </body>
    </html>
    

    说明:

    • {% %}是声明标签
    • {{ }} 是打印输出表达式文本结果的标签
    • {# ... #} 用于注释,但是不会输出到结果文件中
    • ... ## 用于注释行语句

    变量

    Jinja模版中使用的变量油传递给模版的上下文字典来定义.
    如果为传入变量定义,那么该变量就无法被引擎渲染。

    在模版中访问变量:

    可以在模版中标签里面引用变量,例如打印变量结果:

    {{ bar }}
    如果变量中还有其他属性,那么可以通过字典的形式访问:
    {{ bar['foo'] }} 或是 {{ bar.foo }}

    总结: 变量的访问形式取决域传入的变量定义。

    过滤器

    过滤器是用来对模版中的变量进行特定的修改。过滤器通过管道符号(|)和
    变量分开,过滤器可以传入参数
    多个过滤器可以链式使用: 一个过滤器的结果被下一个过滤器处理

    常用过滤器:

    1. {{ my_variable|default('my_variable is not defined') }}  指定默认值  
    2. dictsort(value, case_sensitive=False, by=’key’) 对字典按照键或值进行排序,是否大小写敏感例如: 例如:  
    {% 的 项目 在 mydict | dictsort  %}
    按键分类dict,不区分大小写
    
    {% 的 项目 在 mydict | dictsort (true ) %}
    按键分类,区分大小写
    
    {% 的 项目 在 mydict | dictionsort (false , 'value' ) %}
    按值排序dict,不区分大小写
    3. filesizeformat(value,binary = False ) 将数值格式化为“可读”文件大小(即13 kB,4.1 MB,102字节等)  
    4. first(seq ) 返回序列的第一个元素
    5. format(value,* args,** kwargs ), 对对象应用python字符串格式化, 例如:
    {{ "%s - %s"|format("Hello?", "Foo!") }}
    -> Hello? - Foo!
    6. last(seq ) 返回序列的最后一个项目
    7. length(obj) 返回序列或映射的项目数。
    8. list(value) 将值转换为列表。如果是一个字符串,返回的列表将是一个字符列表。
    9. lower(s ) 将值转换为小写。
    10. pprint(value,verbose = False ) 完整打印一个变量。适用于调试
    11. random(seq ) 从序列中返回随机项
    12. reverse(值) 反转对象或返回一个迭代器,反之亦然。
    13. trim(值)跳过开始和结尾的空白。
    

    测试(逻辑控制)

    测试用来对一个变量或是表达式是否满足某种条件进行检查,根据检查结果执行特定的行为
    例如检查变量是否被定义(被应用程序传入):
    {% if name is defined %}
    检查一个变量能否被3整除:
    {% if loop.index is divisibleby 3 %}
    或是: {% if loop.index is divisibleby(3) %}

    常用测试列表
    1. defined(值) 如果定义了变量,返回true  
    {% if variable is defined %}
        value of variable: {{ variable }}
    {% else %}
        variable is not defined
    {% endif %}
    说明: default()过滤器以简单的方法设置未定义的变量
    
    2. divisibleby(value,num ) 检查变量是否可被数字整除。
    
    3. equalto(value, other) 检查对象是否与其他对象具有相同的值.
    {% if foo.expression is equalto 42 %}
        the foo attribute evaluates to the constant 42
    {% endif %}
    
    4. escaped(值) 检查值是否被转义
    5. even(value) 如果变量为偶,则返回true。
    6. greaterthan(value, other) 检查值是否大于其他值。
    7. iterable(value) 检查是否可以迭代对象。
    8. lessthan(value, other) 检查值是否小于其他值。
    9. lower(value)如果变量全是小写,则返回true。
    10. mapping(value)如果对象是字典(dict等),则返回true
    11. none(value) 如果变量为none,返回true
    12. number(value) 如果变量是数字,返回true。
    13. odd(value 如果变量为奇数则返回true。
    14. sameas(value, other)检查对象是否指向与另一个对象相同的内存地址:
    15. sequence(value)如果变量是一个序列,返回true。序列是可迭代的变量。
    16. string(value)如果对象是字符串,则返回true
    17. undefined(value) 是否未被定义
    18. upper(value) 是否全是大写
    
    全局函数列表
    1. range([ start,] stop [,step ] ) 返回一个序列,例如:
    <ul>
    {% for user in users %}
        <li>{{ user.username }}</li>
    {% endfor %}
    {% for number in range(10 - users|count) %}
        <li class="empty"><span>...</span></li>
    {% endfor %}
    </ul>
    

    注释

    要在模板中注释掉部分行,请使用默认设置为的注释语法。这有助于注释掉模板的部分进行调试或为其他模板设计者或自己添加信息:{# ... #}
    例如:

    {#注意:注释掉的模板,因为我们不再使用这个
    {%的用户在用户%} 
        ... 
    {%endfor%} 
    #}
    

    结构控制

    控制结构是指控制程序流程的所有形式 - 即条件(即if / elif / else),for-循环,以及宏和块等。使用默认语法,控件结构出现在 {% ... %}块内。

    for循环

    遍历一个集合中的所有集合项目
    例如遍历所有的用户集合:

    <h1>Members</h1>
    <ul>
    {% for user in users %}
    <li>{{ user.username|e }}</li>
    {% endfor %}
    </ul>
    

    由于模板中的变量保留对象属性,因此可以遍历像dict这样的容器:

    < dl > 
    {% for  key , value  in  my_dict.iteritems () %} 
        < dt > {{  key | e  }} </ dt > 
        < dd > {{  value | e  }} </ dd > 
    {% endfor  %} 
    </ dl >
    

    在循环块的内部,可以访问一些特殊变量:

    loop.index  当前循环的迭代。(1索引)
    loop.index0 当前循环的迭代。(0索引)
    loop.revindex   循环结束的迭代次数(1个索引)
    loop.revindex0  循环结束的迭代次数(0索引)
    loop.first  如果是第一次迭代,则为true
    loop.last   如果最后一次迭代为真。
    loop.length 序列中的项目数。
    loop.cycle  一个辅助函数,用于在序列列表之间循环。参见下面的说明。
    loop.depth  指示渲染当前处于递归循环的深度。从1级开始
    loop.depth0 指示渲染当前处于递归循环的深度。从0级开始
    

    在一个for循环中,可以通过使用特殊的loop.cycle帮助程序在每次循环之间循环一个字符串/变量列表:

    {% for row in rows %}
    <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
    {% endfor %}
    
    {% for user in users if not user.hidden %}
    <li>{{ user.username|e }}</li>
    {% endfor %}
    
    <ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% else %}
    <li><em>no users found</em></li>
    {% endfor %}
    </ul>
    
    if 语句

    Jinja中的if语句与Python if语句相当。在最简单的形式中,您可以使用它来测试变量是否被定义,而不是空且不是假的:

    {% if users %}
    <ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
    </ul>
    {% endif %}
    
    对于多个分支,elif和else可以像Python一样使用。也可以在这里使用更复杂的表达式:  
    {% if kenny.sick %}
    Kenny is sick.
    {% elif kenny.dead %}
        You killed Kenny!  You bastard!!!
    {% else %}
    Kenny looks okay --- so far
    {% endif %}
    

    宏与常规编程语言的功能相当。它们有助于将经常使用的成语置于可重用的功能中,以便不重复(“DRY”)
    以下是呈现表单元素的宏的一个小例子:

    {% macro input(name, value='', type='text', size=20) -%}
    <input type="{{ type }}" name="{{ name }}" value="{{
        value|e }}" size="{{ size }}">
    {%- endmacro %}
    

    过滤器

    过滤器部分允许您在一组模板数据上应用常规的Jinja2过滤器。只需将代码包装在特殊过滤器部分:

    {% filter upper %}
    This text becomes uppercase
    {% endfilter %}
    

    表达式

    Jinja允许任何地方使用基本表达式。这些工作与常规Python非常相似;

    字符表达式

    最简单的表达形式是字符。字符是Python对象(如字符串和数字)的表示形式。例如:

    Hello World”:
        两个双引号或单引号之间的一切都是一个字符串。当您需要模板中的字符串(例如作为函数调用和过滤器的参数,
    
    42 / 42.23:
        整数和浮点数是通过写下数字创建的。如果存在点,则该数字为浮点数,否则为整数。请记住,在Python中,42并且42.0 分别是(int和float)。
    
    ['list','of','objects']:
        两个括号之间的一切都是列表。列表对于存储要迭代的顺序数据很有用。例如,您可以使用for循环的列表和元组轻松创建链接列表,例如:
    <ul>
    {% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
                         ('downloads.html', 'Downloads')] %}
        <li><a href="{{ href }}">{{ caption }}</a></li>
    {% endfor %}
    </ul>
    
    ('tuple','of','values'):
        元组就像不能修改的列表(“不可变”)。如果一个元组只有一个项,则必须后跟一个逗号(('1-tuple',))。元组通常用于表示两个或多个元素的项目。
    
    {‘dict’: ‘of’, ‘key’: ‘and’, ‘value’: ‘pairs’}:
        Python中的dict是一个结合键和值的结构。键必须是唯一的,并且始终具有一个值。
    
    数学表达式

    Jinja允许使用值进行计算。模板中很少有用.支持以下运算符:

    +
    将两个对象添加在一起。通常对象是数字,但如果两者都是字符串或列表,则可以以这种方式连接它们。然而,这不是连接字符串的首选方法!对于字符串连接,请在~操作员看看。 是。{{ 1 + 1 }}2
    -
    从第一个数字减去第二个数字。 是。{{ 3 - 2 }}1
    /
    划分两个数字 返回值将为浮点数。 是。(就像。){{ 1 / 2 }}{{ 0.5 }}from __future__ import division
    //
    划分两个数字并返回截断的整数结果。 是。{{ 20 // 7 }}2
    %
    计算整数除法的余数。 是。{{ 11 % 7 }}4
    *
    将左操作数与正确的操作数相乘。 将返回。这也可以用来重复一次字符串多次。 将打印一个80个等号的酒吧。{{ 2 * 2 }}4{{ '=' * 80 }}
    **
    将左操作数提高到右操作数的权力。 将返回。{{ 2**3 }}8
    
    比较表达式
    ==
    比较两个对象的相等性。
    !=
    比较两个对象的不平等。
    >
    如果左手侧大于右侧,则为真。
    > =
    如果左手侧大于或等于右侧,则为真。
    <
    如果左手侧低于右侧,则为真。
    <=
    如果左手侧低于或等于右侧,则为真。
    
    逻辑表达式
    and
        如果左和右操作数为真,返回true。
    or 
        如果左或右操作数为真,则返回true。
    not
        否定
    (exp)
        表达式分组

    相关文章

      网友评论

        本文标题:Jinja 模版设计语法

        本文链接:https://www.haomeiwen.com/subject/hnbguxtx.html