Flask筆記:Jinja2模板


Python的Jinja2模板,其實就是在HTML文檔中使用控制語句和表達語句替換HTML文檔中的變量來控制HTML的顯示格式,Python的Jinja2模板可以更加靈活和方便的控制HTML的顯示,而且大大地減少了編程人員的工作量。

本文是作者的學習筆記,並不全面,感興趣的朋友可以參考http://docs.jinkan.org/docs/jinja2/templates.html

模板語法:

1、注釋{# .. #}:HTML中的注釋可以使用<!-- ... -->注釋,但在jinja2的web模板中也可以使用{# .. #}注釋掉一行或多行HTML中的內容。

2、訪問字典值或對象屬性值:有兩種方式,一是“object['name']”采用字典的訪問方式,二是“object.name”采用類屬性的訪問方式。

3、表達語句{{ ... }}:一條表達語句就相當於一條Python語句,不需要結束語句,{{和}}之間可以放入任何Python表達式,Jinja2模板語法可以自動運行{{和}}中的語句並把運行結果顯示在HTML模板中。

4、控制語句{% ... %}:控制語句需要使用一個結束標志表明該語句的結束,通常用來作循環控制、條件控制、模塊控制等,可以更加方便的控制HTML內容的顯示;

  • if語句:使用{% if xxx %}...{% elif xxx %}...{% else %}...{% endif %}語句來進行條件控制。如圖:

  •  for語句:使用如{% for x in xx %} ... {{% else %}}...{% endfor %}語句來進行循環控制:
    • else:當for遍歷的序列中沒有值時就會執行else中的內容。
    • range:用在for循環中,用法和Python一樣,返回一定范圍的序列,具體可查看Python中range的用法。
    • if判斷:可以在for語句后使用if判斷來限制循環,例如:{% for i in range(10) if i < 5 %}...{% endfor %},此循環只會循環5次,即i為0,1,2,3,4時。
    • loop:loop可以看作是jinja2內置的對象,用在for循環中。
      • loop.index:表示當前迭代的索引(從1開始計數);
      • loop.index0:表示當前迭代的索引(從0開始計數);
      • loop.first:當前迭代如果是第一次,則返回True,否則返回False;
      • loop.last:如果當前迭代是最后一次迭代,則返回True,否則返回False;
      • loop.length:返回整個序列的長度。
    • jinja2的for循環是沒有continuebreak語法的。
    • 示例代碼及運行結果如圖:

5、過濾器“|”:形如“{{ var | xxx }}”使用過濾器將變量“var”處理后再渲染展示出來,管道符號“|”前面為變量,后面是一個過濾器(過濾器就相當於一個函數),最外層可以是{{ ... }}或者{% ... %}。常用的過濾器有:

  • abs:返回變量的絕對值。
  • default(value, boolean=False):給變量設置默認值,當變量不存在時,則使用設置的默認值“value”;如果設置了boolean為True,且變量存在時,當它的Python計算結果為False時,也會使用設置的默認值,比如變量的值為None,[],''等。
  • or:or不是過濾器,但是效果相當於default過濾器,當有多個變量時,按照Python中or的邏輯,當有一個變量存在且Python計算結果為True時,取其值,不存在(也算作False)或者Python計算機結果為False時,則繼續檢查下一個變量。例如:{{ var | default('什么也沒有', boolean=True) }}的效果與{{ var or '什么也沒有' }}的效果是一樣的。
  • length:給出前面變量的“長度”,比如字典、列表等的元素個數。
  • escape:將值為字符串的變量中的<、>等HTML中的特殊符號轉義成普通字符串。如果沒有轉義,字符串中含有HTML標簽等特殊符號的話,瀏覽器會將它解釋為HTML的內容,就不再是原先的字符串了。由於jinja2是開啟了自動轉義的,所以變量的字符串是什么,HTML渲染展示的就是什么,這時候就用不着escape過濾器。可以使用{% autoescape off %}{% endautoescape %}來關閉處於其中的HTML內容的自動轉義,這時候想要其中的某個字符串進行轉義的話,就可以使用這個過濾器了。
  • safe:關閉變量字符串的自動轉義。safe是針對變量的,而{% autoescape on/off %}{% endautoescape %}是打開/關閉處於其中的HTML內容的自動轉義。
  • first:返回序列的第一個元素。
  • last:返回序列的最后一個元素。
  • format:格式化字符串,與Python中的%用法類似(只能是%,不能是{}占位符),例如:{{ "這是%s27"|format("Python") }},渲染結果為“這是Python27”。
  • join(d=u''):返回使用d的值來將序列中的元素連接在一起的字符串,類似Python中的join方法。
  • int:將值轉換為int類型。
  • float:將值轉換為float類型。
  • lower:將字符串轉換為小寫。
  • upper:將字符串轉換為大寫。
  • replace(old, new):將字符串中子串old替換為新的子串new。
  • string:將變量轉換為字符串。
  • truncate(length=255):只截取字符串的前length個字符。
  • striptags:刪除字符串中的所有HTML標簽,如果字符串中有多個連續的空格,則替換成一個空格。
  • wordcounts:統計一個字符串中的單詞個數。
  • 更多過濾器:http://jinja.pocoo.org/docs/dev/templates/#builtin-filters

6、自定義過濾器:過濾器其實就是一個普通的函數,該函數至少有一個參數,HTML中使用過濾器時會將變量作為該函數的第一個參數傳入進去,然后將該函數的返回值渲染到HTML中,定義好過濾器的函數后,需要使用裝飾器@app.template_filter('filter_name')將函數注冊到jinja2中才能使用,HTML中使用該自定義的過濾器時,使用自定義的filter_name,jinj2就會自動調用對應的函數了。如下示例瀏覽器顯示為“Python36”:

7、宏macro:模板中宏就像Python中的函數一樣,當多個地方需要使用相似代碼片段時,通過定義宏,然后根據不同需求給宏傳遞參數即可達到目的,不用重新寫一遍代碼。

  • 宏定義:使用形如{% macro macro_name(name, value="", type="") -%}...{%- endmacro %}即可定義一個名叫macro_name的宏,name和value等就是宏的參數。注意-%}{%-這兩個符號中的減號是為了取出宏的首尾的換行符,除非整個宏是定義在一行代碼中的,否則通過瀏覽器查看源代碼時就會發現宏的位置的代碼是被換行了的。
  • 作用和使用:它的作用就像Python中的函數一樣,可以將經常用到的代碼片段定義為一個宏,macro_name就相當於函數名稱,name和value等就相當於函數的參數,這些參數在定義時可以像變量一樣使用{{ value }}去使用它們。使用宏的使用就像使用Python函數一樣即可,例如{{ macro("username", value="username", type="text") }}。
  • 導入宏:我們一般會將宏專門放在一個HTML模板中,然后導入到其他的模板中使用,導入有兩種方式:{% from "macros.html" import macro_name [as new_name] %},或者{% import "macros.html" as macros %},其中"mcros.html"為存放宏的模板路徑。前者可以使用as來起一個別名,但不是必須的,后者就必須給模板起一個別名,然后以macros.macro_name的方式使用。
  • 宏模板路徑:導入宏模板的路徑不能是相對路徑,必須是templates下的絕對路徑。
  • 在宏模板中使用參數變量:想要在定義宏的模板中使用導入該宏時它所在模板中的參數變量,可以在導入語句后加入with context,這樣宏的模板就可以使用當前模板中的所有參數變量了,例如{% import "macros.html" as macros with context %}。

8、模板繼承block和extends:

  • 語法:在父模板中使用{% block block_name %}{% endblock %}進行模塊的占位,block_name可以自己定義,其他的都是固定的語法格式;在子模板中使用{% extends  "xxx.html" %}表示此HTML模板繼承自“xxx.html”模板(父模板),然后在子模板中使用{% block block_name %} ... {% endblock %}重新定父模板中占位的block模塊(注意子模板此時不用再寫父模板中已有的內容,包括HTML標簽),子模板中定義模塊內容就會顯示在母板中占位的位置,不同的子模板中可以定義不同的模塊內容來滿足自身的需要。
  • 使用:{% extends  "xxx.html" %}需要放在所有代碼的前面,一般就放在第一行。還有另外一點就是子模板如果使用了繼承,那么子模板中所有的代碼就需要放在block中實現,也就是說想要實現一些沒有在父模板block中的代碼,那么就需要在父模板中再添加一個block進行占位了,不然在子模板中寫在block之外的代碼不會被展示出來。
  • block:父模板的block中也可以寫代碼,當時如果子模板中重新定義了此block的內容,那么父模板此block就會被覆蓋掉,當然如果沒有重新定義,自然就還是展示父模板中的block內容。
  • super:如果在子模板中的block中想要使用父模板中此block的內容,那么使用{{ super() }}就可以讓父模板中block的內容“copy”這個位置了。
  • self:如果想要在block中使用另一個block中的內容,可以使用{{ self.block_name() }}就可以讓另一個block中的內容“copy”到這個位置。當然,如果子模板中重新定義了block的內容,那么self就會使用子模板中的block了。

9、模板導入include:在一個HTML模板中使用{% include "xxx.html" %},就會將xxx.html的內容導入(嵌入)當前HTML模板中,效果相當於將xxx.html的內容copy到執行include語句時的位置,並且可以在xxx.html中直接使用當前模板中的參數變量。一般會將一些公共內容寫在一個模板中,然后導入到需要使用的模板中,以達到代碼重用的效果,使模板編碼更加簡潔方便,比如導航條、底部信息等大多數頁面都會用到的內容;

10、set語句:類似Python的定義變量,在模板中使用形如{% set para_name=para_value %}就可以在這個語句之后使用這個變量了(在本模板中)。

11、with語句:使用形如{% with [para_name=para_value] %}...{% endwith %},如果這里定義了變量,那么這個變量就只能在with的作用域中使用了,也可以在with的作用域中使用set語句,那么set定義的變量也是只能在with作用域中生效

12、靜態文件加載:靜態文件則使用如“<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}" >”,其中“static”是靜態文件存放的總文件夾,“filename”的值則是靜態文件的具體路徑。如圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM