第五章 常用Lua开发库3-模板渲染
来源:互联网 发布:android 屏保源码 编辑:程序博客网 时间:2024/06/01 09:53
动态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
- cd /usr/example/lualib/resty/
- wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua
- mkdir /usr/example/lualib/resty/html
- cd /usr/example/lualib/resty/html
- wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua
接下来就可以通过如下代码片段引用了
- local template = require("resty.template")
模板位置
我们需要告诉lua-resty-template去哪儿加载我们的模块,此处可以通过set指令定义template_location、
template_root或者从root指令定义的位置加载。
如我们可以在example.conf配置文件的server部分定义
- #first match ngx location
- set $template_location "/templates";
- #then match root read file
- set $template_root "/usr/example/templates";
也可以通过在server部分定义root指令
- root /usr/example/templates;
其顺序是
- 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查找,如果找到(状态为为200)则使用该内容作为模板;此种方式是一种动态获取模板方式;
2、如果定义了template_root,则从该位置通过读取文件的方式加载模板;
3、如果没有定义template_root,则默认从root指令定义的document_root处加载模板。
此处建议首先template_root,如果实在有问题再使用template_location,尽量不要通过root指令定义的document_root加载,因为其本身的含义不是给本模板引擎使用的。
接下来定义模板位置
- mkdir /usr/example/templates
- mkdir /usr/example/templates2
example.conf配置server部分
- #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,找不到会查找/usr/example/templates。
然后创建两个模板文件
- vim /usr/example/templates2/t1.html
内容为
- template2
- vim /usr/example/templates/t1.html
内容为
- template1
test_temlate_1.lua
- local template = require("resty.template")
- template.render("t1.html")
example.conf配置文件
- 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输出。
接下来的测试我们会把模板文件都放到/usr/example/templates下。
API
使用模板引擎目的就是输出响应内容;主要用法两种:直接通过ngx.print输出或者得到模板渲染之后的内容按照想要的规则输出。
1、test_template_2.lua
- local template = require("resty.template")
- --是否缓存解析后的模板,默认true
- template.caching(true)
- --渲染模板需要的上下文(数据)
- local context = {title = "title"}
- --渲染模板
- template.render("t1.html", context)
- ngx.say("<br/>")
- --编译得到一个lua函数
- local func = template.compile("t1.html")
- --执行函数,得到渲染之后的内容
- local content = func(context)
- --通过ngx API输出
- ngx.say(content)
常见用法即如下两种方式:要么直接将模板内容直接作为响应输出,要么得到渲染后的内容然后按照想要的规则输出。
2、examle.conf配置文件
- 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
- local template = require("resty.template")
- local context = {
- title = "测试",
- name = "张三",
- description = "<script>alert(1);</script>",
- age = 20,
- hobby = {"电影", "音乐", "阅读"},
- score = {语文 = 90, 数学 = 80, 英语 = 70},
- score2 = {
- {name = "语文", score = 90},
- {name = "数学", score = 80},
- {name = "英语", score = 70},
- }
- }
- template.render("t3.html", context)
请确认文件编码为UTF-8;context即我们渲染模板使用的数据。
2、模板文件/usr/example/templates/t3.html
- {(header.html)}
- <body>
- {# 不转义变量输出 #}
- 姓名:{* string.upper(name) *}<br/>
- {# 转义变量输出 #}
- 简介:{{description}}<br/>
- {# 可以做一些运算 #}
- 年龄: {* age + 1 *}<br/>
- {# 循环输出 #}
- 爱好:
- {% for i, v in ipairs(hobby) do %}
- {% if i > 1 then %},{% end %}
- {* v *}
- {% end %}<br/>
- 成绩:
- {% local i = 1; %}
- {% for k, v in pairs(score) do %}
- {% if i > 1 then %},{% end %}
- {* k *} = {* v *}
- {% i = i + 1 %}
- {% end %}<br/>
- 成绩2:
- {% for i = 1, #score2 do local t = score2[i] %}
- {% if i > 1 then %},{% end %}
- {* t.name *} = {* t.score *}
- {% end %}<br/>
- {# 中间内容不解析 #}
- {-raw-}{(file)}{-raw-}
- {(footer.html)}
{(include_file)}:包含另一个模板文件;
{* var *}:变量输出;
{{ var }}:变量转义输出;
{% code %}:代码片段;
{# comment #}:注释;
{-raw-}:中间的内容不会解析,作为纯文本输出;
模板最终被转换为Lua代码进行执行,所以模板中可以执行任意Lua代码。
3、example.conf配置文件
- 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进行测试。
基本的模板引擎使用到此就介绍完了。
来源:http://jinnianshilongnian.iteye.com/blog/2187775
- 第五章 常用Lua开发库3-模板渲染
- lua开发--模板渲染
- 第五章 常用Lua开发库2-JSON库、编码转换、字符串处理
- 第五章 常用Lua开发库1-redis、mysql、http客户端
- lua第五章函数学习
- 用newLisp开发网站三 模板渲染
- 开发中常用的模板库
- 渲染模板
- 模板 渲染
- 渲染模板
- 常用 Lua 开发库 1-redis、mysql、http 客户端
- 常用Lua开发库redis、mysql、http客户端
- 深入XSLT第五章--- 模板
- 为什么JSP渲染比常用模板(freemarker\Velcoity\beetl)慢
- ASP.NET自定义控件组件开发 第五章 模板控件开发
- ASP.NET自定义控件组件开发 第五章 模板控件开发
- Lua 常用库
- lua常用数学库
- 浅谈幅度调制(Amplitude Modulation)
- finished with non-zero exit value 1
- ssh免密登陆配置
- Codeforces Round #422 (Div. 2) D. My pretty girl Noora 动态规划
- Linux url调测工具--curl
- 第五章 常用Lua开发库3-模板渲染
- 剑指offer-二叉树中和为某一值的路径
- Linux下常用的C/C++开源Socket库
- ajax跨域请求springmvc传递json对象参数
- boost::static_pointer_cast、boost::dynamic_pointer_cast和boost::const_pointer_cast
- 同步与异步,阻塞与非阻塞
- Leetcode 309. Best Time to Buy and Sell Stock with Cooldown
- 基于TCP的多进程和多线程服务器
- ajax如何处理服务器返回的3种数据格式