web.py 模板

在 Python 中寫 HTML 不是聰明的選擇,相反在 HTML 中寫 Python 則有趣的多兽狭。幸運的是憾股,web.py 讓這件事情做得簡單而又漂亮。

創(chuàng)建模板

這里箕慧,我們先在項目中新建一個目錄templates集中存放模板文件服球,便于管理。然后在templates下新建一個index.html文件颠焦,在新文件中寫入如下代碼:

$def with (name)

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
    <title>Template</title>
</head>
<body>
    Hi, $name
</body>
</html>

這是一個最簡單的html頁面代碼斩熊。

使用模板

然后在修改使用這個模板的類,比如說我們在main.py模塊中的新寫一個index類伐庭,入下:

class index:

    def GET(self):
        render=web.template.render(“templates”)
        return render.index(“Lisa”)

同時修改urls為:

urls = (“/”, “index”)

這樣粉渠,網(wǎng)站默認調(diào)用index類,進而使用index.html模板圾另,打開瀏覽器查看結(jié)果霸株,頁面就會打印出 Hello, Lisa 的字樣。

除此之外還有兩種使用模板的方法:

  • 使用frender直接指定模板文件集乔,GET函數(shù)最后兩行改為:

    render=web.template.frender(“templates/index.html”)
    return render(“Lisa”)
    
  • 直接在代碼里寫出模板文件去件,GET最后兩行改為:

    template = “$def with (name)\nHello $name”
    render = web.template.Template(template)
    return render(“Lisa”)
    

模板含義

解釋一下這個模板的含義:

在index.html第一行 $def with (name)表示本模板接受一個名為name的參數(shù),也就是對應(yīng)index類中return render.index(“Lisa”)中的Lisa扰路。而render=web.template.render(“templates”)表示創(chuàng)建一個模板對象尤溜,模板是存放于templates目錄下,然后就可以用所創(chuàng)建的 render 對象來訪問相應(yīng)的模板

比如templates目錄下的index.html就是用render.index來表示(實際上是匹配尋找index.*文件汗唱,第一個匹配的就認為是所對應(yīng)的模板文件)宫莱,如果templates下還有個a目錄,a目錄下有個pagea.html哩罪,那么訪問這個pagea模板就要用render.a.pagea的形式了梢睛。

頁面參數(shù)

頁面接收的參數(shù)可以多于一個肥印,也可以沒有,如果不需要參數(shù)绝葡,則就不需要$def with (name)這樣的代碼深碱,刪除掉這一句,同時修改模板中對name變量的引用藏畅,修改index類最后一句為return render.index()就可以了敷硅。

如果有參數(shù),那么模板的第一行代碼就必須是這個 $def with (…)愉阎,可以多于一個參數(shù)绞蹦,比如是這樣$def with (gname, fname)。模板下面的那行字改為Hi, $gname $fname榜旦。同時Index類GET返回的時候賦予對應(yīng)兩個參數(shù)return render.index(“Lisa”,”Hayes”)幽七。這樣,頁面最后顯示的是打印出Hi, Lisa Hayes的字樣溅呢。

另外澡屡,模板接受的這個參數(shù)也可以是一個元組,比如像下面這樣:

return render.index((“Lisa”,”Hayes”))

在模板中可以如下以元組方式訪問參數(shù)數(shù)據(jù):

Hi, $name[0] $name[1]

模板語法

模板語法與python語法基本一致咐旧,主要差別可以從上面的代碼中看到驶鹉,要使用到$符號表明這不是文本而是模板代碼。也就是每當用到程序代碼铣墨、對象的時候就必須用$來與html代碼和頁面顯示文本相區(qū)別室埋。

對象賦值

向?qū)ο筚x值時需要在$對象名之間留空格,如為一個名為vara的字符串對象賦值apple的代碼為$ vara = “apple”伊约。

另外姚淆,對象賦值語句必須獨占一行,前面或后面有其他代碼則會程序出錯屡律。

對象引用

引用對象的時候直接使用 $+對象名的形式腌逢,如$vara

另外引用對象時還可以用{}()將對象進行明確的分組疹尾,如$(vara)s就會表示apples上忍,如果沒有括號骤肛,程序則會把 $varas作為一個整體纳本,也就變成對varas對象的引用而發(fā)生錯誤。

另如果向如下定義兩個數(shù)字型對象:

$varb = 1
$varc = 2

然后希望計算兩個值的和腋颠,如果用$varb+$varc的形式繁成,頁面上只會得到1+2而不是3,這時也就需要把兩個對象放在括號里淑玫,如$(varb+varc)的形式才能得到正確答案3巾腕。

注釋

模板中支持單行注釋面睛,以$#符號開始到行末都是注釋內(nèi)容。

$#This is comment

注釋前面可以有其他內(nèi)容尊搬,但是不可以有賦值代碼叁鉴。

如下代碼是正確的:

Hi $#This is comment

但下面的則會出錯:

$ vara = “apple” $#This is comment

打印$符號

由于$符號在模板中有特殊用途,所以在頁面上輸出$時需要進行轉(zhuǎn)義操作佛寿,用連續(xù)兩個$表示在頁面上輸出一個$符號幌墓。

Can you lend me $$50?

控制代碼(循環(huán)、條件判斷)

模板中支持for冀泻、while常侣、if、elif弹渔、else胳施,用法與在python一致,只是控制代碼行要以$開始(包括break和continue命令)肢专,$開始的代碼行中對象不需要在前面再加$符號舞肆,同時要注意縮進規(guī)則,如:

for 循環(huán):

$def with (toUser,fromUser,createTime,articleCnt,articles)
<xml>
    <ToUserName><![CDATA[$toUser]]></ToUserName>
    <FromUserName><![CDATA[$fromUser]]></FromUserName>
    <CreateTime>$createTime</CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <ArticleCount>$articleCnt</ArticleCount>
    <Articles>
        $for a in articles:
            <item>
                <Title><![CDATA[$a['title']]]></Title>
                <Description><![CDATA[$a['desc']]]></Description>
                <PicUrl><![CDATA[$a['picUrl']]]></PicUrl>
                <Url><![CDATA[$a['url']]]></Url>
            </item>
    </Articles>
</xml>

if else判斷:

$if times > max:
    Stop! In the name of love.
$else:
    Keep on, you can do it.

在for循環(huán)中鸟召,有一組內(nèi)置的變量可以使用胆绊,非常方便,分別如下所示:

  • loop.index: 循環(huán)次數(shù)計數(shù) (1-開始)
  • loop.index0: 循環(huán)次數(shù)計數(shù)(0-開始)
  • loop.first: 如果是第一次循環(huán)則為True
  • loop.last: 如果是最后一次循環(huán)則為True
  • loop.odd: 如果是第奇數(shù)次循環(huán)則為True
  • loop.even: 如果是第偶數(shù)次循環(huán)則為True
  • loop.parity: 如果循環(huán)次數(shù)為奇數(shù)值為“odd” 欧募,反之為 “even”
  • loop.parent: 本循環(huán)的外層循環(huán)對象
$for a in ["a", "b", "c", "d"]: 
    $loop.index,$loop.index0,$loop.first,$loop.last,$loop.odd,$loop.even,$loop.parity<br/>

將在頁面上打印出:

1,0,True,False,True,False,odd
2,1,False,False,False,True,even
3,2,False,False,True,False,odd
4,3,False,True,False,True,even

函數(shù)-$def

函數(shù)定義也是與在python中類似压状,用def,只是也要在前面加$跟继,代碼也要注意$的使用和縮進:

$def hello(name=”"):
Hello $name!

函數(shù)調(diào)用也是用$加函數(shù)名的形式:

$hello(“Lisa”)

當然种冬,定義函數(shù)時也可以與html代碼混編:

$def hello(name=”"):
<strong/>Hello $name!</strong>

但是調(diào)用的時候需要在函數(shù)名前用$:前綴,否則html代碼將以plain text形式打印到頁面上舔糖。

$:hello(“Lisa”)

輸出程序代碼-$code塊

如果想在模板里輸入寫一段python代碼而又不想被$所煩惱娱两,那么可以用到$code塊

頁面上輸出一段代碼而不希望被系統(tǒng)理解為模板程序代碼金吗,就需要用到$code命令十兢,比如在模板文件中寫入下面一段:

$code:
    x=10
    def print_num(num):
    return “num is %d” % num

然后再加上下面代碼:

$print_num(x)
<br/>
$x

這里就用在$code塊中定義的print_num函數(shù)以x變量為參數(shù)在頁面上輸出一行:

num is 10

然后下一行直接引用x變量,直接在頁面上輸出數(shù)字10摇庙。

$var

$var命令可以在模板中定義變量旱物,在其他地方引用此模板對象的時候可以訪問此定義的變量。

比如我們可以在index.html中添加如下一行:

$var vara: this is vara

表示定義了一個名為vara的變量卫袒,變量值是字符串this is vara宵呛。

把index的GET函數(shù)改為:

def GET(self):
    render=web.template.render(“templates”)
    return render.index(“Lisa”, “Hayes”).vara

那么結(jié)果顯示在頁面上的就是this is vara這句話。

要注意一點的是夕凝,這種變量是字符串宝穗,即便如下定義變量:

$var vara: 0

Vara也并不是數(shù)字0户秤,

如果把GET函數(shù)最后改成:

return render.index(“Lisa”, “Hayes”).vara+1

會導致程序出錯。如果希望得到期望中的結(jié)果1逮矛,則需要如下形式代碼:

return int(render.index(“Lisa”, “Hayes”).vara)+1

builtins and globals

在模板中鸡号,用戶可以直接使用python的內(nèi)建函數(shù)和變量,寫函數(shù)變量包括range, min, max 以及 True 和 False等须鼎。 除此之外膜蠢,如果希望在模板中使用其他的非內(nèi)建功能,就需要一點特殊操作莉兰。要在創(chuàng)建render的時候顯式指定所需要的功能函數(shù)挑围。

import web
import markdown

globals = {‘markdown’: markdown.markdown}
render =web.template.render(‘templates’, globals=globals)

這樣,在模板中就可以用$markdown來引用markdown.markdown了糖荒。

同樣杉辙,也可以用這種辦法來禁用builtins

# disable all builtins
render = web.template.render(‘templates’, builtins={})

模板復用

當多個頁面有著相同的結(jié)構(gòu)框架的時候,為每一個頁面單獨維護一個模板就顯得比較麻煩捶朵,web.py提供了一種簡易的解決方法蜘矢。

這時候就要用到創(chuàng)建render時使用base參數(shù):

render=web.template.render(“templates”,base=”layout”)
return render.index(“Lisa”, “Hayes”)

這個layout表示要以templates下的layout.html模板為通用模板框架。

因此我們還要在templates目錄下新建一個layout.html文件综看,寫下如下代碼:

$def with (content)
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head>
        <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
        <title>Layout</title>
    </head>
    <body>
        $:content
    </body>
</html>

可以看到品腹,這個模板文件必須是有一個參數(shù)content。

然后修改index.html红碑,只保留如下代碼舞吭,其他刪掉:

$def with(gname, fname)
    Hi, $(gname) $(fname)

運行程序,頁面上打印Hi, Lisa Hayes析珊,查看代碼會發(fā)現(xiàn)最終代碼就是index.html和layout.html合并在一起的結(jié)果羡鸥,index.html中的內(nèi)容被嵌入到layout.html中的$:content處。

在layout.html模板中還可以引用index.html中定義的var變量忠寻,這為程序帶來了更多的靈活性惧浴,比如我們希望在不同的頁面在使用同一個layout模板的時候能有不同的title,可以在使用layout的模板中定義如下一個var變量:

$var title:This is index.html

然后在layout.html中的title處修改為:

<title>$content.title</title>

這樣奕剃,訪問index.html時顯示在瀏覽器上的title就是This is index.html衷旅,而不是原來的Layout了。

在模板中使用python代碼模塊

在默認狀態(tài)下纵朋,在模板中是不能直接調(diào)用其他python代碼模塊文件中的程序的柿顶,必須做一些額外的操作。
首先倡蝙,我們新建一個模塊九串,叫module1.py绞佩,在里面寫一個函數(shù):

def hello_from_m1(name=”"):
    return “hello %s, this is module1″ % name

在main.py里導入module1:

import module1

并且修改GET函數(shù)中創(chuàng)建render的代碼為:

def GET(self):
    render=web.template.render(“templates”,base=”layout”,globals={“m1″:module1})
    return render.index(“Lisa”)

globals參數(shù)中傳遞的是一個字典寺鸥,key以字符串表示模塊在模板中使用時的名稱猪钮,value部分就是這個要在模塊中使用的模塊或?qū)ο蟮恼鎸嵜Q了。

最后在要使用此模塊的模板中就可以用$m1來引用此模塊了胆建。比如在index.html中添加下面一行代碼:

$m1.hello_from_m1(gname)

就會調(diào)用module1中的hello_from_m1函數(shù)烤低,在頁面上打印出:

hello Lisa, this is module1

在web.py模板中使用jQuery

在jQuery中$也是一個關(guān)鍵字,這樣的話如果在模板中使用jQuery就會沖突笆载,這時候只需要用$$做一下轉(zhuǎn)義就可以了扑馁,比如:

<script type=”text/javascript”>
$$(document).ready(function()
{
    alert(“It works.”);
});
</script>

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凉驻,隨后出現(xiàn)的幾起案子腻要,更是在濱河造成了極大的恐慌,老刑警劉巖涝登,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雄家,死亡現(xiàn)場離奇詭異,居然都是意外死亡胀滚,警方通過查閱死者的電腦和手機趟济,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咽笼,“玉大人顷编,你說我怎么就攤上這事〗P蹋” “怎么了媳纬?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長施掏。 經(jīng)常有香客問我层宫,道長,這世上最難降的妖魔是什么其监? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任萌腿,我火速辦了婚禮,結(jié)果婚禮上抖苦,老公的妹妹穿的比我還像新娘毁菱。我一直安慰自己,他們只是感情好锌历,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布贮庞。 她就那樣靜靜地躺著,像睡著了一般究西。 火紅的嫁衣襯著肌膚如雪窗慎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機與錄音遮斥,去河邊找鬼峦失。 笑死,一個胖子當著我的面吹牛术吗,可吹牛的內(nèi)容都是我干的尉辑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼较屿,長吁一口氣:“原來是場噩夢啊……” “哼隧魄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起隘蝎,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤购啄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘱么,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闸溃,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年拱撵,在試婚紗的時候發(fā)現(xiàn)自己被綠了辉川。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拴测,死狀恐怖乓旗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情集索,我是刑警寧澤屿愚,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站务荆,受9級特大地震影響妆距,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜函匕,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一娱据、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盅惜,春花似錦中剩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屈芜,卻和暖如春郊愧,著一層夾襖步出監(jiān)牢的瞬間朴译,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工属铁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眠寿,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓红选,卻偏偏與公主長得像,于是被迫代替她去往敵國和親姆另。 傳聞我的和親對象是個殘疾皇子喇肋,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容