Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 80行Lua代码实现一个满足基本要求的模版引擎

80行Lua代码实现一个满足基本要求的模版引擎,以下内容仅供学习交流,未经严格考虑与测试,切勿用于生产环境。ltemplate.lualocal 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, " ")         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() endmaster.html<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="zh-CN" xml:lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml"> <head>   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>   <meta http-equiv="Content-Language" content="zh-CN"/>   <meta name="robots" content="index, follow" />   <link rel="shortcut icon" type="image/x-icon" href="/img/favicon.ico" />   <title> child&apos;s personal page - 开源中国社区</title>       <link rel="stylesheet/less" href="http://my.oschina.net/lostchild/styles.less?ver=20131219&date=20131110185237" type="text/css" media="screen" />   <link rel="stylesheet" href="/js/2012/poshytip/tip-yellowsimple/tip-yellowsimple.css" type="text/css" />   <link rel="stylesheet" type="text/css" href="/js/2011/fancybox/jquery.fancybox-1.3.4.css" media="screen" />   <script type="text/javascript" src="/js/2012/jquery-1.7.1.min.js"></script>   <script type="text/javascript" src="/js/2012/jquery.form.js"></script>   <script type="text/javascript" src="/js/2011/fancybox/jquery.fancybox-1.3.4.pack.js"></script>   <script type="text/javascript" src="/js/2012/poshytip/jquery.poshytip.min.js"></script>   <script type="text/javascript" src="/js/2011/oschina.js?ver=20121007"></script>   <script type="text/javascript" src="/js/2012/less-1.3.0.min.js"></script>   <script type="text/javascript" src="/js/scrolltopcontrol.js"></script>   <script type="text/javascript" src="/js/jquery/jquery.atwho.js?ver=2013112501"></script>   <link rel="stylesheet" type="text/css" href="/js/jquery/jquery.atwho.css" />   <link rel="alternate" type="application/rss+xml" title="lostchild最新博客" href="http://my.oschina.net/lostchild/rss" />   <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://my.oschina.net/action/xmlrpc/rsd?space=1397642" />   <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://my.oschina.net/action/xmlrpc/wlwmanifest?space=1397642" />   {# echo(header) #} </head> <body> {# echo(content) #} <body> </html>temp.html,继承master.html{# ob_start() #} <script>     alert("hello World") </script> {# local header = ob_get_clean() #}   {# ob_start() #} <table> {# for k, v in pairs(params) do #} <tr>     <td>{# echo(k) #}</td>     <td>{# echo(v) #}</td> </tr> {# end #} </table> {# local content = ob_get_clean() #}  {# include("master.html", {header = header, content = content}) #}循环十万次测试渲染速度(阿里云最便宜一款vps)[root@AY130801221248587d02Z ~]# time lua ltemplate.lua temp.html 
real    0m1.867s user    0m1.862s sys    0m0.004s总结由此可见渲染的速度还是非常快的,可以将此原型用于嵌入式设备中的页面上(用大量js实现的嵌入式设备页面兼容性不好)。而且嵌入式设备的界面需要简单明确,所以也不用太丰富的模版功能。原理很简单:1.用lua版的正则把模版内{#与#}之间的内容挖出来,原样输出成lua代码,其它部分则生成使用echo打印到某个缓冲区的lua代码。2.将这个生成出来的代码使用loadstring编译。3.通过setfenv实现loadstring后的模拟环境配置(用以提供模版内使用的echo,ob_start等函数,以及传入的参数)4.执行这个编译后的函数即可。Lua 的详细介绍:请点这里
Lua 的下载地址:请点这里推荐阅读:Lua 语言 15 分钟快速入门 http://www.linuxidc.com/Linux/2013-06/86582.htmLua程序设计(第2版)中文 PDF http://www.linuxidc.com/Linux/2013-03/81833.htmLua程序设计(第二版)阅读笔记 http://www.linuxidc.com/Linux/2013-03/81834.htmNetBSD 将支持用 Lua 脚本开发内核组件 http://www.linuxidc.com/Linux/2013-02/79527.htmCentOS 编译安装 Lua LuaSocket http://www.linuxidc.com/Linux/2011-08/41105.htm