plugins/looptag/looptag.js
function(Template,expression,sort){
	var name,set,index;
	
	this.rawString = Noodles.Utilities.grabToEndSliceRaw(Template, expression,Template.language.tag('Loop'));
	this.needs = {};
	expression = expression.split(/\s+/g);
	if(expression.length < 2){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop tag has bad syntax');
		return;
	}
	this.object = Noodles.Utilities.parseType(Template,expression[1]);
	if(!(this.object instanceof Noodles.Object)){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop must have an object to loop over');
		delete this.object;
		return;
	}
	this.needs = Noodles.Utilities.mergeObjectWith(this.needs,this.object.needs);

	this.template = Noodles.Utilities.createSubTemplate(Template,this.rawString, this);
	if(this.template.needsCallback){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop cannot contain any tags that will take a long time to run');
		delete this.template;
		return;
	}
	Template._leftCount++;//the end tag we sliced above
	this.sets = {};
	this.modifies = {};
	name = Template.language.other('name')
	this.name = new Noodles.Object(this.template,name);
	this.sets[name];
	this.modifies[name];
	value = Template.language.other('value');
	this.value = new Noodles.Object(this.template,value);
	index = '__' + Template.language.other('index')
	this.index = new Noodles.Object(this.template,index);
	this.sets[index];
	this.modifies[index];
	this.setExists = false;
	//<{loop foo as bar}>
	this.sort = !!sort;
	if(expression.length > 3 && (!this.sort || expression[2].toLowerCase() === Template.language.other('as'))){
		this.setObject = new Noodles.Object(this.template,expression[3]);
		if(this.setObject.order.length > 1){
			Noodles.Utilities.warning(Template,'Loop cannot set an object with multiple levels');
			this.skip = true;
			delete this.setObjet;
			return;
		}
		this.setExists = true;
	}
	
	if(this.sort){
		//<{sortloop foo as bar on baz}>
		if(expression.length > 5){
			this.sortKey = expression[5];
		}
		//<{sortloop foo on bar}>
		else if(expression.length > 3 && expression[2].toLowerCase() === Template.language.other('on')){
			this.sortKey = expression[3];
		}
		else{
			this.sortKey = Template.language.other('value');
		}
		//<{sortloop foo as bar on baz descending}>
		if(expression.length > 6){
			this.descending = expression[6].toLowerCase() === Template.language.other("descending");
		}
		//<{sortloop foo on bar descending}> or <{sortloop foo as bar descending}>
		else if(expression.length > 4 && expression[4].toLowerCase() === Template.language.other("descending")){
			this.descending = true;
		}
		//<{sortloop foo descending}>
		else if(expression.length > 2 && expression[2].toLowerCase() === Template.language.other("descending")){
			this.descending = true;
		}
		else{
			this.descending = false;
		}
	}
}
function(Template,expression,sort){
	var name,set,index;
	
	this.rawString = Noodles.Utilities.grabToEndSliceRaw(Template, expression,Template.language.tag('Loop'));
	this.needs = {};
	expression = expression.split(/\s+/g);
	if(expression.length < 2){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop tag has bad syntax');
		return;
	}
	this.object = Noodles.Utilities.parseType(Template,expression[1]);
	if(!(this.object instanceof Noodles.Object)){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop must have an object to loop over');
		delete this.object;
		return;
	}
	this.needs = Noodles.Utilities.mergeObjectWith(this.needs,this.object.needs);

	this.template = Noodles.Utilities.createSubTemplate(Template,this.rawString, this);
	if(this.template.needsCallback){
		this.skip = true;
		Noodles.Utilities.warning(Template,'Loop cannot contain any tags that will take a long time to run');
		delete this.template;
		return;
	}
	Template._leftCount++;//the end tag we sliced above
	this.sets = {};
	this.modifies = {};
	name = Template.language.other('name')
	this.name = new Noodles.Object(this.template,name);
	this.sets[name];
	this.modifies[name];
	value = Template.language.other('value');
	this.value = new Noodles.Object(this.template,value);
	index = '__' + Template.language.other('index')
	this.index = new Noodles.Object(this.template,index);
	this.sets[index];
	this.modifies[index];
	this.setExists = false;
	//<{loop foo as bar}>
	this.sort = !!sort;
	if(expression.length > 3 && (!this.sort || expression[2].toLowerCase() === Template.language.other('as'))){
		this.setObject = new Noodles.Object(this.template,expression[3]);
		if(this.setObject.order.length > 1){
			Noodles.Utilities.warning(Template,'Loop cannot set an object with multiple levels');
			this.skip = true;
			delete this.setObjet;
			return;
		}
		this.setExists = true;
	}
	
	if(this.sort){
		//<{sortloop foo as bar on baz}>
		if(expression.length > 5){
			this.sortKey = expression[5];
		}
		//<{sortloop foo on bar}>
		else if(expression.length > 3 && expression[2].toLowerCase() === Template.language.other('on')){
			this.sortKey = expression[3];
		}
		else{
			this.sortKey = Template.language.other('value');
		}
		//<{sortloop foo as bar on baz descending}>
		if(expression.length > 6){
			this.descending = expression[6].toLowerCase() === Template.language.other("descending");
		}
		//<{sortloop foo on bar descending}> or <{sortloop foo as bar descending}>
		else if(expression.length > 4 && expression[4].toLowerCase() === Template.language.other("descending")){
			this.descending = true;
		}
		//<{sortloop foo descending}>
		else if(expression.length > 2 && expression[2].toLowerCase() === Template.language.other("descending")){
			this.descending = true;
		}
		else{
			this.descending = false;
		}
	}
}
function ( Template , expression , sort ) { var name , set , index ; this . rawString = Noodles . Utilities . grabToEndSliceRaw ( Template , expression , Template . language . tag ( 'Loop' ) ) ; this . needs = { } ; expression = expression . split ( / \s+ / g ) ; if ( expression . length < 2 ) { this . skip = true ; Noodles . Utilities . warning ( Template , 'Loop tag has bad syntax' ) ; return ; } this . object = Noodles . Utilities . parseType ( Template , expression [ 1 ] ) ; if ( ! ( this . object instanceof Noodles . Object ) ) { this . skip = true ; Noodles . Utilities . warning ( Template , 'Loop must have an object to loop over' ) ; delete this . object ; return ; } this . needs = Noodles . Utilities . mergeObjectWith ( this . needs , this . object . needs ) ; this . template = Noodles . Utilities . createSubTemplate ( Template , this . rawString , this ) ; if ( this . template . needsCallback ) { this . skip = true ; Noodles . Utilities . warning ( Template , 'Loop cannot contain any tags that will take a long time to run' ) ; delete this . template ; return ; } Template . _leftCount ++ ; //the end tag we sliced above this . sets = { } ; this . modifies = { } ; name = Template . language . other ( 'name' ) this . name = new Noodles . Object ( this . template , name ) ; this . sets [ name ] ; this . modifies [ name ] ; value = Template . language . other ( 'value' ) ; this . value = new Noodles . Object ( this . template , value ) ; index = '__' + Template . language . other ( 'index' ) this . index = new Noodles . Object ( this . template , index ) ; this . sets [ index ] ; this . modifies [ index ] ; this . setExists = false ; //<{loop foo as bar}> this . sort = ! ! sort ; if ( expression . length > 3 && ( ! this . sort || expression [ 2 ] . toLowerCase ( ) === Template . language . other ( 'as' ) ) ) { this . setObject = new Noodles . Object ( this . template , expression [ 3 ] ) ; if ( this . setObject . order . length > 1 ) { Noodles . Utilities . warning ( Template , 'Loop cannot set an object with multiple levels' ) ; this . skip = true ; delete this . setObjet ; return ; } this . setExists = true ; } if ( this . sort ) { //<{sortloop foo as bar on baz}> if ( expression . length > 5 ) { this . sortKey = expression [ 5 ] ; } //<{sortloop foo on bar}> else if ( expression . length > 3 && expression [ 2 ] . toLowerCase ( ) === Template . language . other ( 'on' ) ) { this . sortKey = expression [ 3 ] ; } else { this . sortKey = Template . language . other ( 'value' ) ; } //<{sortloop foo as bar on baz descending}> if ( expression . length > 6 ) { this . descending = expression [ 6 ] . toLowerCase ( ) === Template . language . other ( "descending" ) ; } //<{sortloop foo on bar descending}> or <{sortloop foo as bar descending}> else if ( expression . length > 4 && expression [ 4 ] . toLowerCase ( ) === Template . language . other ( "descending" ) ) { this . descending = true ; } //<{sortloop foo descending}> else if ( expression . length > 2 && expression [ 2 ] . toLowerCase ( ) === Template . language . other ( "descending" ) ) { this . descending = true ; } else { this . descending = false ; } } }
/*--module--
name: Loop
description: Loop object
@param {Noodles.Template}
@param {expression}
@param {bool}
/ * -- module -- name : Loop description : Loop object