《Flasky Web開發三》模板

模板是一個包含響應文本的文件,其中包含用佔位變量表示的動態部分。使用真實值替換變量,再返回最終得到的響應字符串,叫渲染。爲了渲染模板,Flask使用Jinja2的模板引擎。

3.1 Jinja2模板引擎

       最簡單的Jinja2模板是一個包含響應文本的文件

       index.html

       <h1>Hello World!</h1>

       user.html

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

3.1.1 渲染模板

       Flask默認在程序文件夾中的templates子文件夾中找模板。

       C:\Windows\System32\flasky\templates

       hello.py

       from flask import Flask, render_template

 

app = Flask(__name__)

 

@app.route('/')

def index():

           return render_template('index.html')

 

@app.route('/user/<name>')

def user(name):

return render_template('user.html', name=name)

       Flask提供的render_template函數第一個參數爲模板的文件名,第二個參數爲鍵值對(模板中變量對應的真實值)

3.1.2 變量

       {{ name }}結構表示一個變量,是一種特殊的佔位符。Jinja2支持所有類型的變量。

              <p>A value from a dictionary:{{ mydict[‘key’] }}.</p>

              <p>A value from a list:{{ mylist[‘3’] }}.</p>

              <p>A value from an object’s method:{{ myobj.somemethod() }}.</p>

       可以使用過濾器修改變量,過濾器名添加在變量名後,中間豎線分隔

              Hello,{{ name|capitalize }}

              以首字母大寫形式顯示變量name的值

       常用過濾器

              safe:渲染值時不轉義,注意:不可在不可信的值上使用safe過濾器

              capitalize:值的首字母轉換成大寫,其他小寫

              lower:值轉換成小寫

              upper:值轉換成大寫

              title:值中每個單詞的首字母轉換成大寫

              trim:把值的首尾空格去掉

              striptags:渲染之前把值中所有的HTML標籤刪掉

3.1.3 控制結構

       3.1.3.1 條件控制語句

              {% if user %}

                     Hello,{{ user }}!

              {% else %}

                     Hello,Stranger!

              {% endif %}

       3.1.3.2 for循環

              <ul>

{% for comment in comments %}

                            <li>{{ comment }}</li>

                     {% endfor %}

              </ul>

       3.1.3.3 宏

              {% macro render_comment(comment) %}

                     <li>{{ comment }}</li>

              {% end macro %}

              <ul>

                     {% for comment in comments %}

                            {{ render_comment(comment) }}

                     {% endfor %}}

              </ul>

              爲了重複使用宏,可單獨保存在文件中,使用時在模板中導入

              {% import ‘macro.html’ as macros %}

              <ul>

                     {% for comment in comments %}

                            {{ macros.render_comment(comment) }}

                     {% endfor %}

              </ul>

       3.1.3.4 重複使用的模板代碼片段

              寫入單獨的文件,再包含再所有模板中

              {% include ‘common.html’ %}

       3.1.3.5 模板繼承

              基模板

base.html

              <html>

<head>

       {% block head %}

       <title>{% block title %}{% endblock %} - My Application</title>

       {% endblock %}

</head>

<body>

       {% block body %}

       {% endblock %}

</body>

</html>

基模板的衍生模板

{% extends “base.html” %}

{% block title %}Index{% endblock %}     //title包含在head所以要先聲明

{% block head %}

       {{ super() }}

       <style>

       </style>

{% endblock %}

{% block body %}

<h1>Hello,World!</h1>

{% endblock %}

extends指令聲明模板衍生自base.html。基模板的3個塊被重新定義,其中head塊的內容使用super()獲取原來的內容。

3.2 使用Flask-Bootstrap集成Twitter Bootstrap

       Bootstrap是Twitter開發的一個開源客戶端框架,不涉及服務器。服務器需要提供引用了Bootstrap層疊樣式表(CSS)和JavaScript文件的HTML響應。

       我們使用Flask-Bootstrap的Flask擴展集成Bootstrap

       pip stall flask-bootstrap

       3.2.1 Flask擴展的初始化

from flask_bootstrap import Bootstrap

 

bootstrap = Bootstrap(app)

 

templates/user.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">

    <div class="page-header">

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

    </div>

</div>

{% endblock %}

3.3 自定義錯誤頁面

       Flask允許程序使用給予模板的自定義錯誤頁面。常見錯誤代碼:404,客戶端請求未知頁面或路由時顯示;500,有未處理的異常時顯示。

       @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

       1.templates/user.html

       {% extends "base.html" %}

 

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

 

{% block page_content %}

<div class="page-header">

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

</div>

{% endblock %}

2. .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 %}

3.4 鏈接

       具有多個路由的程序都需要鏈接來連接不同頁面。直接編寫簡單路由的URL鏈接,在包含可變部分的動態路由會很困難,而且對路由產生不必要的依賴關係。

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

       url_for()函數最簡單的用法是以視圖函數名作爲參數,返回URL。例如:url_for(‘index’)得到的結果/;url_for(‘index’,_external=True)返回絕對地址,http://localhost:5000/。

       url_for()生成動態地址時,將動態部分作爲關鍵字參數傳入。url_for(‘user’,name=’john’,_external=True)返回http://localhost:5000/user/john。還可以將額外參數添加到查詢字符串,url_for(‘user’,page=2)返回/?page=2

3.5 靜態文件

       Flask默認到程序根目錄中名爲static的子目錄中尋找靜態文件

       在基模板中放置favicon.ico圖標

{% 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.6 Flask-Moment本地化日期和時間

       安裝pip install flask-moment

       1.hello.py

       from datetime import datetime

from flask_moment import Moment

 

moment = Moment(app)

 

@app.route('/')

def index():

return render_template('index.html', current_time=datetime.utcnow())

       2.templates/base.html

       {% block scripts %}

{{ super() }}

{{ moment.include_moment() }}

{% endblock %}

3.templates/index.html

<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>

<p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>

 

發佈了36 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章