博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
高并发 Nginx+Lua OpenResty系列(8)——Lua模版渲染
阅读量:4627 次
发布时间:2019-06-09

本文共 4803 字,大约阅读时间需要 16 分钟。

模版渲染

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

wget https://github.com/bungle/lua-resty-template/archive/v1.9.tar.gztar -xvzf v1.9.tar.gz

解压后可以看到lib/resty下面有一个template.lua,这个就是我们所需要的,在template目录中还有两个lua文件,将这两个文件复制到/usr/openResty/lualib/resty中即可。

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

local template = require("resty.template")

模版位置

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

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

# first match ngx locationset $template_location "/templates";# then match root read fileset $template_root "/usr/openResty/templates";

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

root /usr/openResty/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 pathend
  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/openResty/templatesmkdir /usr/openResty/templates2

openResty.conf配置文件

# first match ngx locationset $template_location "/templates";# then match root read fileset $template_root "/usr/openResty/templates";location /templates {    internal;    alias /usr/openResty/templates2;}

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

然后创建两个模板文件

vi /usr/openResty/templates2/t1.html

内容为

template2
vi /usr/example/templates/t1.html

内容为

template1

test_temlate_1.lua

local template = require("resty.template")template.render("t1.html")

openResty.conf配置文件

location /lua_template_1 {    default_type 'text/html';    lua_code_cache on;    content_by_lua_file /usr/openResty/lua/test_template_1.lua;}

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

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

API

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

test_template_2.lua

local template = require("resty.template")--是否缓存解析后的模板,默认truetemplate.caching(true)--渲染模板需要的上下文(数据)local context = {title = "title"}--渲染模板template.render("t1.html", context)ngx.say("
")--编译得到一个lua函数local func = template.compile("t1.html")--执行函数,得到渲染之后的内容local content = func(context)--通过ngx API输出ngx.say(content)

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

openResty.conf配置文件

location /lua_template_2 {      default_type 'text/html';      lua_code_cache on;      content_by_lua_file /usr/openResty/lua/test_template_2.lua;  }

使用示例

test_template_3.lua

local template = require("resty.template")local context = {  title = "测试",  name = "张三",  description = "",  age = 20,  hobby = {"电影", "音乐", "阅读"},  score = {语文 = 90, 数学 = 80, 英语 = 70},  score2 = {    {name = "语文", score = 90},    {name = "数学", score = 80},    {name = "英语", score = 70},  }}template.render("t3.html", context)

模板文件/usr/openResty/templates/t3.html

      
{# 不转义变量输出 #} 姓名:{* string.upper(name) *}
{# 转义变量输出 #} 简介:{
{description}}
{# 可以做一些运算 #} 年龄: {* age + 1 *}
{# 循环输出 #} 爱好: {% for i, v in ipairs(hobby) do %} {% if i > 1 then %},{% end %} {* v *} {% end %}
成绩: {% local i = 1; %} {% for k, v in pairs(score) do %} {% if i > 1 then %},{% end %} {* k *} = {* v *} {% i = i + 1 %} {% end %}
成绩2: {% for i = 1, #score2 do local t = score2[i] %} {% if i > 1 then %},{% end %} {* t.name *} = {* t.score *} {% end %}
{# 中间内容不解析 #} {-raw-}{(file)}{-raw-}

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

{* var *}:变量输出;
{
{ var }}:变量转义输出;
{% code %}:代码片段;
{# comment #}:注释;
{-raw-}:中间的内容不会解析,作为纯文本输出;
模板最终被转换为Lua代码进行执行,所以模板中可以执行任意Lua代码。

openResty.conf配置文件

location /lua_template_3 {    default_type 'text/html';    lua_code_cache on;    content_by_lua_file /usr/openResty/lua/test_template_3.lua;}

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

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

转载于:https://www.cnblogs.com/babycomeon/p/11109494.html

你可能感兴趣的文章
spring security remember me实现自动登录
查看>>
ie6下常见的bug 调整页面兼容性
查看>>
初识python
查看>>
Jsoncpp 使用方法解析
查看>>
后台写的分页
查看>>
第1次java1作业
查看>>
Spring配置声明
查看>>
web.config配置
查看>>
Matlab随笔之矩阵入门知识
查看>>
线程范围内的数据共享
查看>>
css 背景样式学习
查看>>
oracle执行计划连接方式
查看>>
机器学习 决策树 ID3
查看>>
Cmake
查看>>
vue 之 nextTick 与$nextTick
查看>>
JavaScript中的加法运算
查看>>
JS设计模式——3.封装与信息隐藏
查看>>
git-- 使用
查看>>
Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo
查看>>
delphi对窗体的查询(delphi xe2)
查看>>