npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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