生活随笔
收集整理的這篇文章主要介紹了
第五章 常用Lua开发库3-模板渲染
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
動(dòng)態(tài)web網(wǎng)頁(yè)開發(fā)是Web開發(fā)中一個(gè)常見的場(chǎng)景,比如像京東商品詳情頁(yè),其頁(yè)面邏輯是非常復(fù)雜的,需要使用模板技術(shù)來實(shí)現(xiàn)。而Lua中也有許多模板引擎,如目前我在使用的lua-resty-template,可以渲染很復(fù)雜的頁(yè)面,借助LuaJIT其性能也是可以接受的。
?
如果學(xué)習(xí)過JavaEE中的servlet和JSP的話,應(yīng)該知道JSP模板最終會(huì)被翻譯成Servlet來執(zhí)行;而lua-resty-template模板引擎可以認(rèn)為是JSP,其最終會(huì)被翻譯成Lua代碼,然后通過ngx.print輸出。
?
而lua-resty-template和大多數(shù)模板引擎是類似的,大體內(nèi)容有:
模板位置:從哪里查找模板;
變量輸出/轉(zhuǎn)義:變量值輸出;
代碼片段:執(zhí)行代碼片段,完成如if/else、for等復(fù)雜邏輯,調(diào)用對(duì)象函數(shù)/方法;
注釋:解釋代碼片段含義;
include:包含另一個(gè)模板片段;
其他:lua-resty-template還提供了不需要解析片段、簡(jiǎn)單布局、可復(fù)用的代碼塊、宏指令等支持。
?
首先需要下載lua-resty-template
Java代碼??
cd?/usr/example/lualib/resty/?? wget?https:?? mkdir?/usr/example/lualib/resty/html?? cd?/usr/example/lualib/resty/html??? wget?https:??
接下來就可以通過如下代碼片段引用了
Java代碼??
local?template?=?require("resty.template")??
??
模板位置
我們需要告訴lua-resty-template去哪兒加載我們的模塊,此處可以通過set指令定義template_location、template_root或者從root指令定義的位置加載。
?
如我們可以在example.conf配置文件的server部分定義
Java代碼??
#first?match?ngx?location?? set?$template_location?"/templates";?? #then?match?root?read?file?? set?$template_root?"/usr/example/templates";??
也可以通過在server部分定義root指令
Java代碼??
root?/usr/example/templates;??
?
其順序是
Java代碼??
local?function?load_ngx(path)?? ????local?file,?location?=?path,?ngx_var.template_location?? ????if?file:sub(1)??==?"/"?then?file?=?file:sub(2)?end?? ????if?location?and?location?~=?""?then?? ????????if?location:sub(-1)?==?"/"?then?location?=?location:sub(1,?-2)?end?? ????????local?res?=?ngx_capture(location?..?'/'?..?file)?? ????????if?res.status?==?200?then?return?res.body?end?? ????end?? ????local?root?=?ngx_var.template_root?or?ngx_var.document_root?? ????if?root:sub(-1)?==?"/"?then?root?=?root:sub(1,?-2)?end?? ????return?read_file(root?..?"/"?..?file)?or?path?? end??
1、通過ngx.location.capture從template_location查找,如果找到(狀態(tài)為為200)則使用該內(nèi)容作為模板;此種方式是一種動(dòng)態(tài)獲取模板方式;
?
2、如果定義了template_root,則從該位置通過讀取文件的方式加載模板;
3、如果沒有定義template_root,則默認(rèn)從root指令定義的document_root處加載模板。
?
此處建議首先template_root,如果實(shí)在有問題再使用template_location,盡量不要通過root指令定義的document_root加載,因?yàn)槠浔旧淼暮x不是給本模板引擎使用的。
?
接下來定義模板位置
Java代碼??
mkdir?/usr/example/templates?? mkdir?/usr/example/templates2??
?
example.conf配置server部分
Java代碼??
#first?match?ngx?location?? set?$template_location?"/templates";?? #then?match?root?read?file?? set?$template_root?"/usr/example/templates";?? ?? location?/templates?{?? ?????internal;?? ?????alias?/usr/example/templates2;?? }??
首先查找/usr/example/template2,找不到會(huì)查找/usr/example/templates。
?
然后創(chuàng)建兩個(gè)模板文件
Java代碼??
vim?/usr/example/templates2/t1.html??
內(nèi)容為?
Java代碼??
template2??
?
Java代碼??
vim?/usr/example/templates/t1.html??
內(nèi)容為?
Java代碼??
template1??
?
test_temlate_1.lua?
Java代碼??
local?template?=?require("resty.template")?? template.render("t1.html")??
?
example.conf配置文件
Java代碼??
location?/lua_template_1?{?? ????default_type?'text/html';?? ????lua_code_cache?on;?? ????content_by_lua_file?/usr/example/lua/test_template_1.lua;?? }??
訪問如http://192.168.1.2/lua_template_1將看到template2輸出。然后rm /usr/example/templates2/t1.html,reload nginx將看到template1輸出。
?
接下來的測(cè)試我們會(huì)把模板文件都放到/usr/example/templates下。
?
API
使用模板引擎目的就是輸出響應(yīng)內(nèi)容;主要用法兩種:直接通過ngx.print輸出或者得到模板渲染之后的內(nèi)容按照想要的規(guī)則輸出。
?
1、test_template_2.lua
Java代碼??
local?template?=?require("resty.template")?? --是否緩存解析后的模板,默認(rèn)true?? template.caching(true)?? --渲染模板需要的上下文(數(shù)據(jù))?? local?context?=?{title?=?"title"}?? --渲染模板?? template.render("t1.html",?context)?? ?? ?? ngx.say("<br/>")?? --編譯得到一個(gè)lua函數(shù)?? local?func?=?template.compile("t1.html")?? --執(zhí)行函數(shù),得到渲染之后的內(nèi)容?? local?content?=?func(context)?? --通過ngx?API輸出?? ngx.say(content)??
常見用法即如下兩種方式:要么直接將模板內(nèi)容直接作為響應(yīng)輸出,要么得到渲染后的內(nèi)容然后按照想要的規(guī)則輸出。
?
2、examle.conf配置文件
Java代碼??
location?/lua_template_2?{?? ????default_type?'text/html';?? ????lua_code_cache?on;?? ????content_by_lua_file?/usr/example/lua/test_template_2.lua;?? }??
??
使用示例
1、test_template_3.lua
Java代碼??
local?template?=?require("resty.template")?? ?? local?context?=?{?? ????title?=?"測(cè)試",?? ????name?=?"張三",?? ????description?=?"<script>alert(1);</script>",?? ????age?=?20,?? ????hobby?=?{"電影",?"音樂",?"閱讀"},?? ????score?=?{語(yǔ)文?=?90,?數(shù)學(xué)?=?80,?英語(yǔ)?=?70},?? ????score2?=?{?? ????????{name?=?"語(yǔ)文",?score?=?90},?? ????????{name?=?"數(shù)學(xué)",?score?=?80},?? ????????{name?=?"英語(yǔ)",?score?=?70},?? ????}?? }?? ?? template.render("t3.html",?context)??
請(qǐng)確認(rèn)文件編碼為UTF-8;context即我們渲染模板使用的數(shù)據(jù)。?
?
2、模板文件/usr/example/templates/t3.html
Java代碼??
{(header.html)}?? ???<body>?? ??????{#?不轉(zhuǎn)義變量輸出?#}?? ??????姓名:{*?string.upper(name)?*}<br/>?? ??????{#?轉(zhuǎn)義變量輸出?#}?? ??????簡(jiǎn)介:{{description}}<br/>?? ??????{#?可以做一些運(yùn)算?#}?? ??????年齡:?{*?age?+?1?*}<br/>?? ??????{#?循環(huán)輸出?#}?? ??????愛好:?? ??????{%?for?i,?v?in?ipairs(hobby)?do?%}?? ?????????{%?if?i?>?1?then?%},{%?end?%}?? ?????????{*?v?*}?? ??????{%?end?%}<br/>?? ?? ??????成績(jī):?? ??????{%?local?i?=?1;?%}?? ??????{%?for?k,?v?in?pairs(score)?do?%}?? ?????????{%?if?i?>?1?then?%},{%?end?%}?? ?????????{*?k?*}?=?{*?v?*}?? ?????????{%?i?=?i?+?1?%}?? ??????{%?end?%}<br/>?? ??????成績(jī)2:?? ??????{%?for?i?=?1,?#score2?do?local?t?=?score2[i]?%}?? ?????????{%?if?i?>?1?then?%},{%?end?%}?? ??????????{*?t.name?*}?=?{*?t.score?*}?? ??????{%?end?%}<br/>?? ??????{#?中間內(nèi)容不解析?#}?? ??????{-raw-}{(file)}{-raw-}?? {(footer.html)}??
{(include_file)}:包含另一個(gè)模板文件;
?
{* var *}:變量輸出;
{{ var }}:變量轉(zhuǎn)義輸出;
{% code %}:代碼片段;
{# comment #}:注釋;
{-raw-}:中間的內(nèi)容不會(huì)解析,作為純文本輸出;
?
模板最終被轉(zhuǎn)換為L(zhǎng)ua代碼進(jìn)行執(zhí)行,所以模板中可以執(zhí)行任意Lua代碼。?
?
3、example.conf配置文件
Java代碼??
location?/lua_template_3?{?? ????default_type?'text/html';?? ????lua_code_cache?on;?? ????content_by_lua_file?/usr/example/lua/test_template_3.lua;?? }??
訪問如http://192.168.1.2/lua_template_3進(jìn)行測(cè)試。?
?
基本的模板引擎使用到此就介紹完了。?
來源:http://jinnianshilongnian.iteye.com/blog/2187775
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的第五章 常用Lua开发库3-模板渲染的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。