做web不簡單,特別是當你需要使用一些web效果的時候, 比如顯示個圓角矩形,提示框之類的,也許你認為很簡單,好讓我們分析一下:
1.引用css。這可能是最常見的做法了,對一些特定的元素定義特定的樣式。那么使用它,你需要在HTML
頁面中加入
標簽。
2.引入js。許多特效也可以通過javascript來進行處理,比如動態顯示效果,或對元素進行封裝。使用
它你需要在HTML頁面加入標簽,必要時還要加一些javascript代碼。
3.HTML元素。需要設定一些特殊的屬性,比如class=某個屬性。這塊還相對簡單。
因此從上面的分析可以看出,在通常情況下,加入一個好看的web元素可能到許多地方的修改。因此我一
直在思考如何讓這個過程可以更簡化,麻煩的地方就是如何處理這些資源,如何讓這些資源可以與原始的
HTML很好的結合呢?最終我想出的辦法就是:代碼組裝。
對于css,javascript鏈接和代碼,它們可以按調用的順序依次拼成一段文本,然后插入到元素前
面。然后對于html代碼,在模板中直接輸出。對于css,javascript的鏈接可以檢查是否重復。
那么如何定義web元素類和如何在模板中對其進行處理?
一個web元素類定義如下:
classSnippet(object):
css=''
csslink=''
jslink=''
html=''
js=''
defrender(self):
return''
def__str__(self):
returnself.render()
定義為類屬性的將輸出到HTML的頭部,而render()的結果將顯示在模板中調用類的地方。先看一下在模板
中調用的示例:
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{{
htmlbuf<
}}
這里你可以看到htmlbuf,它是什么,它就是用來采集每個Snippet類的類屬性的。這里使用<<來將一個
Snippet對象加到htmlbuf中去。同時它還會將Snippet的HTML代碼在調用位置輸出。
如何輸出?首先uliweb的模板將轉為python代碼,它有一個內置的out對象,可以調用它的方法來輸出
HTML代碼。那么htmlbuf對象將在調用模板前被創建,在調用模板后被處理,在創建時將傳入out的write
屬性。這一切都是在SImpleFrame.py中通過plugin方法來實現的,但是這只是定義了一個調用點,如:
fname,code=template.render_file(filename,vars,env,dirs)
out=template.Out()
template._prepare_run(vars,env,out)
callplugin(self,'before_render_template',env,out)
ifisinstance(code,(str,unicode)):
code=compile(code,fname,'exec')
execcodeinenv,vars
text=out.getvalue()
output=execplugin(self,'after_render_template',text,vars,env)
before_render_template會在調用模板前被調用。after_render_template會在調用模板后被調用。因
此你可以通過plugin機制來加入額外的處理。這是在settings.py中定義的,如:
@plugin('before_render_template')
defbefore_render_template(sender,env,out):
fromuliweb.coreimportjs
fromuliweb.core.SimpleFrameimporturl_for
fromuliweb.helpersimporthtmlwidgets
htmlbuf=js.HtmlBuf(write=out.noescape,static_suffix=url_for('Portal.views.static',
filename=''))
env['htmlbuf']=htmlbuf
env['htmlwidgets']=htmlwidgets
這里注入htmlbuf和htmlwidgets到模板的env環境中,所以可以在模板中直接使用。在htmlwidgets中已經
定義了一些Snippet。htmlbuf在創建時,會使用out.noescape方法,它將不會對Snippet中的代碼進行轉
義。static_suffix表示靜態文件的前綴,缺省為/static/,這里由于使用了靜態服務,所以通過url_for
來得到靜態URL前綴。
@plugin('after_render_template')
defafter_render_template(sender,text,vars,env):
importre
r_links=re.compile(']|
(.*?)["/s>]',re.I)
if'htmlbuf'inenv:
htmlbuf=env['htmlbuf']
ifhtmlbuf.modified:
b=re.search('(?i)',text)
ifb:
pos=b.start()
#findlinks
links=[xoryforx,yinr_links.findall(text[:pos])]
htmlbuf.remove_links(links)
t=htmlbuf.render()
ift:
return''.join([text[:pos],t,text[pos:]])
else:
returnt+text
returntext
這里將在模板處理完畢后查找生成的HTML文本中的標簽,然后將相應的信息插入到它的前面。同
時這里增加了對原HTML中已經存在的鏈接進行了判斷,如果存在則刪除之,這是通過remove_links來處理
的。
經過這些的處理,你只要定義一個Snippet,Uliweb將自動為你處理css,js的鏈接包括代碼,和HTML代碼
的生成。因此你就可以簡單的:
{{
htmlbuf<
}}
來生成一個消息的提示信息。
我會慢慢擴展這個htmlwidgets庫。
再簡單描述一下如何配置:
1.在settings.py中
INSTALLED_APPS=['Documents','Examples','Portal','Post',
'uliweb.builtins.auth','uliweb.helpers.htmlwidgets']
這里要加入'uliweb.helpers.htmlwidgets',讓static目錄生效
2.加入:
@plugin('before_render_template')
defbefore_render_template(sender,env,out):
和
@plugin('after_render_template')
defafter_render_template(sender,text,vars,env):
3.可以使用了。
新聞熱點
疑難解答