doT.js iterations by objects with conditions

Addition of new iterator header for doT.js templater. https://github.com/spmbt/doT

by spmbt

JavaScript

// doT.js
// 2011, Laura Doktorova, https://github.com/olado/doT
// 2013, modified by spmbt0 (iterHash iterator in objects with conditions)
// Licensed under the MIT license.

(function(){
	var doT = {
		version: '1.1.0',
		templateSettings: {
			evaluate:    /\{\{([\s\S]+?(\}?)+)\}\}/g, //{{.+}}
			interpolate: /\{\{=([\s\S]+?)\}\}/g, //{{=.+}}
			encode:      /\{\{!([\s\S]+?)\}\}/g, //{{!.+}}
			use:         /\{\{#([\s\S]+?)\}\}/g, //{{#.+}}
			useParams:   /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
			define:      /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
			defineParams:/^\s*([\w$]+):([\s\S]+)/, // .:.
			conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g, //{{? .* }}
			iterate:     /\{\{~\s*(?:\}\}|(.+?)\s*(?:\:\s*([\w$]*)\s*(?:\:\s*([\w$]*))?\s*)?\}\})/g, //{{~.*:.*:.*}}
            iterHash:    /\{\{@\s*(?:\}\}|(\{[\s\S]+?\}|.+?)\s*(?:\:\s*([\w$]*)\s*(?:\:\s*([\w$]*))?\s*\:?((?:[^}]|\}(?!\}))*)\s*)?\}\})/g, //{{@.*:.*:.*:.*}}
			varname:	'it',
			strip:		true,
			append:		true,
			selfcontained: false
		},
		template: undefined, //fn, compile template
		compile:  undefined  //fn, for express
	}, global;

	if(typeof module !=='undefined' && module.exports)
		module.exports = doT;
	else if(typeof define ==='function' && define.amd)
		define(function(){return doT;});
	else{
		global = (function(){ return this || (0,eval)('this'); })(); //TODO eval
		global.doT = doT;
	}
	function encodeHTMLSource(){
		var encodeHTMLRules = { "&": "&#38;", "<": "&#60;", ">": "&#62;", '"': '&#34;', "'": '&#39;', "/": '&#47;' },
			matchHTML = /&(?!#?\w+;)|<|>|"|'|\//g;
		return function(){
			return this ? this.replace(matchHTML, function(m){return encodeHTMLRules[m] || m;}) : this;
		};
	}
	String.prototype.encodeHTML = encodeHTMLSource();

	var startend = {
		append: { start: "'+(",      end: ")+'",      endencode: "||'').toString().encodeHTML()+'" },
		split:  { start: "';out+=(", end: ");out+='", endencode:...