zoukankan      html  css  js  c++  java
  • twig 模板设计 快速入门手册 中文

    写了好几篇关于twig的东西。。居然还没写个快速入门之类的。现在就写

    来源 http://twig.sensiolabs.org/doc/templates.html

    概要

    twig 的模板就是普通的文本文件,也不需要特别的扩展名,.html .htm .twig 都可以。
    模板内的 变量 和 表达式 会在运行的时候被解析替换,标签(tags)会来控制模板的逻辑
    下面是个最小型的模板,用来说明一些基础的东西
    1. <!DOCTYPE html> 
    2. <html> 
    3.     <head> 
    4.         <title>My Webpage</title> 
    5.     </head> 
    6.     <body> 
    7.         <ulid="navigation"> 
    8.         {% for item in navigation %} 
    9.             <li><ahref="{{ item.href }}">{{ item.caption }}</a></li> 
    10.         {% endfor %} 
    11.         </ul> 
    12.  
    13.         <h1>My Webpage</h1> 
    14.         {{ a_variable }} 
    15.     </body> 
    16. </html> 
    <!DOCTYPE html>
    <html>
        <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 }}
        </body>
    </html>
    里面包含两种符号 {% ... %} 和 {{ ... }} 第一种用来控制的比如for循环什么的,第二个是用来输出变量和表达式的
     

    ide 支持

    很多ide 都对twig进行高亮支持。大伙自己找需要的吧。

    变量

    程序会传递给模板若干变量,你需要在模板里输出他们。例如输出 $hello
    1. {{ hello }} 
    {{ hello }}
    如果传递给模板的是对象或者数组,你可以使用点 . 来输出对象的属性或者方法,或者数组的成员。或者你可以使用下标的方式。
    1. {{ foo.bar }} 
    2. {{ foo['bar'] }} 
    {{ foo.bar }}
    {{ foo['bar'] }}
    如果你访问的值不存在就会返回null。TWIG有一整套的流程来确认值是否存在。
     
    for.bar会进行以下操作
    。。。如果 foo是个数组,就尝试返回bar成员,如果不存在的话,往下继续
    。。。如果foo是个对象,会尝试返回bar属性,如果不存在的话,往下继续
    。。。会尝试运行bar方法,如果不存在的话,往下继续
    。。。会尝试运行getBar方法,如果不存在的话,往下继续
    。。。会尝试运行isBar方法,如果不存在的话,返回null
     
    for['bar'] 就简单很多了 for必须是个数组,尝试返回bar成员,如果不就返回null

    全局变量

    TWIG定义了有一些全局变量

    • _self  这个参看macro标签
    • _context 这个就是当前的环境
    • _charset: 当前的字符编码

    变量赋值

    具体参见set标签
    1. {% set foo = 'foo' %} 
    2. {% set foo = [1, 2] %} 
    3. {% set foo = {'foo': 'bar'} %} 
    {% set foo = 'foo' %}
    {% set foo = [1, 2] %}
    {% set foo = {'foo': 'bar'} %}

    过滤器 Firters

    变量可以被过滤器修饰。过滤器和变量用(|)分割开。过滤器也是可以有参数的。过滤器也可以被多重使用。
    下面这例子就使用了两个过滤器。
    1. {{ name|striptags|title }} 
    {{ name|striptags|title }}
    striptas表示去除html标签,title表示每个单词的首字母大写。更多过滤器参见我博客
     
    过滤器也可以用在代码块中,参见 filter标签
    1. {% filter upper %} 
    2.   This text becomes uppercase 
    3. {% endfilter %} 
    {% filter upper %}
      This text becomes uppercase
    {% endfilter %}

    函数 Function

    这个没什么好说的,会写程序的都知道,TWIG内置了一些函数,参考我的博客
    举个例子 返回一个0到3的数组,就使用 range函数
    1. {% for i in range(0, 3) %} 
    2.     {{ i }}, 
    3. {% endfor %} 
    {% for i in range(0, 3) %}
        {{ i }},
    {% endfor %}

    流程控制

    支持for循环 和 if/elseif/else结构。直接看例子吧,没什么好说的。
    1. <h1>Members</h1> 
    2. <ul> 
    3.     {% for user in users %} 
    4.         <li>{{ user.username|e }}</li> 
    5.     {% endfor %} 
    6. </ul> 
    <h1>Members</h1>
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
    1. {% if users|length > 0 %} 
    2.     <ul> 
    3.         {% for user in users %} 
    4.             <li>{{ user.username|e }}</li> 
    5.         {% endfor %} 
    6.     </ul> 
    7. {% endif %} 
    {% if users|length > 0 %}
        <ul>
            {% for user in users %}
                <li>{{ user.username|e }}</li>
            {% endfor %}
        </ul>
    {% endif %}

    注释

    {# ... #} 包围的内容会被注释掉,可以是单行 也可以是多行。
     

    载入其他模板

    详见include标签(我博客内已经翻译好哦),会返回经过渲染的内容到当前的模板里
    1. {% include 'sidebar.html' %} 
    {% include 'sidebar.html' %}
    当前模板的变量也会传递到 被include的模板里,在那里面可以直接访问你这个模板的变量。
    比如
    1. {% for box in boxes %} 
    2.     {% include "render_box.html" %} 
    3. {% endfor %} 
    {% for box in boxes %}
        {% include "render_box.html" %}
    {% endfor %}
    在 render_box.html 是可以访问 box变量的 加入其他参数可以使被载入的模板只访问部分变量,或者完全访问不到。参考手册
     

    模板继承

    TWIG中最有用到功能就是模板继承,他允许你建立一个“骨骼模板”,然后你用不同到block来覆盖父模板中任意到部分。而且使用起来非常到简单。
    我们先定义一个基本骨骼页base.html 他包含许多block块,这些都可以被子模板覆盖。
    1. <!DOCTYPE html> 
    2. <html> 
    3.     <head> 
    4.         {% block head %} 
    5.             <linkrel="stylesheet"href="style.css"/> 
    6.             <title>{% block title %}{% endblock %} - My Webpage</title> 
    7.         {% endblock %} 
    8.     </head> 
    9.     <body> 
    10.         <divid="content">{% block content %}{% endblock %}</div> 
    11.         <divid="footer"> 
    12.             {% block footer %} 
    13.                 © Copyright 2011 by <ahref="http://domain.invalid/">you</a>
    14.             {% endblock %} 
    15.         </div> 
    16.     </body> 
    17. </html> 
    <!DOCTYPE html>
    <html>
        <head>
            {% block head %}
                <link rel="stylesheet" href="style.css" />
                <title>{% block title %}{% endblock %} - My Webpage</title>
            {% endblock %}
        </head>
        <body>
            <div id="content">{% block content %}{% endblock %}</div>
            <div id="footer">
                {% block footer %}
                    © Copyright 2011 by <a href="http://domain.invalid/">you</a>.
                {% endblock %}
            </div>
        </body>
    </html>
    我们定义了4个block块,分别是 block head, block title, block content, block footer
    注意
    1、block是可以嵌套的。
    2、block可以设置默认值(中间包围的内容),如果子模板里没有覆盖,那就直接显示默认值。比如block footer ,大部分页面你不需要修改(省力),但你需要到时候仍可以方便到修改(灵活)
    下面我看下 子模板应该怎么定义。
    1. {% extends "base.html" %} 
    2.  
    3. {% block title %}Index{% endblock %} 
    4. {% block head %} 
    5.     {{ parent() }} 
    6.     <styletype="text/css"> 
    7.         .important { color: #336699; } 
    8.     </style> 
    9. {% endblock %} 
    10. {% block content %} 
    11.     <h1>Index</h1> 
    12.     <pclass="important"> 
    13.         Welcome on my awesome homepage. 
    14.     </p> 
    15. {% endblock %} 
    {% extends "base.html" %}
    
    {% block title %}Index{% endblock %}
    {% block head %}
        {{ parent() }}
        <style type="text/css">
            .important { color: #336699; }
        </style>
    {% endblock %}
    {% block content %}
        <h1>Index</h1>
        <p class="important">
            Welcome on my awesome homepage.
        </p>
    {% endblock %}
    注意 {% extends "base.html" %} 必须是第一个标签。其中 block footer就没有定义,所以显示父模板中设置的默认值
    如果你需要增加一个block的内容,而不是全覆盖,你可以使用 parent函数
    1. {% block sidebar %} 
    2.     <h3>Table Of Contents</h3> 
    3.     ... 
    4.     {{ parent() }} 
    5. {% endblock %} 
    {% block sidebar %}
        <h3>Table Of Contents</h3>
        ...
        {{ parent() }}
    {% endblock %}
    extends标签只能有一个,所以你只能有一个父模板,但有种变通到方法来达到重用多个模板到目的,具体参见手册的use标签

    HTML转义

    主要是帮助转义 尖括号等  <, >,  &,  " 可以有两种办法。一种是用标签,另一种是使用过滤器。其实TWIG内部就是调用 php 的htmlspecialchars 函数
    1. {{ user.username|e }} 
    2. {{ user.username|e('js') }} 
    3.  
    4. {% autoescape true %} 
    5.     Everything will be automatically escaped in this block 
    6. {% endautoescape %} 
    {{ user.username|e }}
    {{ user.username|e('js') }}
    
    {% autoescape true %}
        Everything will be automatically escaped in this block
    {% endautoescape %}
    因为{{是TWIG的操作符,如果你需要输出两个花括号,最简单到办法就是
    1. {{ '{{' }} 
    {{ '{{' }}
    还可以使用 raw 标签和raw 过滤器,详细参考手册
    1. {% raw %} 
    2.     <ul> 
    3.     {% for item in seq %} 
    4.         <li>{{ item }}</li> 
    5.     {% endfor %} 
    6.     </ul> 
    7. {% endraw %} 
    {% raw %}
        <ul>
        {% for item in seq %}
            <li>{{ item }}</li>
        {% endfor %}
        </ul>
    {% endraw %}

    macros宏

    宏有点类似于函数,常用于输出一些html标签。
    这里有个简单示例,定义了一个输出input标签的宏。
    1. {% macro input(name, value, type, size) %} 
    2.     <inputtype="{{ type|default('text') }}"name="{{ name }}"value="{{ value|e }}"size="{{ size|default(20) }}"/> 
    3. {% endmacro %} 
    {% macro input(name, value, type, size) %}
        <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
    {% endmacro %}
    宏参数是没有默认值的,但你可以通过default过滤器来实现。
    一般来说宏会定义在其他到页面,然后通过import标签来导入,
    1. {% import "forms.html" as forms %} 
    2.  
    3. <p>{{ forms.input('username') }}</p> 
    {% import "forms.html" as forms %}
    
    <p>{{ forms.input('username') }}</p>
    你也可以只导入一个文件中部分宏,你还可以再重命名。
    1. {% from 'forms.html' import input as input_field, textarea %} 
    2.  
    3. <dl> 
    4.     <dt>Username</dt> 
    5.     <dd>{{ input_field('username') }}</dd> 
    6.     <dt>Password</dt> 
    7.     <dd>{{ input_field('password', type='password') }}</dd> 
    8. </dl> 
    9. <p>{{ textarea('comment') }}</p> 
    {% from 'forms.html' import input as input_field, textarea %}
    
    <dl>
        <dt>Username</dt>
        <dd>{{ input_field('username') }}</dd>
        <dt>Password</dt>
        <dd>{{ input_field('password', type='password') }}</dd>
    </dl>
    <p>{{ textarea('comment') }}</p>
    上面的代码表示 从forms.html中导入了 input 和 textarea宏,并给input重命名为input_field。

    表达式

    TWIG允许你在任何地方使用表达式,他的规则和PHP几乎一模一样,就算你不会PHP 仍然会觉得很简单。
    最简单的有
    字符串:“hello world”  或者 'hello world' 
    数字:42 或者 42.33
    数组:['a','b','c']
    哈希:{'a':'av', 'b':'bv'} 其中keys 可以不要引号 也可以是数字 还可以是一个表达式,比如{a:'av', b:'bv'} {1:'1v', 2:'2v'}  {1+2:'12v'}
    逻辑: true 或者 false
    最后还有null
    你可以嵌套定义
    1. {% set foo = [1, {"foo": "bar"}] %} 
    {% set foo = [1, {"foo": "bar"}] %}
    运算符
    包括数字运算+ - * /  %(求余数)  //(整除) **(乘方)
    1. <p>{{ 2 * 3 }}=6 
    2. <p>{{ 2 * 3 }}=8 
    <p>{{ 2 * 3 }}=6
    <p>{{ 2 * 3 }}=8
    逻辑运算 and or  not
    比较运算 > < >= <= == !=
    包含运算 in 以下的代码会返回 true
    1. {{ 1 in [1, 2, 3] }} 
    2. {{ 'cd' in 'abcde' }} 
    {{ 1 in [1, 2, 3] }}
    {{ 'cd' in 'abcde' }}
    测试运算 is 这个不用多说 直接看代码
    1. {{ name is odd }} 
    2. {% if loop.index is divisibleby(3) %} 
    3. {% if loop.index is not divisibleby(3) %} 
    4. {# is equivalent to #} 
    5. {% if not (loop.index is divisibleby(3)) %} 
    {{ name is odd }}
    {% if loop.index is divisibleby(3) %}
    {% if loop.index is not divisibleby(3) %}
    {# is equivalent to #}
    {% if not (loop.index is divisibleby(3)) %}
    其他操作符
    .. 建立一个指定开始到结束的数组,他是range函数的缩写,具体参看手册
    1. <PREclass=htmlname="code">{% for i in 0..3 %} 
    2.     {{ i }}, 
    3. {% endfor %}</PRE> 
    4. <PRE></PRE> 
    1. {% for i in 0..3 %}
    2. {{ i }},
    3. {% endfor %}
    {% for i in 0..3 %}
        {{ i }},
    {% endfor %}
    | 使用一个过滤器
    1. {# output will be HELLO #} 
    2. {{ "hello"|upper }} 
    {# output will be HELLO #}
    {{ "hello"|upper }}
    ~ 强制字符串连接
    1. {{ "Hello " ~ name ~ "!" }} 
    {{ "Hello " ~ name ~ "!" }}
    ?: 三元操作符
    1. {{ foo ? 'yes' : 'no' }} 
    {{ foo ? 'yes' : 'no' }}
    . [] 得到一个对象的属性,比如以下是相等的。
    1. {{ foo.bar }} 
    2. {{ foo['bar'] }} 
    {{ foo.bar }}
    {{ foo['bar'] }}
    你还可以在一个字符串内部插入一个表达式,通常这个表达式是变量。 格式是 #{表达式}
    1. {{ "foo #{bar} baz" }} 
    2. {{ "foo #{1 + 2} baz" }} 
    {{ "foo #{bar} baz" }}
    {{ "foo #{1 + 2} baz" }}

    空白控制

    和 php一样,在TWIG模板标签之后的第一个换行符会被自动删掉,其余的空白(包括 空格 tab 换行等)都会被原样输出。
    使用spaceless标签就可以删除这些HTML标签之间的空白
    1. {% spaceless %} 
    2.     <div> 
    3.         <strong>foo</strong> 
    4.     </div> 
    5. {% endspaceless %} 
    6.  
    7. {# output will be <div><strong>foo</strong></div> #} 
    {% spaceless %}
        <div>
            <strong>foo</strong>
        </div>
    {% endspaceless %}
    
    {# output will be <div><strong>foo</strong></div> #}
    使用-操作符,可以很方便的删除TWIG标签之前或之后与html标签之间的空白。
    1. {% set value = 'no spaces' %} 
    2. {#- No leading/trailing whitespace -#} 
    3. {%- if true -%} 
    4.     {{- value -}} 
    5. {%- endif -%} 
    6.  
    7. {# output 'no spaces' #} 
    {% set value = 'no spaces' %}
    {#- No leading/trailing whitespace -#}
    {%- if true -%}
        {{- value -}}
    {%- endif -%}
    
    {# output 'no spaces' #}
    1. {% set value = 'no spaces' %} 
    2. <li>    {{- value }}    </li> 
    3.  
    4. {# outputs '<li>no spaces    </li>' #} 
    {% set value = 'no spaces' %}
    <li>    {{- value }}    </li>
    
    {# outputs '<li>no spaces    </li>' #}
  • 相关阅读:
    爬取豆瓣分页照片下载
    css布局:三列布局,中间内容优先加载
    解决在IE下label中IMG图片无法选中radio的几个方法
    CSS架构:最新最佳实践
    JavaScript登陆弹窗,可拖拽
    网站变成灰色的代码
    5个jQuery的备选轻量级移动客户端开发(Mobile development)类库
    jQuery 底部漂浮导航当前位置突出 + 锚点平滑滚动
    Exchange 2007 自定义传输规则
    基于jQuery打造TabPanel
  • 原文地址:https://www.cnblogs.com/Kakasi/p/2881022.html
Copyright © 2011-2022 走看看