编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> Lua -> 使用Lua编写Web端模板引擎的实例代码分享 -> 正文阅读

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

这里我们给出一个使用Lua编写Web端模板引擎的实例代码分享,力求简洁(核心代码约为70行),仅实现最基本的模板功能:
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

<!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'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.htmlreal  0m1.867s


user  0m1.862s
sys   0m0.004s

总结
由此可见渲染的速度还是非常快的,可以将此原型用于嵌入式设备中的页面上(用大量js实现的嵌入式设备页面兼容性不好)。而且嵌入式设备的界面需要简单明确,所以也不用太丰富的模版功能。
原理很简单:
1.用lua版的正则把模版内{#与#}之间的内容挖出来,原样输出成lua代码,其它部分则生成使用echo打印到某个缓冲区的lua代码。
2.将这个生成出来的代码使用loadstring编译。
3.通过setfenv实现loadstring后的模拟环境配置(用以提供模版内使用的echo,ob_start等函数,以及传入的参数)
4.执行这个编译后的函数即可。
  Lua 最新文章
OpenResty中正则模式匹配的2种方法详解
Lua Table转C# Dictionary的方法示例
Lua语言新手简单入门教程
利用Lua定制Redis命令的方法详解
Lua判断变量是否为数字、字符串是否可以转换
Lua中设置table为只读属性的方法详解
Lua学习笔记之表和函数
简单的Lua 连接操作mysql数据库的方法
Lua 数学库的所有函数功能作用一览
Lua极简入门指南:全局变量
上一篇文章      下一篇文章      查看所有文章
加:2016-11-09 23:03:21  更:2017-05-14 02:44:29 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年10日历
2019-10-22 20:02:04
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识