模板引擎是為了使用戶界面與業(yè)務(wù)數(shù)據(jù)(內(nèi)容)分離而產(chǎn)生的, 其本身并不是一種深?yuàn)W的技術(shù).
template模板引擎首先會(huì)將合法的模板編譯為lua函數(shù), 然后將模板文件和數(shù)據(jù)通過模板引擎生成一份HTML代碼.
cf的admin庫整使使用了template來構(gòu)建服務(wù)端渲染頁面, 并利用單頁面+iframe模式快速完成lua后臺(tái)開發(fā).
在真正使用之前, 我們先來學(xué)習(xí)一下template常見的一些基本語法:
{{ lua expression }}
- lua expression
是一段lua表達(dá)式; 作用為輸出表達(dá)式的結(jié)果, 一些特殊符號(hào)將會(huì)被轉(zhuǎn)義;{* lua expression *}
- lua expression
是一段lua表達(dá)式; 作用為輸出表達(dá)式的結(jié)果, 不會(huì)轉(zhuǎn)義任何符號(hào);{% lua code %}
- 執(zhí)行一段lua代碼, 如: {% for i = x, y do %} ... {% end %}
;{# comments #}
- comments僅作為注釋, 不會(huì)包含在輸出字符串內(nèi). 這段語法的作用類似lua內(nèi)的--
與--[[]]
;{(template)}
- 導(dǎo)入其它模板文件; 同時(shí)支持傳參: {(file.html, { message = "Hello, World" })}
;&
將會(huì)轉(zhuǎn)義為 &
<
將會(huì)轉(zhuǎn)義為 <
>
將會(huì)轉(zhuǎn)義為 >
"
將會(huì)轉(zhuǎn)義為 "
'
將會(huì)轉(zhuǎn)義為 '
/
將會(huì)轉(zhuǎn)義為 /
參數(shù)html為字符串類型, 可以是:模板文件路徑、
此方法返回一個(gè)渲染函數(shù), 調(diào)用這個(gè)函數(shù)并傳入一個(gè)table(key-value)作為參數(shù)則可以在模板文件內(nèi)直接引用.
此方法用來將view預(yù)編譯為lua的二進(jìn)制代碼塊, strip是一個(gè)bool類型用來確定是否包含調(diào)試信息.
此方法用來重寫template內(nèi)部的加載行為; 默認(rèn)的模板加載流程為: 檢查緩存 -> 讀取文件 -> 解析文件 -> 渲染 -> 輸出;
path字段為需要加載的文件路徑或模板、html代碼;
此方法用來重寫template內(nèi)部渲染后的輸出行為; 默認(rèn)的輸出行為: print
此方法用來告訴template是否緩存; 默認(rèn)為true.
現(xiàn)在嘗試使用模板引擎完成一個(gè)靜態(tài)頁面的數(shù)據(jù)導(dǎo)入工作渲染一個(gè)頁面并展示給用戶看.
首先, 導(dǎo)入template庫local template = require "template"
. 并且將目前我們熟知的編程語言名稱都羅列出來.
local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }
然后, 我們在app
目錄下新建一個(gè)view
目錄, 并在view
目錄下新建一個(gè)名字為base.html
的文件。 內(nèi)容如下:
<html>
<head>
<title>{*title*}</title>
</head>
<body>
<span><b>{*title*}:</b></span>
<ul>
{% if type(languages) == 'table' then %}
{% for index, lang in ipairs(languages) do %}
<li>{*index..'. '..lang*}</li>
{% end %}
{% end %}
</ul>
{# 沒錯(cuò), 注釋不會(huì)展示給用戶看到! #}
</body>
</html>
最后完成一個(gè)/languages
的路由注冊, 將我們剛剛完成的模板渲染出來.
local template = require "template"
app:use('/languages', function(content)
template.cache = {}
local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }
return template.compile("view/base.html"){
title = '語言列表',
languages = languages
}
end)
template.cache = {}
的意思是, 每次都重新刷新緩存去讀取文件, 這樣方便我們進(jìn)行調(diào)試.
最后打開http://localhost:8080/
languages查看效果.
當(dāng)一個(gè)項(xiàng)目的業(yè)務(wù)需求變得非常多的時(shí)候, 即是一個(gè)單純的模板頁面也會(huì)變得非常龐大并且不容維護(hù)與閱讀.
現(xiàn)在我們來嘗試將上面的模板進(jìn)行模塊化.
首先, 我們繼續(xù)在app
目錄新建head.html
與content.html
. 然后將這些代碼拷貝進(jìn)去:
{# 這是head.html的內(nèi)容 #}
<title>{*title*}</title>
{# 這是content.html的內(nèi)容 #}
<span><b>{*title*}:</b></span>
<ul>
{% if type(languages) == 'table' then %}
{% for index, lang in ipairs(languages) do %}
<li>{*index..'. '..lang*}</li>
{% end %}
{% end %}
</ul>
{# 沒錯(cuò), 注釋不會(huì)展示給用戶看到! #}
然后將原來的base.html
修改為:
<html>
<head>
{(view/head.html)}
</head>
<body>
{(view/content.html)}
</body>
</html>
最后, 由于服務(wù)器會(huì)自動(dòng)刷新模板緩存, 我們只需要再次刷新瀏覽器就能查看效果.
-- main.lua
local httpd = require "httpd"
local app = httpd:new("app")
local template = require "template"
app:use('/languages', function(content)
local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }
template.cache = {}
return template.compile("view/base.html"){
title = '語言列表',
languages = languages
}
end)
app:listen("0.0.0.0", 8080)
app:run()
更多template用法可以參考cf的admin庫.
下一章我們繼續(xù)學(xué)習(xí)如何使用緩存與數(shù)據(jù)庫.
更多建議: