文档章节

五章 常用Lua开发库3-模板渲染

epiclight
 epiclight
发布于 2015/06/07 12:12
字数 1466
阅读 191
收藏 7

五章 常用Lua开发库3-模板渲染

nginxlua

动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。

 

如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-resty-template模板引擎可以认为是JSP,其最终会被翻译成Lua代码,然后通过ngx.print输出。

 

而lua-resty-template和大多数模板引擎是类似的,大体内容有:

模板位置:从哪里查找模板;

变量输出/转义:变量值输出;

代码片段:执行代码片段,完成如if/else、for等复杂逻辑,调用对象函数/方法;

注释:解释代码片段含义;

include:包含另一个模板片段;

其他:lua-resty-template还提供了不需要解析片段、简单布局、可复用的代码块、宏指令等支持。

 

首先需要下载lua-resty-template

Java代码  收藏代码

  1. cd /usr/example/lualib/resty/  

  2. wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua  

  3. mkdir /usr/example/lualib/resty/html  

  4. cd /usr/example/lualib/resty/html   

  5. wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua  

接下来就可以通过如下代码片段引用了

Java代码  收藏代码

  1. local template = require("resty.template")  

  

模板位置

我们需要告诉lua-resty-template去哪儿加载我们的模块,此处可以通过set指令定义template_location、template_root或者从root指令定义的位置加载。

 

如我们可以在example.conf配置文件的server部分定义

Java代码  收藏代码

  1. #first match ngx location  

  2. set $template_location "/templates";  

  3. #then match root read file  

  4. set $template_root "/usr/example/templates";  

也可以通过在server部分定义root指令

Java代码  收藏代码

  1. root /usr/example/templates;  

 

其顺序是

Java代码  收藏代码

  1. local function load_ngx(path)  

  2.     local file, location = path, ngx_var.template_location  

  3.     if file:sub(1)  == "/" then file = file:sub(2) end  

  4.     if location and location ~= "" then  

  5.         if location:sub(-1) == "/" then location = location:sub(1, -2) end  

  6.         local res = ngx_capture(location .. '/' .. file)  

  7.         if res.status == 200 then return res.body end  

  8.     end  

  9.     local root = ngx_var.template_root or ngx_var.document_root  

  10.     if root:sub(-1) == "/" then root = root:sub(1, -2) end  

  11.     return read_file(root .. "/" .. file) or path  

  12. end  

1、通过ngx.location.capture从template_location查找,如果找到(状态为为200)则使用该内容作为模板;此种方式是一种动态获取模板方式;

 

2、如果定义了template_root,则从该位置通过读取文件的方式加载模板;

3、如果没有定义template_root,则默认从root指令定义的document_root处加载模板。

 

此处建议首先template_root,如果实在有问题再使用template_location,尽量不要通过root指令定义的document_root加载,因为其本身的含义不是给本模板引擎使用的。

 

接下来定义模板位置

Java代码  收藏代码

  1. mkdir /usr/example/templates  

  2. mkdir /usr/example/templates2  

 

example.conf配置server部分

Java代码  收藏代码

  1. #first match ngx location  

  2. set $template_location "/templates";  

  3. #then match root read file  

  4. set $template_root "/usr/example/templates";  

  5.   

  6. location /templates {  

  7.      internal;  

  8.      alias /usr/example/templates2;  

  9. }  

首先查找/usr/example/template2,找不到会查找/usr/example/templates。

 

然后创建两个模板文件

Java代码  收藏代码

  1. vim /usr/example/templates2/t1.html  

内容为 

Java代码  收藏代码

  1. template2  

 

Java代码  收藏代码

  1. vim /usr/example/templates/t1.html  

内容为 

Java代码  收藏代码

  1. template1  

 

test_temlate_1.lua 

Java代码  收藏代码

  1. local template = require("resty.template")  

  2. template.render("t1.html")  

 

example.conf配置文件

Java代码  收藏代码

  1. location /lua_template_1 {  

  2.     default_type 'text/html';  

  3.     lua_code_cache on;  

  4.     content_by_lua_file /usr/example/lua/test_template_1.lua;  

  5. }  

访问如http://192.168.1.2/lua_template_1将看到template2输出。然后rm /usr/example/templates2/t1.html,reload nginx将看到template1输出。

 

接下来的测试我们会把模板文件都放到/usr/example/templates下。

 

API

使用模板引擎目的就是输出响应内容;主要用法两种:直接通过ngx.print输出或者得到模板渲染之后的内容按照想要的规则输出。

 

1、test_template_2.lua

Java代码  收藏代码

  1. local template = require("resty.template")  

  2. --是否缓存解析后的模板,默认true  

  3. template.caching(true)  

  4. --渲染模板需要的上下文(数据)  

  5. local context = {title = "title"}  

  6. --渲染模板  

  7. template.render("t1.html", context)  

  8.   

  9.   

  10. ngx.say("<br/>")  

  11. --编译得到一个lua函数  

  12. local func = template.compile("t1.html")  

  13. --执行函数,得到渲染之后的内容  

  14. local content = func(context)  

  15. --通过ngx API输出  

  16. ngx.say(content)  

常见用法即如下两种方式:要么直接将模板内容直接作为响应输出,要么得到渲染后的内容然后按照想要的规则输出。

 

2、examle.conf配置文件

Java代码  收藏代码

  1. location /lua_template_2 {  

  2.     default_type 'text/html';  

  3.     lua_code_cache on;  

  4.     content_by_lua_file /usr/example/lua/test_template_2.lua;  

  5. }  

  

使用示例

1、test_template_3.lua

Java代码  收藏代码

  1. local template = require("resty.template")  

  2.   

  3. local context = {  

  4.     title = "测试",  

  5.     name = "张三",  

  6.     description = "<script>alert(1);</script>",  

  7.     age = 20,  

  8.     hobby = {"电影""音乐""阅读"},  

  9.     score = {语文 = 90, 数学 = 80, 英语 = 70},  

  10.     score2 = {  

  11.         {name = "语文", score = 90},  

  12.         {name = "数学", score = 80},  

  13.         {name = "英语", score = 70},  

  14.     }  

  15. }  

  16.   

  17. template.render("t3.html", context)  

请确认文件编码为UTF-8;context即我们渲染模板使用的数据。 

 

2、模板文件/usr/example/templates/t3.html

Java代码  收藏代码

  1. {(header.html)}  

  2.    <body>  

  3.       {# 不转义变量输出 #}  

  4.       姓名:{* string.upper(name) *}<br/>  

  5.       {# 转义变量输出 #}  

  6.       简介:{{description}}<br/>  

  7.       {# 可以做一些运算 #}  

  8.       年龄: {* age + 1 *}<br/>  

  9.       {# 循环输出 #}  

  10.       爱好:  

  11.       {% for i, v in ipairs(hobby) do %}  

  12.          {% if i > 1 then %},{% end %}  

  13.          {* v *}  

  14.       {% end %}<br/>  

  15.   

  16.       成绩:  

  17.       {% local i = 1; %}  

  18.       {% for k, v in pairs(score) do %}  

  19.          {% if i > 1 then %},{% end %}  

  20.          {* k *} = {* v *}  

  21.          {% i = i + 1 %}  

  22.       {% end %}<br/>  

  23.       成绩2:  

  24.       {% for i = 1, #score2 do local t = score2[i] %}  

  25.          {% if i > 1 then %},{% end %}  

  26.           {* t.name *} = {* t.score *}  

  27.       {% end %}<br/>  

  28.       {# 中间内容不解析 #}  

  29.       {-raw-}{(file)}{-raw-}  

  30. {(footer.html)}  

{(include_file)}:包含另一个模板文件;

 

{* var *}:变量输出;

{{ var }}:变量转义输出;

{% code %}:代码片段;

{# comment #}:注释;

{-raw-}:中间的内容不会解析,作为纯文本输出;

 

模板最终被转换为Lua代码进行执行,所以模板中可以执行任意Lua代码。 

 

3、example.conf配置文件

Java代码  收藏代码

  1. location /lua_template_3 {  

  2.     default_type 'text/html';  

  3.     lua_code_cache on;  

  4.     content_by_lua_file /usr/example/lua/test_template_3.lua;  

  5. }  

访问如http://192.168.1.2/lua_template_3进行测试。 

 

基本的模板引擎使用到此就介绍完了。 


本文转载自:http://jinnianshilongnian.iteye.com/blog/2187775

共有 人打赏支持
epiclight
粉丝 3
博文 41
码字总数 79
作品 0
深圳
架构师
用Nginx+Lua(OpenResty)开发高性能Web应用

在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡、反向代理、代理缓存、限流等场景;而把Nginx作为一个Web容器使用的还不是那么广泛。Nginx的高性能是大家公认的,而Nginx开...

长征2号
2017/08/30
0
0
使用Nginx+Lua(OpenResty)开发高性能Web应用

使用Nginx+Lua(OpenResty)开发高性能Web应用 博客分类: 跟我学Nginx+Lua开发 架构 ngxluaopenresty 在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡、反向代理、代理缓存、...

fdhay
2016/08/31
45
0
使用Nginx+Lua(OpenResty)开发高性能Web应用

Nginx+Lua(OpenResty)开发高性能Web应用 使用Nginx+Lua(OpenResty)开发高性能Web应用 在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡、反向代理、代理缓存、限流等场景;而...

oldgril
2017/02/27
0
0
模仿京东使用Openresty+Redis做读服务

看了开涛的Nginx+Lua开发教程,很是感兴趣。所以,自己也把环境搭建起来玩。 跟开涛的不同,我使用Vagrant + Ansible来搭建(不要问我为什么不使用Docker)。这样,所有的人只要两条命令就可...

翟志军
2016/10/17
4.9K
11
使用Nginx+Lua(OpenResty)开发高性能Web应用

一、ngx_lua简介 1 、Nginx 优点 Nginx设计为一个主进程多个工作进程的工作模式,每个进程是单线程来处理多个连接,而且每个工作进程采用了非阻塞I/O来处理多个连接,从而减少了线程上下文切...

DB_Terrill
2016/10/26
129
0

没有更多内容

加载失败,请刷新页面

加载更多

【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
57分钟前
1
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
9
0
vm GC 日志 配置及查看

-XX:+PrintGCDetails 打印 gc 日志 -XX:+PrintTenuringDistribution 监控晋升分布 -XX:+PrintGCTimeStamps 包含时间戳 -XX:+printGCDateStamps 包含时间 -Xloggc:<filename> 可以将数据保存为......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部