您现在的位置是:网站首页> 编程资料编程资料

使用Lua编写Web端模板引擎的实例代码分享_Lua_

2023-05-26 283人已围观

简介 使用Lua编写Web端模板引擎的实例代码分享_Lua_

ltemplate.lua

 local insert = table.insert local remove = table.remove local concat = table.concat local format = string.format local loaded = {} local partten = "(.-){#([^#].-[^#])#}()" local content = {} local cur_content = nil local function ob_start() cur_content = {} insert(content, cur_content) end local function ob_get_clean() local ret = concat(cur_content) remove(content) cur_content = content[#content] return ret end local function echo(value) insert(cur_content, value) end local function include(path, params) local bitcode = loaded[path] if not bitcode then local fp = io.open(path, "rb") local template = fp:read('*a') fp:close() local results = {} local last_endpos = 0 for outside, inside, endpos in template:gmatch(partten) do insert(results, format("echo(%q)", outside)) insert(results, inside) last_endpos = endpos end insert(results, format("echo(%q)", template:sub(last_endpos))) results = concat(results, "\n") bitcode = assert(loadstring(results)) loaded[path] = bitcode end local env = { include = include, echo = echo, ob_start = ob_start, ob_get_clean = ob_get_clean } setmetatable(env, {__index = function(tb, k) return params[k] or _G[k] end}) setfenv(bitcode, env) bitcode() end for i = 1, 100000 do ob_start() include(arg[1], { params = { a = '1234', b = '4321' } }) ob_get_clean() end 

master.html

 child's personal page - 开源中国社区 {# echo(header) #}  {# echo(content) #} 

temp.html,继承master.html

 {# ob_start() #}  {# local header = ob_get_clean() #} {# ob_start() #}  {# for k, v in pairs(params) do #}  {# end #} 
{# echo(k) #}{# echo(v) #}
{# local content = ob_get_clean() #} {# include('master.html', {header = header, content = content}) #}

循环十万次测试渲染速度(阿里云最便宜一款vps)

 [root@AY130801221248587d02Z ~]# time lua ltemplate.lua temp.htmlreal 0m1.867s 
 user 0m1.862s sys 0m0.004s 

总结

由此可见渲染的速度还是非常快的,可以将此原型用于嵌入式设备中的页面上(用大量js实现的嵌入式设备页面兼容性不好)。而且嵌入式设备的界面需要简单明确,所以也不用太丰富的模版功能。

原理很简单:

1.用lua版的正则把模版内{#与#}之间的内容挖出来,原样输出成lua代码,其它部分则生成使用echo打印到某个缓冲区的lua代码。

2.将这个生成出来的代码使用loadstring编译。

3.通过setfenv实现loadstring后的模拟环境配置(用以提供模版内使用的echo,ob_start等函数,以及传入的参数)

4.执行这个编译后的函数即可。

-六神源码网