tss
v0.0.24
Published
a minimal template engine
Downloads
19
Readme
tss
tss is a minimal templage engine, unlike all other template system tss not use any pseudo langage into the template,
instead, to really separate design from code it is fully callback based
only one char define template keywords : §, nothing else need to be know
install tss
npm install tss
import tss
var tss = require("tss").tss;
how to & example
syntax is easy :
var filledTemplate = tss(template, data, callback);
callback use is optionnal, if there is not any, tss will just replace keywords with their associed data or with empty string ''
minimal example, not any use of callback
tss("hello §name§",{
name : "world"
});
will return "hello world"
if data is an array, tss will loop itself on each value :
"<ul>" + tss("<li>§name§</li>",[
{ name : "john" },
{ name : "mike" },
{ name : "kate" }
]) + "</ul>";
will result in :
<ul>
<li>john</li>
<li>mike</li>
<li>kate</li>
</ul>
callback can be an object with some function, or a "generic" single function, "this" in callback will always refer to the data object
callback object example :
tss("§greetings§ §name§",{
name : "world",
greetings : "hello"
},{
name : function(name){
return name.toUpperCase();
// or this.name.toUpperCase();
}
});
will return "hello WORLD"
single generic callback function example :
tss("hello §name§",{
name : "world"
},function(keyword){
switch(keyword){
case 'name' : return this.name.toUpperCase(); break;
} return '';
});
keywords can be "virtual", not any dedicated data, but generated by callback
tss("hello §name§",{
userName : "world"
},{
name : function(){
return this.userName.toUpperCase();
}
});
that work with the two syntax :
tss("hello §name§",{
userName : "world"
},function(keyword){
switch(keyword){
case 'name' : return this.userName.toUpperCase(); break;
} return '';
});
extract all handler and templates into dedicated data object for maximum reuse and abstraction :
var template = {
user : {
registered : 'hello user §id§ <b>§name§</b> <a href="/logout">logout</a>',
unregistered : 'Hello unregistered user, <a href="/auth/google">login</a>',
userpage : '<h1>user §id§</h1><section><h2>§name§</h2><p>§email§</p></section>'
}
}
var handler = {
user : {
name:function(){
switch(this.account){
case 'google':
return this.profile.displayName;
break;
}; return 'anon';
},
mail:function(){
switch(this.account){
case 'google':
return this.profile.emails[0].value;
break;
}; return 'not any mail';
}
}
};
var html = tss(template.user.userpage,user,{
name:handler.user.name,
email:handler.user.mail
});
or directly :
var html = tss(template.user.userpage,user,handler.user);
async
default tss use is sync, but it can be used in an async way, for that purpose it will require async and async-replace npm packages
async tss can be used simply with :
tss.async(template, data, callback, done);
all data callback will get an extra parameter who is the job end callback
tss.async("hello §name§",{
name : "world"
},{
name : function(name,done){
setTimeout(function(){
done(null,'<i>'+name+'</i>');
},1000);
}
},function(err,data){
console.log( "filled data : ", data);
});
for virtual keywords :
tss.async("hello §name§",{
myname : "world"
},{
name : function(done){
var t = this;
setTimeout(function(){
done(null,'<i>'+t.myname+'</i>');
},1000);
}
},function(err,data){
console.log( "filled data : ", data);
});
the use of this job end callback is optionnal, if your data callback return anything the job callback will not be used, you can mix async && sync data callback :
tss.async("hello <i>§name§</i>, glad to see you back §time§",{
login : "kate",
gender : "Miss"
},{
name : function(){
return this.gender + " " + this.login;
},
time : function(done){
db.get("users:last-ping:"+this.login,function(err,time){
time = (new Date()) - time; // from now
time /= 1000*3600*24; // in day
if(time > 90) return done(null, "from death");
var timeString = (time > 7)?"after so long time !":"so fast.";
done(null, timeString );
});
}
},function(err,data){
res.send( data );
});
and if there is not any callback for a keyword, this one will just be done in a sync way :
function toUpperCase(s){ return s.toUpperCase(); }
var smiles = { cool:":)", great:":D" };
tss.async("§greetings§ §name§ this is a §what§ ! §smile§",{
myname : "world",
what : "test",
greetings : "hello",
feeling : "great"
},{
name:function(done){
var t = this;
setTimeout(function(){
done(null,'<i>'+t.myname+'</i>');
},1000);
},
smile:function(){
return smiles[this.feeling];
},
greetings:toUpperCase
},function(err,data){
console.log(data);
});
that will log after a second :
HELLO <i>world</i> this is a test ! :D
finally, array data could be async too, and will be processed in parallel
tss.async("§a§",[
{ a:1 },
{ a:2 },
{ a:3 }
],function(keyword,done){
var t = this;
var time = t.a * 1000;
setTimeout(function(){
done(null,"\n#"+t.a+" took "+time+"ms to complete");
},time);
},function(err,data){
console.log(data);
});
who will log 3 second after :
#1 took 1000ms to complete
#2 took 2000ms to complete
#3 took 3000ms to complete
and with a keyword more :
tss.async("§a§ §hello§",[
{ a:1 },
{ a:2 },
{ a:3 }
],function(keyword,done){
var t = this;
var time = t.a * 1000;
setTimeout(function(){
done(null,"\n #"+t.a+" ("+keyword+") took "+time+"ms to complete");
},time);
},function(err,data){
console.log(data);
});
still output 3 second after :
#1 (a) took 1000ms to complete
#1 (hello) took 1000ms to complete
#2 (a) took 2000ms to complete
#2 (hello) took 2000ms to complete
#3 (a) took 3000ms to complete
#3 (hello) took 3000ms to complete