diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d16e09e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# v1.2.0 2015 +* 忘了更新啥了 + +# v1.1.0 2014-08-16 +* 优化引擎的核心算法,性能大幅度提升。 +* 在不丧失功能的前提下,代码减少0.5kb +* 模版规则微调,通过d来读取字段,如:{{ d.title }} +* 修复缓存模版,并渲染不同数据时,视图不改变的bug \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..be179b1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 layui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index c949bff..3fde80c 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,26 @@ -## 简要 -laytpl是一款颠覆性的JavaScript模板引擎,它用巧妙的实现方式,将自身的体积变得小巧玲珑,不仅性能接近极致,并且还具备传统前端引擎的几乎所有功能。所有的变身魔法都由不到1KB的代码创造,这仿佛是一场革命,又或者不是,但毋庸置疑的是,laytpl的确在用最轻量的方式呈现给世人。如果你对此心存质疑,没关系,下面的讲述将会让你迫不及待地选择laytpl,从此更好地把握页面的数据渲染,走上人生巅峰! - -[文档与演示](http://sentsin.com/layui/laytpl/) - -![laytpl](http://sentsin.qiniudn.com/sentsinlaytpltuiguang.png) - -## 优势 -1. 性能卓绝,执行速度比号称性能王的artTemplate、doT还要快将近1倍,比baiduTemplate、kissyTemplate等快20-40倍,数据规模和渲染频率越大越明显。([性能测试](http://sentsin.com/layui/laytpl/test.html)) -2. 体积小到极致,只有1kb。 -3. 具备转义等安全机制,较科学的报错功能。 -4. 模版中可任意书写Native JavaScript,充分确保模版的灵活度。 -5. 支持应用在Node.js平台。 -6. 支持所有古代或现代的主流浏览器。 - -## 更新日志 - -【1.1】 2014-08-16 - -1. 优化引擎的核心算法,性能大幅度提升。 -2. 在不丧失功能的前提下,代码减少0.5kb -3. 模版规则微调,通过d来读取字段,如:{{ d.title }} -4. 修复缓存模版,并渲染不同数据时,视图不改变的bug - -【1.0】 2014-8-10(首个版本) - -## 备注 -[官网](http://sentsin.com/layui/laytpl/) +## 介绍 +laytpl是一款非常轻量的JavaScript模板引擎,语法遵循原生JS。laytpl试图打造极简的模版渲染。 + + +## 模版语法 + +输出一个普通字段,不转义html: +``` +{{ d.field }} +``` +输出一个普通字段,并转义html: +``` +{{= d.field }} +``` +逻辑处理: +``` +{{# JavaScript表达式 }} +``` + +## 协议 +MIT License + +## 其它 +[更多文档](http://www.layui.com/doc/modules/laytpl.html) diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..7a2e38d --- /dev/null +++ b/bower.json @@ -0,0 +1,19 @@ +{ + "name": "laytpl", + "main": "src/laytpl.js", + "version": "1.2.0", + "homepage": "https://github.com/sentsin/laytpl", + "authors": [ + "sentsin " + ], + "description": "JS模板引擎", + "moduleType": [ + "amd", + "globals" + ], + "keywords": [ + "laytpl", + "templeate" + ], + "license": "MIT" +} diff --git a/build/laytpl.js b/build/laytpl.js new file mode 100644 index 0000000..d345679 --- /dev/null +++ b/build/laytpl.js @@ -0,0 +1,2 @@ +/*! laytpl-v1.2.0 JavaScript模板引擎 MIT License By http://www.layui.com/doc/modules/laytpl.html */ + ;!function(){"use strict";var e={open:"{{",close:"}}"},r={exp:function(e){return new RegExp(e,"g")},query:function(r,t,c){var o=["#([\\s\\S])+?","([^{#}])*?"][r||0];return n((t||"")+e.open+o+e.close+(c||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var n="Laytpl Error:";return"object"==typeof console&&console.error(n+e+"\n"+(r||"")),n+e}},n=r.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(t,c){var o=this,p=t,a=n("^"+e.open+"#",""),l=n(e.close+"$","");t=t.replace(/\s+|\r|\t|\n/g," ").replace(n(e.open+"#"),e.open+"# ").replace(n(e.close+"}"),"} "+e.close).replace(/\\/g,"\\\\").replace(/(?="|')/g,"\\").replace(r.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(r.query(1),function(r){var t='"+(';return r.replace(/\s/g,"")===e.open+e.close?"":(r=r.replace(n(e.open+"|"+e.close),""),/^=/.test(r)&&(r=r.replace(/^=/,""),t='"+_escape_('),t+r.replace(/\\/g,"")+')+"')}),t='"use strict";var view = "'+t+'";return view;';try{return o.cache=t=new Function("d, _escape_",t),t(c,r.escape)}catch(u){return delete o.cache,r.error(u,p)}},t.pt.render=function(e,n){var t,c=this;return e?(t=c.cache?c.cache(e,r.escape):c.parse(c.tpl,e),console.log(),n?void n(t):t):r.error("no data")};var c=function(e){return"string"!=typeof e?r.error("Template not found"):new t(e)};c.config=function(r){r=r||{};for(var n in r)e[n]=r[n]},c.v="1.2","function"==typeof define?define(function(){return c}):"undefined"!=typeof exports?module.exports=c:window.laytpl=c}(); \ No newline at end of file diff --git "a/doc/\346\233\264\346\226\260\346\227\245\345\277\227.txt" "b/doc/\346\233\264\346\226\260\346\227\245\345\277\227.txt" deleted file mode 100644 index 1746e25..0000000 --- "a/doc/\346\233\264\346\226\260\346\227\245\345\277\227.txt" +++ /dev/null @@ -1,9 +0,0 @@ -http://sentsin.com/layui/laytpl/ - -1.1־2014-08-16 -1Żĺ㷨ܴ -2ڲɥʧܵǰ£0.5kb -3ģ΢ͨdȡֶΣ磺{{ d.title }} -4޸ģ棬Ⱦͬʱͼıbug - - diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..8dff361 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,27 @@ +/** + laytpl构建 +*/ + +var pkg = require('./package.json'); + +var gulp = require('gulp'); +var uglify = require('gulp-uglify'); +var header = require('gulp-header'); +var del = require('del'); + +gulp.task('clear', function(cb){ //清理 + return del(['./build/*'], cb); +}); + +//全部 +gulp.task('default', ['clear'], function(){ + return gulp.src('./src/laytpl.js').pipe(uglify()) + .pipe(header('/*! <%= pkg.name %>-v<%= pkg.version %> <%= pkg.description %> <%= pkg.license %> License By <%= pkg.homepage %> */\n ;', {pkg: pkg})) + .pipe(gulp.dest('./build')); +}); + + + + + + diff --git a/lib/laytpl.dev.js b/lib/laytpl.dev.js deleted file mode 100644 index 40932cf..0000000 --- a/lib/laytpl.dev.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - - @Name : laytpl v1.1 - 精妙的JavaScript模板引擎 - @Author: 贤心 - @Date: 2014-08-16 - @Site:http://sentsin.com/layui/laytpl - @License:MIT license - - */ - -;!function(win){ -"use strict"; - -var config = { - open: '{{', - close: '}}' -}; - -var tool = { - exp: function(str){ - return new RegExp(str, 'g'); - }, - //匹配满足规则内容 - query: function(type, _, __){ - var types = [ - '#([\\s\\S])+?', //js语句 - '([^{#}])*?' //普通字段 - ][type || 0]; - return exp((_||'') + config.open + types + config.close + (__||'')); - }, - escape: function(html){ - return String(html||'').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&') - .replace(//g, '>').replace(/'/g, ''').replace(/"/g, '"'); - }, - error: function(e, tplog){ - var error = 'Laytpl Error:'; - typeof console === 'object' && console.error(error + e + '\n'+ (tplog || '')); - return error + e; - } -}; - -var exp = tool.exp, Tpl = function(tpl){ - this.tpl = tpl; -}; - -Tpl.pt = Tpl.prototype; - -//核心引擎 -Tpl.pt.parse = function(tpl, data){ - var that = this, tplog = tpl; - var jss = exp('^'+config.open+'#', ''), jsse = exp(config.close+'$', ''); - - tpl = tpl.replace(/[\r\t\n]/g, ' ').replace(exp(config.open+'#'), config.open+'# ') - .replace(exp(config.close+'}'), '} '+config.close).replace(/\\/g, '\\\\') - .replace(/(?="|')/g, '\\').replace(tool.query(), function(str){ - str = str.replace(jss, '').replace(jsse, ''); - return '";' + str.replace(/\\/g, '') + '; view+="'; - }).replace(tool.query(1), function(str){ - var start = '"+('; - if(str.replace(/\s/g, '') === config.open+config.close){ - return ''; - } - str = str.replace(exp(config.open+'|'+config.close), ''); - if(/^=/.test(str)){ - str = str.replace(/^=/, ''); - start = '"+_escape_('; - } - return start + str.replace(/\\/g, '') + ')+"'; - }); - - tpl = '"use strict";var view = "' + tpl + '";return view;'; - //console.log(tpl); - try{ - that.cache = tpl = new Function('d, _escape_', tpl); - return tpl(data, tool.escape); - } catch(e){ - delete that.cache; - return tool.error(e, tplog); - } -}; - -Tpl.pt.render = function(data, callback){ - var that = this, tpl; - if(!data) return tool.error('no data'); - tpl = that.cache ? that.cache(data, tool.escape) : that.parse(that.tpl, data); - if(!callback) return tpl; - callback(tpl); -}; - -var laytpl = function(tpl){ - if(typeof tpl !== 'string') return tool.error('Template not found'); - return new Tpl(tpl); -}; - -laytpl.config = function(options){ - options = options || {}; - for(var i in options){ - config[i] = options[i]; - } -}; - -laytpl.v = '1.1'; - -"function" == typeof define ? define(function() { - return laytpl -}) : "undefined" != typeof exports ? module.exports = laytpl : window.laytpl = laytpl - -}(); diff --git a/lib/laytpl.js b/lib/laytpl.js deleted file mode 100644 index 016e5bb..0000000 --- a/lib/laytpl.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - - @Name:laytpl-v1.1 精妙的js模板引擎 - @Author:贤心 - 2014-08-16 - @Site:http://sentsin.com/layui/laytpl - @License:MIT license - */ - -;!function(){"use strict";var f,b={open:"{{",close:"}}"},c={exp:function(a){return new RegExp(a,"g")},query:function(a,c,e){var f=["#([\\s\\S])+?","([^{#}])*?"][a||0];return d((c||"")+b.open+f+b.close+(e||""))},escape:function(a){return String(a||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(a,b){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+a+"\n"+(b||"")),c+a}},d=c.exp,e=function(a){this.tpl=a};e.pt=e.prototype,e.pt.parse=function(a,e){var f=this,g=a,h=d("^"+b.open+"#",""),i=d(b.close+"$","");a=a.replace(/[\r\t\n]/g," ").replace(d(b.open+"#"),b.open+"# ").replace(d(b.close+"}"),"} "+b.close).replace(/\\/g,"\\\\").replace(/(?="|')/g,"\\").replace(c.query(),function(a){return a=a.replace(h,"").replace(i,""),'";'+a.replace(/\\/g,"")+'; view+="'}).replace(c.query(1),function(a){var c='"+(';return a.replace(/\s/g,"")===b.open+b.close?"":(a=a.replace(d(b.open+"|"+b.close),""),/^=/.test(a)&&(a=a.replace(/^=/,""),c='"+_escape_('),c+a.replace(/\\/g,"")+')+"')}),a='"use strict";var view = "'+a+'";return view;';try{return f.cache=a=new Function("d, _escape_",a),a(e,c.escape)}catch(j){return delete f.cache,c.error(j,g)}},e.pt.render=function(a,b){var e,d=this;return a?(e=d.cache?d.cache(a,c.escape):d.parse(d.tpl,a),b?(b(e),void 0):e):c.error("no data")},f=function(a){return"string"!=typeof a?c.error("Template not found"):new e(a)},f.config=function(a){a=a||{};for(var c in a)b[c]=a[c]},f.v="1.1","function"==typeof define?define(function(){return f}):"undefined"!=typeof exports?module.exports=f:window.laytpl=f}(); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2931a10 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "laytpl", + "version": "1.2.0", + "description": "JavaScript模板引擎", + "main": "src/laytpl.js", + "license": "MIT", + "scripts": { + "run": "gulp" + }, + "repository": { + "type": "https", + "url": "https://github.com/sentsin/laytpl.git" + }, + "author": "贤心", + "homepage": "http://www.layui.com/doc/modules/laytpl.html", + "devDependencies": { + "gulp": "^3.9.0", + "gulp-uglify": "^1.5.4", + "gulp-header": "^1.8.8", + "del": "^2.2.2" + } +} diff --git a/src/laytpl.js b/src/laytpl.js new file mode 100644 index 0000000..62ac336 --- /dev/null +++ b/src/laytpl.js @@ -0,0 +1,116 @@ +/** + + @Name : laytpl v1.2 - 精妙的JavaScript模板引擎 + @Author: 贤心 + @Date: 2014-10-27 + @Site:http://sentsin.com/layui/laytpl + @License:MIT + + */ + +;!function(){ +"use strict"; + +var config = { + open: '{{', + close: '}}' +}; + +var tool = { + exp: function(str){ + return new RegExp(str, 'g'); + }, + //匹配满足规则内容 + query: function(type, _, __){ + var types = [ + '#([\\s\\S])+?', //js语句 + '([^{#}])*?' //普通字段 + ][type || 0]; + return exp((_||'') + config.open + types + config.close + (__||'')); + }, + escape: function(html){ + return String(html||'').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&') + .replace(//g, '>').replace(/'/g, ''').replace(/"/g, '"'); + }, + error: function(e, tplog){ + var error = 'Laytpl Error:'; + typeof console === 'object' && console.error(error + e + '\n'+ (tplog || '')); + return error + e; + } +}; + +var exp = tool.exp, Tpl = function(tpl){ + this.tpl = tpl; +}; + +Tpl.pt = Tpl.prototype; + +window.errors = 0; + +//编译模版 +Tpl.pt.parse = function(tpl, data){ + var that = this, tplog = tpl; + var jss = exp('^'+config.open+'#', ''), jsse = exp(config.close+'$', ''); + + tpl = tpl.replace(/\s+|\r|\t|\n/g, ' ').replace(exp(config.open+'#'), config.open+'# ') + + .replace(exp(config.close+'}'), '} '+config.close).replace(/\\/g, '\\\\') + + .replace(/(?="|')/g, '\\').replace(tool.query(), function(str){ + str = str.replace(jss, '').replace(jsse, ''); + return '";' + str.replace(/\\/g, '') + ';view+="'; + }) + + .replace(tool.query(1), function(str){ + var start = '"+('; + if(str.replace(/\s/g, '') === config.open+config.close){ + return ''; + } + str = str.replace(exp(config.open+'|'+config.close), ''); + if(/^=/.test(str)){ + str = str.replace(/^=/, ''); + start = '"+_escape_('; + } + return start + str.replace(/\\/g, '') + ')+"'; + }); + + tpl = '"use strict";var view = "' + tpl + '";return view;'; + //console.log(tpl); + + try{ + that.cache = tpl = new Function('d, _escape_', tpl); + return tpl(data, tool.escape); + } catch(e){ + delete that.cache; + return tool.error(e, tplog); + } +}; + +Tpl.pt.render = function(data, callback){ + var that = this, tpl; + if(!data) return tool.error('no data'); + tpl = that.cache ? that.cache(data, tool.escape) : that.parse(that.tpl, data); + console.log() + if(!callback) return tpl; + callback(tpl); +}; + +var laytpl = function(tpl){ + if(typeof tpl !== 'string') return tool.error('Template not found'); + return new Tpl(tpl); +}; + +laytpl.config = function(options){ + options = options || {}; + for(var i in options){ + config[i] = options[i]; + } +}; + +laytpl.v = '1.2'; + +"function" == typeof define ? define(function() { + return laytpl +}) : "undefined" != typeof exports ? module.exports = laytpl : window.laytpl = laytpl + +}(); \ No newline at end of file diff --git a/test/demo.url b/test/demo.url index f5229e6..e57d004 100644 --- a/test/demo.url +++ b/test/demo.url @@ -1,6 +1,8 @@ [{000214A0-0000-0000-C000-000000000046}] Prop3=19,2 [InternetShortcut] -URL=http://sentsin.com/layui/laytpl/ +URL=http://www.layui.com/demo/laytpl.html IDList= HotKey=0 +IconIndex=0 +IconFile=C:\Program Files (x86)\Google\Chrome\Application\chrome.exe