Created
June 24, 2012 14:55
-
-
Save kindy/2983544 to your computer and use it in GitHub Desktop.
在 ngx_lua 中实现类似 php 的被嵌入 html 功能
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"abc" | |
<?= 124 ?> | |
<?= a ?> | |
<? local x = 12 | |
if math.random(1, 5) > 1 then ?> | |
xxx | |
<? else ?> | |
yyy | |
<? end ?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 在 http://www.savarese.com/software/ltp/ 获取 ltp | |
-- lposix 可以在 https://github.com/rrthomas/luaposix.git 获取 | |
-- 把 ltp 目录和当前文件放到 ngx_lua 可搜索的地方 在希望使用模板的nginx配置中添加以下定义即可 | |
local ltp = require 'ltp.template' | |
local posix = nil | |
do | |
local ok, ret = pcall(require, 'posix') | |
if ok then | |
posix = ret | |
end | |
end | |
local ltp_cache = {} | |
module(..., package.seeall) | |
-- in: filename | |
-- in: mode - 1 force cache, 2 nocache, 3 mtime cache | |
-- out: render function | |
function loadltp(path, mode) | |
mode = mode or 1 | |
if mode == 3 and not posix then | |
mode = 2 | |
end | |
if ltp_cache[path] then | |
if mode == 1 then | |
return ltp_cache[path][2] | |
elseif mode == 2 then | |
ltp_cache[path] = nil | |
elseif mode == 3 then | |
if assert(posix.stat(path)).mtime < ltp_cache[1] then | |
return ltp_cache[path][2] | |
else | |
ltp_cache[path] = nil | |
end | |
end | |
end | |
local con = assert(io.open(ngx.var.request_filename, 'rb')):read('*a') | |
local str = assert(ltp.compile_template_as_function(con, '<?', '?>')) | |
local fn = assert(loadstring(str))() | |
ltp_cache[path] = {ngx.time(), fn} | |
return fn | |
end | |
function render(path) | |
path = path or ngx.var.request_filename | |
local fn = assert(loadltp(path)) | |
local ctx = {} | |
setmetatable(ctx, {__index = _G}) | |
local ret = {} | |
setfenv(fn, ctx) | |
fn(ret) | |
ngx.print(ret) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#在 http://www.savarese.com/software/ltp/ 下载 http://www.savarese.com/downloads/ltp/ltp-1.0.4.tar.bz2 | |
#把 ltp 目录放到 ngx_lua 可搜索的地方 在希望使用模板的nginx配置中添加以下定义即可 | |
#模板中可使用任意 lua 模块,如果想设置通用的对象,可在 ctx 变量中指定 | |
#模板例子见 a.ltp | |
location ~ \.ltp$ { | |
content_by_lua " | |
local ctx = { | |
a = 2; | |
} | |
local ltp = require 'ltp.template' | |
local con = assert(io.open(ngx.var.request_filename, 'rb')):read('*a') | |
local str = assert(ltp.compile_template_as_function(con, '<?', '?>')) | |
local fn = assert(loadstring(str))() | |
local ret = {} | |
setmetatable(ctx, {__index = _G}) | |
setfenv(fn, ctx) | |
fn(ret) | |
ngx.print(ret) | |
"; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 注意不要让其他 nginx 的 location 定义覆盖了这里的,那样你的源码就暴露了!!!!!! | |
# nginx 很容易出这样的问题 | |
location ~ \.ltp$ { | |
default_type text/html; | |
content_by_lua " require 'ltp_util'.render() "; | |
} |
同时,通过用户 Lua 模块级的变量来缓存 ltp 编译模版的结果,避免每请求都现编一次,可以极大地提高效率 :) 同时也可以避免每请求去现读磁盘 ;)
嗯嗯, ngx.print(ret) 可以有。
不过在用户态缓存可能不能简单全量缓存,毕竟传统用户习惯了改改文件就刷新之类。
Hello!
2012/6/24 kindy
reply@reply.github.com:
不过在用户态缓存可能不能简单全量缓存,毕竟传统用户习惯了改改文件就刷新之类。
生产环境里不会有人想改改文件就刷新吧?呵呵。对于开发模式,直接禁用 lua_code_cache 就可以了,Lua 模块便会每请求刷新。
Regards,
-agentzh
我强烈建议你吧。把 改成 可以么。
好处有三
第一 这个是HTML的标准注释 注释不解析是方便的,而且即便是很多不支持LUA的ide也不至于出错。
第二 跟PHP 5.4 + 以后的版本严重冲突啊。你有没有想过 如果你是个PHP程序员转过来的,写<? 以后 后面跟着是lua代码很奇怪?
第三 明示 阅读代码的小鸟 可能还在猜 这东西看着像 ruby啊 不对 更像NODEJS。 如果有了 小鸟一看 天哪这居然是我没看过的lua啊。
呃,个人比较喜欢 php 的这个标记风格。当然啦,你可以自己修改成任意想要的风格,
修改 local str = assert(ltp.compile_template_as_function(con, ''))
里面的 标记即可。。
比如 local str = assert(ltp.compile_template_as_function(con, ''))
这也是自己写的好处哈。。
local ltp = require("ltp.template")
ltp.render(io.stdout, 1, request.app_path .. "/lua.html", false, {}, '', { total="2400" })
然后怎么直接输出?不用NGX呢?
@fokite 你是要在哪里使用呢?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
直接 ngx.print(ret) 效率更高,因为可以免去拼接字符串的巨大开销。ngx.print 和 ngx.say 都支持字符串数组作为参数。