<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ![模板](https://box.kancloud.cn/2016-04-15_57105525f215e.png) # 模板 盡管Flask并不強迫你使用某個特定的模板語言,它還是默認你會使用Jinja。在Flask社區的大多數開發者使用Jinja,并且我建議你也跟著做。有一些插件允許你用其他模板語言進行替代(比如[Flask-Genshi](http://pythonhosted.org/Flask-Genshi/)和[Flask-Mako](http://pythonhosted.org/Flask-Mako/)),但除非你有充分理由(不懂Jinja可不是一個充分的理由!),否則請保持那個默認的選項;這樣你會避免浪費很多時間來焦頭爛額。 > **注意** > 幾乎所有提及Jinja的資源講的都是Jinja2。Jinja1確實曾存在過,但在這里我們不會講到它。當你看到Jinja時,我們討論的是這個Jinja: http://jinja.pocoo.org/ ## Jinja快速入門 **Jinja**文檔在解釋這門語言的語法和特性這方面做得很棒。在這里我不會啰嗦一遍,但還是會再一次向你強調下面一點: {% raw %} > Jinja有兩種定界符。`{% ... %}`和`{{ ... }}`。前者用于執行像for循環或賦值等語句,后者向模板輸出一個表達式的結果。 {% endraw %} > **參見**: http://jinja.pocoo.org/docs/templates/#synopsis ## 怎樣組織模板 所以要將模板放進我們的應用的哪里呢?如果你是從頭開始閱讀的本文,你可能注意到了Flask在對待你如何組織項目結構的事情上十分隨意。模板也不例外。你大概也已經注意到,總會有一個放置文件的推薦位置。記住兩點。對于模板,這個最佳位置是放在包文件夾下。 ``` myapp/ __init__.py models.py views/ templates/ static/ run.py requirements.txt ``` 讓我們打開模板文件夾看看。 ``` templates/ layout.html index.html about.html profile/ layout.html index.html photos.html admin/ layout.html index.html analytics.html ``` **模板**的結構平行于對應的路由的結構。對應于路由*myapp.com/admin/analytics*的模板是*templates/admin/analytics.html*。這里也有一些額外的模板不會被直接渲染。*layout.html*文件就是用于被其他模板繼承的。 ## 繼承 就像蝙蝠俠一樣,一個組織良好的模板文件夾也離不開繼承帶來的好處。**基礎模板**通常定義了一個適用于所有的*子模板*的主體結構。在我們的例子里,*layout.html*是一個基礎模板,而其他的*html*文件都是子模板。 通常,你會有一個頂級的*layout.html*定義你的應用的主體布局,外加站點的每一個節點也有自己的一個*layout.html*。如果再看一眼上面的文件夾結構,你會看到一個頂級的*myapp/templates/layout.html*,以及*myapp/templates/profile/layout.html*和*myapp/templates/admin/layout.html*。后兩個文件繼承并修改第一個文件。 {% raw %} 繼承是通過`{% extends %}`和`{% block %}`標簽實現的。在雙親模板中,你可以定義要給子模板處理的block。 {% endraw %} _myapp/templates/layout.html_ ``` <!DOCTYPE html> <html lang="en"> <head> <title>{% block title %}{% endblock %}</title> </head> <body> {% block body %} <h1>這個標題在雙親模板中定義</h1> {% endblock %} </body> </html> ``` 在子模板中,你可以拓展雙親模板并定義block里面的內容。 _myapp/templates/index.html_ ``` {% extends "layout.html" %} {% block title %}Hello world!{% endblock %} {% block body %} {{ super() }} <h2>這個標題在子模板中定義</h2> {% endblock %} ``` `super()`函數讓我們在子模板里加載雙親模板中這個block的內容。 > **參見** > 若想了解更多關于繼承的內容,請移步到Jinja模板繼承方面的文檔。 > <http://jinja.pocoo.org/docs/templates/#template-inheritance> ## 創建宏 憑借將反復出現的代碼片段抽象成**宏**,我們可以實現DRY原則(Don't Repeat Yourself)。在撰寫用于應用的導航功能的HTML時,我們可能會需要給“活躍”鏈接(比如,到當前頁面的鏈接)一個不同的類。如果沒有宏,我們將不得不使用一大堆if/else語句來從每個鏈接中過濾出“活躍”鏈接。 宏提供了模塊化模板代碼的一種方式;它們就像是函數一樣。讓我們看一下如何使用宏來標記活躍鏈接。 myapp/templates/layout.html ``` {% from "macros.html" import nav_link with context %} <!DOCTYPE html> <html lang="en"> <head> {% block head %} <title>我的應用</title> {% endblock %} </head> <body> <ul class="nav-list"> {{ nav_link('home', 'Home') }} {{ nav_link('about', 'About') }} {{ nav_link('contact', 'Get in touch') }} </ul> {% block body %} {% endblock %} </body> </html> ``` 現在我們調用了一個尚未定義的宏 - `nav_link` - 并傳遞兩個參數給它:一個目標(比如目標視圖的函數名)和我們想要展示的文本。 > **注意** > 你可能注意到了我們在import語句中加入了**with context**。Jinja的**上下文(context)**包括了通過`render_template()`函數傳遞的參數以及在我們的Python代碼的Jinja環境上下文。這些變量能夠被用于模板的渲染。 > {% raw %} > 一些變量是我們顯式傳遞過去的,比如`render_template("index.html", color="red")`,但還有些變量和函數是Flask自動加入到上下文的,比如`request`,`g`和`session`。使用了`{% from ... import ... with context %}`,我們告訴Jinja讓所有的變量也在宏里可用。 {% endraw %} > **參見** > * 所有的全局變量都是由Flask傳遞給Jinja上下文的: http://flask.pocoo.org/docs/templating/#standard-context > * 通過上下文處理器(context processors),我們可以增加傳遞給Jinja上下文的變量和函數: http://flask.pocoo.org/docs/templating/#context-processors 是時候定義模板中用的`nav_link`宏了。 myapp/templates/macros.html ``` {% macro nav_link(endpoint, text) %} {% if request.endpoint.endswith(endpoint) %} <li class="active"><a href="{{ url_for(endpoint) }}">{{text}}</a></li> {% else %} <li><a href="{{ url_for(endpoint) }}">{{text}}</a></li> {% endif %} {% endmacro %} ``` 現在我們已經在*myapp/templates/macros.html*中定義了一個宏。我們所做的,就是使用Flask的`request`對象 - 默認在Jinja上下文中可用 - 來檢查當前路由是否是傳遞給`nav_link`的那個路由參數。如果是,我們就在目標鏈接指向的頁面上,于是可以標記它為活躍的。 > **注意** > `from x import y`語句中要求x是相對于y的相對路徑。如果我們的模板位于*myapp/templates/user/blog.html*,我們需要使用`from "../macros.html" import nav_link with context`。 ## 自定義過濾器 Jinja過濾器是在渲染成模板之前,作用于`{{ ... }}`中的表達式的值的函數。 ``` <h2>{{ article.title|title }}</h2> ``` 在這個代碼中,`title`過濾器接受`article.title`并返回一個標題格式的文本,用于輸出到模板中。它的語法,以及功能,皆一如Unix中修改程序輸出的“管道”一樣。 > **參見** > 除了`title`,還有許許多多別的內建的過濾器。在這里可以看到完整的列表: http://jinja.pocoo.org/docs/templates/#builtin-filters 我們可以自定義用于Jinja模板的過濾器。作為例子,我們將實現一個簡單的`caps`過濾器來使字符串中所有的字母大寫。 > **注意** > Jinja已經有一個`upper`過濾器能實現這一點,還有一個`capitalize`過濾器能大寫第一個字符并小寫剩余字符。這些過濾器還能處理Unicode轉換,不過我們的這個例子將只專注于闡述相關概念。 我們將在*myapp/util/filters.py*中定義我們的過濾器。這個`util`包可以用來放置各種雜項。 myapp/util/filters.py ``` from .. import app @app.template_filter() def caps(text): """Convert a string to all caps.""" return text.uppercase() ``` 在上面的代碼中,通過`@app.template_filter()`裝飾器,我們能將某個函數注冊成Jinja過濾器。默認的過濾器名字就是函數的名字,但是通過傳遞一個參數給裝飾器,你可以改變它: ``` @app.template_filter('make_caps') def caps(text): """Convert a string to all caps.""" return text.uppercase() ``` 現在我們可以在模板中調用`make_caps`而不是`caps`:`{{ "hello world!"|make_caps }}`。 為了讓我們的過濾器在模板中可用,我們僅需要在頂級*\_\_init\_\_.py*中import它。 myapp/\_\_init\_\_.py ``` # 確保app已經被初始化以免導致循環import from .util import filters ``` ## 總結 * 使用Jinja作為模板語言。 {% raw %} * Jinja有兩種定界符:`{% ... %}`和`{{ ... }}`。前者用于執行類似循環或賦值的語句,后者向模板輸出表達式求值的結果。 {% endraw %} * 模板應該放在*myapp/templates/* - 一個在應用文件夾里面的目錄。 * 我建議*template/*文件夾的結構應該與應用URL結構一一對應。 * 你應該在*myapp/templates*以及站點的每一部分放置一個*layout.html*作為布局模板。后者是前者的拓展。 * 可以用模板語言寫類似于函數的宏。 * 可以用Python代碼寫應用在模板中的過濾器函數。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看