当前位置:首页 > 开发 > 系统架构 > 架构 > 正文

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

发表于: 2015-03-01   作者:jinnianshilongnian   来源:转载   浏览:
摘要: 动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。   如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r

动态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进行测试。 

 

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

 

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
os.time ([table]) 功能:按table的内容返回一个时间值(数字),若不带参数则返回当前时间.(在许多系
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(14)---Winform开发的常用类库(终结篇,CHM
源码已发布,请打开下载 http://www.cppblog.com/mybios/archive/2008/10/31/65636.html 上次发了个
1、检测网络连接 Reachablity 用来检测网络连接是否可用:包括WIFI和WWAN(3G/EDGE/CDMA等)2中工作
lua静态库的编译 lua静态库的编译 使用lua除了可以直接使用DLL之外,再有一个方法就是直接使用lua的
实在厌倦了做了多个游戏项目之后,对常用的数学计算总是算了又忘忘了再算。与其他技术问题相比,一
I/O库为文件操作提供两种模式。简单模式(simple model)拥有一个当前输入文件和一个当前输出文件,
Lua解释器对字符串的支持很有限。一个程序可以创建字符串并连接字符串,但不能截取子串,检查字符串
template<class T> class Array{   //... }; T就是类参数,T前面的关键字是class或typename
本章围绕ImageButton深入讨论,为什么是ImageButton? 图片本身就是表达美的最佳手段之一,自古形容
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号