TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

T.js - A tiny templating framework in ~400 bytes

91 pointsby jasonmooalmost 13 years ago

13 comments

whalesaladalmost 13 years ago
The one thing that sucks about projects with one-char names is finding them weeks after you first discover them, when you really want to experiment with using them in a real project.
评论 #4378838 未加载
评论 #4378782 未加载
评论 #4379390 未加载
评论 #4378742 未加载
Kilimanjaroalmost 13 years ago
I use this little helper in my underground lab:<p><pre><code> function template(str,data){ for(var i in data){ str=str.replace(new RegExp("{("+i+")}","g"),data[i]) } return str } </code></pre> It can be used with arrays and object literals as well:<p><pre><code> txt = template('hello {name}!',{name:'Jen'}) txt = template('days: {0}, {1} and {2}',['mon','tue','wed']) </code></pre> GPL and WTFPL just in case.<p>* Looks coincidentally similar to Fuchs'
评论 #4380046 未加载
评论 #4379155 未加载
thezilchalmost 13 years ago
And a few less-featureful templating-frameworks in 140 bytes or less: <a href="http://www.140byt.es/keywords/template" rel="nofollow">http://www.140byt.es/keywords/template</a><p>Notably, the examples found at <a href="https://gist.github.com/964762#file_test.js" rel="nofollow">https://gist.github.com/964762#file_test.js</a> has the closest parity.<p>Edit: On second thought, I think the previous gist can reach parity with just a helper function for iterating and escaping:<p><pre><code> function engine(a,b){return function(c,d){return a.replace(/#{([^}]*)}/g,function(a,e){return Function("x","with(x)return "+e).call(c,d||b||{})})}} function iterator(o, k, f){ var i, v = []; for(i in o[k]){ v = v.concat(f(o, k, i)); } return v.join(''); } function print_kv(o, k, i){ return [" ", i, ":", o[k][i]]; } hello = engine("Hello,#{iterator(this, 'users', print_user)}!") // We don't have to pass iterator, on the next line, but it should demonstrate // how we context can be overwritten hello({users: {a: 1, b: 2, c:3}}, {iterator: iterator, print_user: print_kv}) // Or don't pass print_user print_user = print_kv hello({users: {a: 1, b: 2, c:3}}) // "Hello, a:1 b:2 c:3!" // Overload it! hello({users: {a: 1, b: 2, c:3}}, {print_user: function(o, k, i){return " "+i}}) // "Hello, a b c!"</code></pre>
评论 #4379222 未加载
endlessvoid94almost 13 years ago
I'm not sure anyone's ever said "this templating framework is too big"
评论 #4380297 未加载
评论 #4384899 未加载
rabidsnailalmost 13 years ago
The 80% case:<p><pre><code> var render = function(src, data) { return src.replace(/{{(.*?)}}/g, function(w, p) { return data[p]; }); };</code></pre>
评论 #4379701 未加载
stcredzeroalmost 13 years ago
I wonder if it would be possible to fit an entire webserver and web framework runtime into L2 cache? (I'm thinking Lua VM or something like that.)<p>EDIT Xeon 3050 has 2MB of L2 cache, so the answer is probably yes!
评论 #4379011 未加载
thezilchalmost 13 years ago
I promised myself I'd show parity with <a href="https://gist.github.com/3346253#file_t_js_parity.js" rel="nofollow">https://gist.github.com/3346253#file_t_js_parity.js</a> at <a href="http://news.ycombinator.com/item?id=4378847" rel="nofollow">http://news.ycombinator.com/item?id=4378847</a>, but comments eventually go non-editable.<p>I haven't properly updated the gist fork yet, but as follows are the semi-minified additions [of `safe` and `map` (iter)] and parity tests.<p><pre><code> function t(a,b){ return function(c,d){ return a.replace(/#{([^}]*)}/g, function(a,e){ function safe(v){return new Option(v).innerHTML;} function map(o, f){ var k, v = []; for(k in o) v.push(f(k, o[k])); return v; } return Function("x",safe+map+"with(x)return "+e).call(c,d||b||{}) }) } } function l(v){ console.log(v); } // Simple interpolation: {{=value}} l(t("Hello, #{this.name}!")({name: "Mike"})); // Scrubbed interpolation: {{%unsafe_value}} l(t("Saved from #{safe(this.xss)}!")({xss: "&#60;script&#62;alert('xss')&#60;\/script&#62;"})); // Name-spaced variables: {{=User.address.city}} l(t("Hello1, #{this.user.name}!")({user: {name: "Mike"}})); // If/else blocks: {{value}} &#60;&#60;markup&#62;&#62; {{:value}} &#60;&#60;alternate markup&#62;&#62; {{/value}} l(t("Hello2, #{this.name || 'World'}!")({name: "Mike"})); l(t("Hello2, #{this.name || 'World'}!")()); l(t("Hello2, #{this.u ? this.u.name : 'World'}!")({u: {name: "Mike"}})); // If not blocks: {{!value}} &#60;&#60;markup&#62;&#62; {{/value}} l(t("Hello3, #{!this.u ? 'World' : ''}!")({user: {name: "Mike"}})); // Object/Array iteration: {{@object_value}} {{=_key}}:{{=_val}} {{/@object_value}} l(t("Hello4, #{map(this.users, print_user).join(', ')}!", { print_user: function(k, user){return user;} })({users: ["Mike", "John", "Bill"]})); // Maybe you have one of those new-fangled browsers w/ builtin map l(t("Hello4, #{this.users.map(print_user).join(', ')}!", { print_user: function(user){return user;} })({users: ["Mike", "John", "Bill"]})); // Let's go deeper... l(t("Hello4, #{map(this.users, user).join(', ')}!", { user: function(_, user){ return t("#{safe(this.name)}")(user); } })({users:[{name: "Mike"}, {name: "John&#60;3"}, {name: "Bill"}]})); // Render the same template multiple times with different data hello = t("Hello5, and #{this.goodbye}!"); l(hello({goodbye: "goodbye"})); l(hello({goodbye: "good night"}));</code></pre>
riobardalmost 13 years ago
Can we stop calling these things “frameworks” if they are so lightweight?
评论 #4378855 未加载
vainalmost 13 years ago
<p><pre><code> function render(tpl,data){ var matches = tpl.match(/{[^\}]+}/g); for(var i in matches){ var rep = eval("data."+matches[i].replace('{','').replace('}','')); tpl = tpl.replace(matches[i],rep); } return tpl; } alert(render("{a} is all that i've {b.a} {b.b} {b.c}", {a:"this", b:{a:"ever",b:"really",c:"needed"} })) </code></pre> <a href="http://pastebin.com/txM6NZBS" rel="nofollow">http://pastebin.com/txM6NZBS</a> here, to copy and paste
评论 #4378764 未加载
评论 #4378754 未加载
评论 #4378710 未加载
nreecealmost 13 years ago
Also see Tweet-Templ (0.1 kB): <a href="http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/" rel="nofollow">http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-...</a><p>More micro-frameworks at <a href="http://microjs.com" rel="nofollow">http://microjs.com</a>
jfaucettalmost 13 years ago
looking at the replace chains on s(val) reminded me of something a while back, is there a faster/better way to do this king of stuff? something like:<p>return s(val).replace(re, function(t){<p><pre><code> if( t == '&#62;' ) return '&#38;gt'; if( t == '&#60;' ) return '&#38;lt;'; if( t == '&#38;' ) return '&#38;amp;'; if( t == '"' ) return '&#38;quot;'; return t;</code></pre> });
评论 #4378971 未加载
评论 #4378791 未加载
评论 #4379002 未加载
HugoDiasalmost 13 years ago
Awesome work. Starting to test it right now :)
tjtrappalmost 13 years ago
cool but what was wrong w mustache or handlebars?
评论 #4379656 未加载