Tim: A tiny, secure JavaScript micro-templating script.

Modified slightly for Servoy. Source: https://github.com/premasagar/tim

“Don’t you just hate having to write HTML with a mess of string concatenation that clutters up your JavaScript?:”

var myHTML = "<ul class='" + myClass + "'>" +
    "<li id='" + theId + "'>" + liContents + "</li>" +
    // etc, etc, etc

Tim lets you write simple templates that uses JavaScript’s familiar dot notation. You pass in a JavaScript object that contains all the relevant strings, and they are then substituted into the template:"

tim("Hello {{place}}", {place: "world"});
// "Hello world"

Servoy version. Rename the method (optional) and paste it somewhere in your solution:

/**
 * Tim (lite): A tiny, secure JavaScript micro-templating script.
 *   github.com/premasagar/tim
 *   
 * @param {String} template
 * @param {Object} data
 * 
 * @example 
 * 		CMS.markup.merge("Hello {{place}}", {place: "world"})
 * 			> Hello world
 * 		CMS.markup.merge("Hello {{place}}. My name is {{person.name}}.", { place: "Brighton", person: { name: "Prem" } })
 *			> Hello Brighton. My name is Prem.
 *
 * @properties={typeid:24,uuid:"E93C4B64-5AC4-4A50-A6EF-8506C5D07371"}
 */
function merge(template, data){

    var start   = "{{",
        end     = "}}",
        path    = "[a-z0-9_][\\.a-z0-9_]*", // e.g. config.person.name
        pattern = new RegExp(start + "\\s*("+ path +")\\s*" + end, "gi"),
        undef; 

        // Merge data into the template string
        return template.replace(pattern, function(tag, token){
            path = 	token.split(".")
            var  	len = path.length,
                	lookup = data,
                	i = 0;

            for (; i < len; i++){
                lookup = lookup[path[i]];
                
                // Property not found
                if (lookup === undef){
                    throw "tim: '" + path[i] + "' not found in " + tag;
                }
                
                // Return the required value
                if (i === len - 1){
                    return lookup;
                }
            }
        });
}

Cool!! This will save me hours and hours, tnx David!

ngervasi:
Cool!! This will save me hours and hours, tnx David!

For real? Have you looked at Velocity for this kind of merging? This has been around for a couple of years:

var merged = plugins.VelocityReport.evaluateWithContext(whateverComplexTemplateYouWantAsAString, whateverComplexObjectYouWant);

Ouch! How could I have missed this one!?!? Probably because the sample code doesn’t show an actual call to it.
Tnx Patrick!

I’ve been using this:

/**
 *  Similar to utils.stringReplaceTags, but supports only form variables, or Record Object,  generic objects with named properties
 * 
 * @properties={typeid:24,uuid:"BFECB7EA-B144-4C5C-BDCD-85439C51DEBA"}
 */
function string_tag_replace(text, form) {
	if(!text || !form)
		return

	//use regex with function handler to convert %%formVar%% to form[formVar] so we render value
	var result =  text.replace(/%%[\w-]+%%/g, function(match){
		var formVar = match.replace(/%/g, "")
		return form[formVar]
	})
	
	//make recursive
	if(result.indexOf("%%") != -1) //if there are still tags in the result, run it again
		return string_tag_replace(result, form)
	else	
		return result
}

Then you can do things like this:

//works with form vars, dataproviders, relations, etc.
var result = globals.string_tag_replace(stringWithTags, this)

Unless you don’t actually use Velocity (in which case you really are missing something in your Servoy stack) and this is a contest on who’s got the best regular expression, I don’t see the point of crafting these kinds of functions that will always be much less powerful than the Velocity templating language (that was made and optimized for this very purpose and is in production use in thousands of applications) and the wrappers included in the Velocity plugin (that were made to make Velocity Servoy aware and leverage that power)…

ptalbot:
Unless you don’t actually use Velocity (in which case you really are missing something in your Servoy stack) and this is a contest on who’s got the best regular expression, I don’t see the point of crafting these kinds of functions that will always be much less powerful than the Velocity templating language (that was made and optimized for this very purpose and is in production use in thousands of applications) and the wrappers included in the Velocity plugin (that were made to make Velocity Servoy aware and leverage that power)…

I learned something from Scott’s post (the Servoy-specific angle is cool) and we use Velocity (thought everyone knew about Velocity’s capabilities). Different variations may have their uses…even if for learning purposes.

But we actually use this over velocity in some instances just for its brevity. Like for…“micro-templating” tasks…