Flask_0x02 模板

0x1 Jinja2

  1.1 Jinja2模板引擎

    模板是包含响应文本的文件,其中包含用站位变量表示的动态部分

    templates/user.html

<h1>Hello, {{ name }}!</h1>

    Flask提供render_template函数把Jinja2模板引擎集成到程序中

    渲染模板

from flask import Flask, render_template
#...
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

    Jinja2能识别所有类型的变量

<p>A value from a dictionary: {{ mydict['key'] }}.</p>
<p>A value from a list: {{ mylist[3] }}.</p>
<p>A value from a list,with a variable index: {{ mylist[myintvar] }}.</p>
<p>A value from an object's method: {{ myobj.somemethod() }}.</p>

    可以使用过滤器修改变量

Hello,{{ name|capitalize }}

Jinjia2变量过滤器:http://jinja.pocoo.org/docs/2.9/templates/#builtin-filters
safe 渲染值时不转义 capitalize 首字母大写,其他小写 lower 转换小写 upper 转换大写 title 把值中每个单词首字母转换成大写 trim 去掉值的首尾空格 striptags 渲染前把值中所有HTML标签删掉

  1.2 控制结构

{% if user %}
    Hello, {{ user }}
{% else %}
    Hello, Stranger!
{% endif %}
<ul>
{% for comment in comments %}
    <li>{{ comment }}</li>
{% endfor %}
</ul>

    宏

{% macro render_comment(comment) %}
    <li>{{ comment }}</li>
{% endmacro %}
<ul>
{% for comment in comments %}
    {{ render_comment(comment) }}
{% endfor %}
</ul>

    重复使用宏,可以将其保存在单独的文件中

{% import 'macros.html' as macros %}
<ul>
  {% for comment in comments %}
      {{ macros.render_comment(comment) }}
  {% endfor %}
</ul>

    继承,先创建名为base.html的模板

<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - MyApplication</title>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

    block标签定义的元素可在衍生模板中修改

{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
    <style>
    </style>
{% endblock %}
{% block body %}
<h1>Hello, World</h1>
{% endblock %}

    使用super()获取原来模板中的内容

 

0x2 Flask-Bootstrap & 错误页面

  2.1 Flask-Bootstrap

    git checkout 3b

    Bootstrap官方文档 http://getbootstrap.com/

(venv) $ pip install flask-bootstrap

    初始化Flask-Bootstrap

from flask.ext.bootstrap import Bootstrap
#...
bootstrap = Bootstrap(app)

    templates/user.html 使用Flask-Bootstrap的模板

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-

collap    se">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
     </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    <div class="page-header">
        <h1>Hello, {{ name }}!</h1>
    </div>
</div>
{% endblock %}

如果程序需要向已经有内容的块中添加新内容,必须使用Jinja2提供的super()函数
如果要在衍生模板中添加新的js文件

{% block scripts %}
{{ super() }}
<script type="text/javascript" src="my-script.js"></script>
{% endblock %}

  2.2 错误页面
    git checkout 3c

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500

    templates/base.html

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-

collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}

templates/404.html
{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}

templates/user.html
{% extends "base.html" %}

{% block title %}Flasky{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}
View Code

0x3 链接 & 静态文件 & Flask-Moment

  3.1 链接

        git checkout 3d

    Flask提供了url_for()可以使用程序URL映射中保存的信息生成URL

    使用url_for()生成动态地址时,将动态部分作为关键字参数传入

url_for('user',name='john',_external=True)的返回结果是http://localhost:5000/user/john

    传入url_for()的关键字参数能将任何额外参数添加到查询字符串中

url_for('index',page=2)的返回结果是/?page=2

  3.2 静态文件

    调用url_for('user',name='john',_external=True)的返回结果是http://xx/static/css/styles.css

    templates/base.html:定义收藏夹图标

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}

  3.3 Flask-Moment本地化日期和时间

    git checkout 3e

    学习moment.js提供的全部格式化选项:http://momentjs.com/docs/#/displaying

(venv) $ pip install flask-moment

    初始化Flask-moment

from flask.ext.moment import Moment
moment = Moment(app)

   templates/base.html:引入moment.js库

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

   代码把变量current_time传入模板进行渲染

from datetime import datetime

@app.route('/')
def index():
    return render_template('index.html',current_time=datetime.utcnow())

    模板中渲染current_time

    templates/index.html:使用Flask-Moment渲染时间戳

<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>

    format('LLL')根据客户端电脑中的时区和时域设置渲染日期时间,L到LLLL对应不同复杂度
    format() 还可以接受自定义格式说明符
    fromNow()渲染相对应时间戳,指定refresh后,其内容随时间推移而更新

    语言可在模板中选择,把语言代码传给lang()

{{ moment.lang('es') }}

 

posted @ 2017-01-22 21:58  Hxxxxx  阅读(251)  评论(0编辑  收藏  举报