<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 模板語法規則 ### Nunjucks模板語法 ## 變量 變量會從模板上下文獲取,如果你想顯示一個變量可以: ~~~ {{ username }} ~~~ 會從上下文查找 username 然后顯示,可以像 javascript 一樣獲取變量的屬性 (可使用點操作符或者中括號操作符): ~~~ {{ foo.bar }} {{ foo["bar"] }} ~~~ 如果變量的值為 undefined 或 null 將不顯示,引用到 undefined 或 null 對象也是如此 (如 foo 為 undefined,{{ foo }}, {{ foo.bar }}, {{ foo.bar.baz }} 也不顯示)。 ~~~ {{ foo | title }} {{ foo | join(",") }} {{ foo | replace("foo", "bar") | capitalize }} ~~~ 第三個例子展示了鏈式過濾器,最終會顯示 "Bar",第一個過濾器將 "foo" 替換成 "bar",第二個過濾器將首字母大寫。 Nunjucks 提供了一些內置的過濾器,你也可以自定義過濾器。 ~~~ {% block header %} This is the default content {% endblock %} <section class="left"> {% block left %}{% endblock %} </section> <section class="right"> {% block right %} This is more content {% endblock %} </section> ~~~ 然后再寫一個模板繼承他 ~~~ {% extends "parent.html" %} {% block left %} This is the left side! {% endblock %} {% block right %} This is the right side! {% endblock %} ~~~ 以下為渲染結果 ~~~ This is the default content <section class="left"> This is the left side! </section> <section class="right"> This is the right side! </section> ~~~ 你可以將繼承的模板設為一個變量,這樣就可以動態指定繼承的模板。這個變量既可以是個指向模板文件的字符串,也可以是個模板編譯后所生成的對象(需要添加上下文環境)。因此你可以通過設置上下文變量,從而在渲染時動態地改變所要繼承的模板。 ~~~ {% extends parentTemplate %} ~~~ 繼承功能使用了 extends 和 block 標簽,jinja2 文檔中有更細節的描述。 ## super 你可以通過調用super從而將父級區塊中的內容渲染到子區塊中。如果在前面的例子中你的子模板是這樣的: ~~~ {% block right %} {{ super() }} Right side! {% endblock %} ~~~ 這個區塊的渲染結果將是: ~~~ This is more content Right side! ~~~ ### 自定義。 ## **if** if 為分支語句,與 javascript 中的 if 類似。 ~~~ {% if variable %} It is true {% endif %} ~~~ 如果 variable 定義了并且為 true (譯者注:這里并非布爾值,和 javascript 的處理是一樣的) 則會顯示 "It is true",否則什么也不顯示。 ~~~ {% if hungry %} I am hungry {% elif tired %} I am tired {% else %} I am good! {% endif %} ~~~ 在內聯表達式(inline expression)中也可以使用 if。 ## **for** for 可以遍歷數組 (arrays) 和對象 (dictionaries)。 如果你使用的自定義模板加載器為異步的可查看 asyncEach `var items = [{ title: "foo", id: 1 }, { title: "bar", id: 2}];` ~~~ <h1>Posts</h1> <ul> {% for item in items %} <li>{{ item.title }}</li> {% else %} <li>This would display if the 'item' collection were empty</li> {% endfor %} </ul> ~~~ 上面的示例通過使用items數組中的每一項的title屬性顯示了所有文章的標題。如果items數組是空數組的話則會渲染else語句中的內容。 你還可以遍歷對象: ~~~ var food = { 'ketchup': '5 tbsp', 'mustard': '1 tbsp', 'pickle': '0 tbsp' }; {% for ingredient, amount in food %} Use {{ amount }} of {{ ingredient }} {% endfor %} ~~~ dictsort 過濾器可將對象排序 (new in 0.1.8) 除此之外,Nunjucks 會將數組解開,數組內的值對應到變量 (new in 0.1.8) `var points = [[0, 1, 2], [5, 6, 7], [12, 13, 14]];` ~~~ {% for x, y, z in points %} Point: {{ x }}, {{ y }}, {{ z }} {% endfor %} ~~~ 在循環中可獲取一些特殊的變量 * loop.index: 當前循環數 (1 indexed) * loop.index0: 當前循環數 (0 indexed) * loop.revindex: 當前循環數,從后往前 (1 indexed) * loop.revindex0: 當前循環數,從后往前 (0 based) * loop.first: 是否第一個 * loop.last: 是否最后一個 * loop.length: 總數 ## **asyncEach** > 這個是適用于異步模板,請讀[文檔](http://mozilla.github.io/nunjucks/cn/api.html#asynchronous-support)。 asyncEach 為 for 的異步版本,只有當使用自定義異步模板加載器的時候才使用,否則請不要使用。異步過濾器和擴展也需要他。如果你在循環中使用了異步過濾器的話,Nunjucks就會在內部自動將循環轉換成 asyncEach。 asyncEach 和 for 的使用方式一致,但他支持循環的異步控制。將兩者區分的原因是性能,大部分人使用同步模板,將 for 轉換成原生的 for 語句會快很多。 編譯時 nunjuck 不用關心模板是如何加載的,所以無法決定 include 是同步或異步。這也是為什么Nunjucks無法自動將普通的循環語句轉換成異步循環語句的原因,所以如果你要使用異步模板加載器的話,就需要使用 asyncEach。 > // If you are using a custom loader that is async, you need asyncEach > var env = new nunjucks.Environment(AsyncLoaderFromDatabase, opts); ~~~ <h1>Posts</h1> <ul> {% asyncEach item in items %} {% include "item-template.html" %} {% endeach %} </ul> ~~~ ## **asyncAll** > 這個是適用于異步模板,請讀[文檔](http://mozilla.github.io/nunjucks/cn/api.html#asynchronous-support)。 asyncAll 和 asyncEach 類似,但 asyncAll 會并行的執行,并且每項的順序仍然會保留。除非使用異步的過濾器、擴展或加載器,否則不要使用。 如果你寫了一個 lookup 的過濾器用來從數據庫獲取一些文本,使用 asyncAll 可以并行渲染。 ~~~ <h1>Posts</h1> <ul> {% asyncAll item in items %} <li>{{ item.id | lookup }}</li> {% endall %} </ul> ~~~ 如果 lookup 是一個異步的過濾器,那么可能會比較慢(如從磁盤獲取些數據)。asyncAll 會減少執行的時間,他會并行執行所有的異步操作,當所有的操作完成后才會繼續渲染頁面。 ## **macro** 宏 (macro) 可以定義可復用的內容,類似與編程語言中的函數,看下面的示例: ~~~ {% macro field(name, value='', type='text') %} <div class="field"> <input type="{{ type }}" name="{{ name }}" value="{{ value | escape }}" /> </div> {% endmacro %} ~~~ 現在 field 可以當作函數一樣使用了: ~~~ {{ field('user') }} {{ field('pass', type='password') }} ~~~ 支持關鍵字參數,通過鏈接查看具體使用方式。 還可以從其他模板 import 宏,可以使宏在整個項目中復用。 > **重要:如果你使用異步 API,請注意你 不能 在宏中做任何異步的操作,因為宏只是像函數一樣被簡單地調用。將來我們可能會提供一種異步的宏調用方式,但現在這么使用是不被支持的。** ## **set** set 可以設置和修改變量。 ~~~ {{ username }} {% set username = "joe" %} {{ username }} ~~~ 如果 username 初始化的時候為 "james', 最終將顯示 "james joe"。 可以設置新的變量,并一起賦值。 ~~~ {% set x, y, z = 5 %} ~~~ 如果在頂級作用域使用 set,將會改變全局的上下文中的值。如果只在某個作用域 (像是include或是macro) 中使用,則只會影響該作用域。 同樣地,你也可以使用區塊賦值將一個區塊的內容儲存在一個變量中。 它的語法和標準的set語法相似,只不過你不需要用=。區塊中從頭到{% endset %}之間的內容都會被捕獲,并作為值來使用。 在某些情境下,你可以用這種語法來替代宏: ~~~ {% set standardModal %} {% include 'standardModalData.html' %} {% endset %} <div class="js-modal" data-modal="{{standardModal | e}}"> ~~~ ## **extends** extends 用來指定模板繼承,被指定的模板為父級模板,查看模板繼承。 ~~~ {% extends "base.html" %} ~~~ 你可以將繼承的模板設為一個變量,這樣就可以動態指定繼承的模板。這個變量既可以是個指向模板文件的字符串,也可以是個模板編譯后所生成的對象(需要添加上下文環境)。因此你可以通過設置上下文變量,從而在渲染時動態地改變所要繼承的模板。 ~~~ {% extends parentTemplate %} ~~~ extends也可以接受任意表達式,只要它最終返回一個字符串或是模板所編譯成的對象: ~~~ {% extends name + ".html" %}`. ~~~ ## **block** 區塊(block) 定義了模板片段并標識一個名字,在模板繼承中使用。父級模板可指定一個區塊,子模板覆蓋這個區塊,查看模板繼承。 ~~~ {% block css %} <link rel="stylesheet" href="app.css" /> {% endblock %} ~~~ 可以在循環中定義區塊 ~~~ {% for item in items %} {% block item %}{{ item }}{% endblock %} {% endfor %} ~~~ 子模板可以覆蓋 item 區塊并改變里面的內容。 ~~~ {% extends "item.html" %} {% block item %} The name of the item is: {{ item.name }} {% endblock %} ~~~ 在區塊中,你可以調用特殊的super函數。它會渲染父級區塊中的內容。具體請查看super。 ## **include** include 可引入其他的模板,可以在多模板之間共享一些小模板,如果某個模板已使用了繼承那么 include 將會非常有用。 ~~~ {% include "item.html" %} ~~~ 可在循環中引入模板 ~~~ {% for item in items %} {% include "item.html" %} {% endfor %} ~~~ 這一點可以幫助我們把模板切分成更小的部分,從而使得在瀏覽器上,當我們需要改變頁面時,我們可以渲染這些小部分的模板,而非一整個的大的模板。 include 可以接受任意表達式,只要它最終返回一個字符串或是模板所編譯成的對象: `{% include name + ".html" as obj %}`. 在某些情況下,我們可能希望在模板文件不存在時不要拋出異常。對于這類情況,我們可以使用ignore missing來略過這些異常: ~~~ {% include "missing.html" ignore missing %} ~~~ 被包含的模版自身可以擴展(extends)另一個模版(因此你可以讓一系列相關聯的模版繼承同一種結構)。 一個被包含的模版并不會改變包含它的模版的區塊結構,它有一個分離的繼承樹和塊級命名空間。換言之, 在渲染時,include并不 不是 將被包含模版代碼拉取到包含它的模版中的預處理器。相對的,它對被 包含的模版觸發了一次的分離渲染,然后再將渲染的結果引入。 ## **import** import 可加載不同的模板,可使你操作模板輸出的數據,模板將會輸出宏 (macro) 和在頂級作用域進行的賦值 (使用 set)。 被 import 進來的模板沒有當前模板的上下文,所以無法使用當前模板的變量, 創建一個叫 forms.html 如下所示 ~~~ {% macro field(name, value='', type='text') %} <div class="field"> <input type="{{ type }}" name="{{ name }}" value="{{ value | escape }}" /> </div> {% endmacro %} {% macro label(text) %} <div> <label>{{ text }}</label> </div> {% endmacro %} ~~~ 我們可以 import 這個模板并將模板的輸出綁定到變量 forms 上,然后就可以使用這個變量了: ~~~ {% import "forms.html" as forms %} {{ forms.label('Username') }} {{ forms.input('user') }} {{ forms.label('Password') }} {{ forms.input('pass', type='password') }} ~~~ 也可以使用 from import 從模板中 import 指定的值到當前的命名空間: ~~~ {% from "forms.html" import input, label as description %} {{ description('Username') }} {{ input('user') }} {{ description('Password') }} {{ input('pass', type='password') }} ~~~ import 可以接受任意表達式,只要它最終返回一個字符串或是模板所編譯成的對象: `{% import name + ".html" as obj %}`. ## **raw** 如果你想輸出一些 Nunjucks 特殊的標簽 (如 {{),可以使用 {{),可以使用` {% raw %}` 將所有的內容輸出為純文本。 ## **filter** filter區塊允許我們使用區塊中的內容來調用過濾器。不同于使用|語法,它會將區塊渲染出的內容傳遞給過濾器。 ~~~ {% filter title %} may the force be with you {% endfilter %} {% filter replace("force", "forth") %} may the force be with you {% endfilter %} ~~~ 切記:你不能在這些區塊中進行任何異步操作。 ## **call** call區塊允許你使用標簽之間的內容來調用一個宏。這在你需要給宏傳入大量內容時是十分有用的。在宏中,你可以通過caller()來獲取這些內容。 ~~~ {% macro add(x, y) %} {{ caller() }}: {{ x + y }} {% endmacro%} {% call add(1, 2) -%} The result is {%- endcall %} ~~~ 上面的例子將會輸出"The result is: 3"。 ~~~ {{ foo(1, 2, bar=3, baz=4) }} ~~~ bar 和 baz 為關鍵字參數,Nunjucks 將他們轉換成一個對象作為最后一個參數傳入,等價于 javascript 的如下調用: ~~~ foo(1, 2, { bar: 3, baz: 4}) ~~~ 因為這使一個標準的調用轉換,所以適用于所有的符合預期的函數和過濾器。查看 API 章節獲得更多信息。 定義宏的時候也可以使用關鍵字參數,定義參數值時可設置默認值。Nunjucks 會自動將關鍵字參數與宏里定義的值做匹配。 ~~~ {% macro foo(x, y, z=5, w=6) %} {{ x }}, {{ y }}, {{ z }}, {{ w}} {% endmacro %} {{ foo(1, 2) }} -> 1, 2, 5, 6 {{ foo(1, 2, w=10) }} -> 1, 2, 5, 10 ~~~ 在宏中還可以混合使用位置參數 (positional arguments) 和關鍵字參數。如示例,你可以將位置參數用作關鍵字參數: ~~~ {{ foo(20, y=21) }} -> 20, 21, 5, 6 ~~~ 你還可以用位置參數來替換關鍵字參數: ~~~ {{ foo(5, 6, 7, 8) }} -> 5, 6, 7, 8 ~~~ 如下示例,你可以跳過 ("skip") 位置參數: ~~~ {{ foo(8, z=7) }} -> 8, , 7, 6 {# Loop through all the users #} {% for user in users %}...{% endfor %} {% for i in [1,2,3,4,5] -%} {{ i }} {%- endfor %} ~~~ 上面準確的輸出為 "12345",`-%} `會去除標簽右側的空白字符,`{%-` 會去除標簽之前的空白字符。 ## **運算 (Math)** Nunjucks 支持運算 (但盡量少用,把邏輯放在代碼中),可使用以下操作符: * Addition: + * Subtraction: - * Division: / * Division and integer truncation: // * Division remainder: % * Multiplication: * * Power: ** 可以如下使用: ~~~ {{ 2 + 3 }} (outputs 5) {{ 10/5 }} (outputs 2) {{ numItems*2 }} ~~~ 比較 (Comparisons) * == * === * != * !== * > * >= * < * <= Examples: ~~~ {%-` 會去除標簽之前的空白字符。 ## 表達式 你可以使用和 javascript 一樣的字面量。 * Strings: `"How are you?"`, `'How are you?'` * Numbers: `40`, `30.123` * Arrays: `[1, 2, "array"]` * Dicts: `{ one: 1, two: 2 }` * Boolean: `true`, `false` ### 運算 (Math) Nunjucks 支持運算 (但盡量少用,把邏輯放在代碼中),可使用以下操作符: * Addition: `+` * Subtraction: `-` * Division: `/` * Division and integer truncation: `//` * Division remainder: `%` * Multiplication: `*` * Power: `**` 可以如下使用: ```jinja {{ 2 + 3 }} (outputs 5) {{ 10/5 }} (outputs 2) {{ numItems*2 }} ~~~ ## **比較 (Comparisons)** * == * === * != * !== * > * >= * < * <= Examples: ~~~ {% if numUsers < 5 %}...{% endif %} {% if i == 0 %}...{% endif %} ~~~ ## Logic * and * or * not * 可使用大括號來分組 Examples: ~~~ {% if users and showUsers %}...{% endif %} {% if i == 0 and not hideFirst %}...{% endif %} {% if (x < 5 or y < 5) and foo %}...{% endif %} ~~~ ## **If 表達式** 和 javascript 的三元運算符 (ternary operator) 一樣,可使用 if 的內聯表達式: ~~~ {{ "true" if foo else "false" }} ~~~ 當 foo 為 true 的時候最終輸出 "true" 否則為 "false",對于獲取默認值的時候非常有用: ~~~ {{ baz(foo if foo else "default") }} ~~~ 函數調用 (Function Calls) 如果你傳入一個函數,則可以直接調用 ~~~ {{ foo(1, 2, 3) }} ~~~ ~~~ {{ /^foo.*/ }} {{ /bar$/g }} ~~~ 正則表達式所支持的標志如下。查閱Regex on MDN以獲取更多信息。 * g: 應用到全局 * i: 不區分大小寫 * m: 多行模式 * y: 粘性支持(sticky) ## **自動轉義 (Autoescaping)** 如果在環境變量中設置了 autoescaping,所有的輸出都會自動轉義,但可以使用 safe 過濾器,Nunjucks 就不會轉義了。 ~~~ {{ foo }} // &lt;span%gt; {{ foo | safe }} // <span> ~~~ 如果未開啟 autoescaping,所有的輸出都會如實輸出,但可以使用 escape 過濾器來轉義。 ~~~ {{ foo }} // <span> {{ foo | escape }} // &lt;span&gt; ~~~ ## **全局函數 (Global Functions)** 以下為一些內置的全局函數 ### **range([start], stop, [step])** 如果你需要遍歷固定范圍的數字可以使用 range,start (默認為 0) 為起始數字,stop 為結束數字,step 為間隔 (默認為 1)。 ~~~ {% for i in range(0, 5) -%} {{ i }}, {%- endfor %} ~~~ 上面輸出 0,1,2,3,4. ### **cycler(item1, item2, ...itemN)** cycler 可以循環調用你指定的一系列的值。 ~~~ {% set cls = cycler("odd", "even") %} {% for row in rows %} <div class="{{ cls.next() }}">{{ row.name }}</div> {% endfor %} ~~~ 上面的例子中奇數行的 class 為 "odd",偶數行的 class 為 "even"。你可以使用current屬性來獲取當前項(在上面的例子中對應cls.current)。 ### **joiner([separator])** 當合并多項的時候,希望在他們之間又分隔符 (像逗號),但又不希望第一項也輸出。joiner 將輸出分割符 (默認為 ",") 除了第一次調用。 ~~~ {% set comma = joiner() %} {% for tag in tags -%} {{ comma() }} {{ tag }} {%- endfor %} ~~~ 如果 tags 為 ["food", "beer", "dessert"], 上面將輸出 food, beer, dessert。 ### **default(value, default, [boolean])** (簡寫為 d) 如果value全等于undefined則返回default,否則返回value。 如果boolean為true,則會在value為JavaScript中的假值時(比如:false, ""等)返回default。 在2.0版本中,這個過濾器的默認表現與以前有所不同。在之前的版本中,它會把boolean的默認值 設置為true,所以傳入任何假值都會返回default。在2.0中,默認只有值為undefined時會 返回default。如果你仍舊希望保持原來版本的表現的話,你可以給boolean傳入true,或是 直接使用value or default。 ### **sort(arr, reverse, caseSens, attr)** 用JavaScript中的arr.sort函數排序arr。如果reverse為true,則會返回相反的 排序結果。默認狀態下排序不會區分大小寫,但你可以將caseSens設置為true來讓排序 區分大小寫。我們可以用attr來指定要比較的屬性。 ### **striptags (value, [preserve_linebreaks])** 類似于jinja中的striptags. 如果preserve_linebreaks為false(同時也是默認值),則會移去SGML/XML標簽并用一個空格符 替換臨近的、連續的空白符號。如果preserve_linebreaks為true,則會嘗試保留臨近的空白符號。 如果你希望使用管道操作符進行類似于{{ text | striptags | nl2br }}這樣的操作時,你就會 需要用到后一種。否則你還是應該使用默認的用法。 ### **dump (object)** 在一個對象上調用JSON.stringify,并將結果輸出到模板上。這在調試時很有用:{{ foo | dump }}。
                  <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>

                              哎呀哎呀视频在线观看