Stencil

Advanced template engine for Java

View project onGitHub

Functions

Stencil has it's own built in expression language designed for template processing. To augment the built in functions and the methods of objects passed into Stencil you can define your own utility functions right inside a template.

At first glance functions look exactly like macros but there is an important distinction. Functions are code that process statement and can return values. Macros are blocks of text that are processed as templates themselves. If a function doesn't return a value, calling it from an output will not output anything.

Basic

Defining a function in Stencil is done with this simple syntax

	$func myFunc () {
		return 'My Function!';
	};
	
	$myFunc ();
	
	My Function!
	

Parameters

Parameters are specified in familiar parentheses format. Remember, Stencil is an untyped language so no types are specified, just names.

	$macro myFunc ( greeting, name ) {
		return greeting + ' ' name + '!';
	};
	
	$myFunc('Hello','World');
	
	Hello World!
	

Parameters can be passed by location (as in the previous example) or by name. You must choose one passing method or the other. You cannot mix methods.

	$macro myFunc ( greeting, name ) {
		return greeting + ' ' + name + '!';
	};
	
$myFunc(greeting='Hello',name='World');
	
	Hello World!
	

Default Values

Parameters can also have default values. You simply specify an expression after the parameter name. Any parameters not passed will receive their default value or null if no default was defined.

	$macro myMacro ( greeting='Hello', name ) {
		return greeting + ' ' + name + '!';
	};
	
	$myMacro(name='World');
	
	Hello World!
	

Any Parameters

Occasionally you would like to accept any number of parameters and process them all in your macro. This is done by marking a parameter with the '*' sign. Then you can enumerate the parameter keys/values at will.

	$macro myFunc (*all) {
		var text = '';
		foreach entry in all {
			text += entry.key + ' = ' + entry.value + '\n';
		}
	};
	
$myFunc(one='blue',two='red',three='green');
	
	one = blue;
	two = red;
	three = green;
	






Statements

Functions process statements. As such they can do pretty much any imaginable thing you would like. All the available statements are described below along with an example of the associated syntax.

Return

Exits the function immediately, returning a value to its caller

	return 10;
	

Declaration

Declares a variable in the current function scope;

	var text = '';
	

Assignment

Assigns a value to a variable. The variable must have been previously declared.

	text = 'New Value';
	

If/Else

Choose to execute one of two statements

	if value {
		text = "this";
	}
	else {
		text = "that";
	}
	

The else statement is optional

	if value {
		text = "this";
	}
	

Foreach/Else

Execute a statement once for each member of a collection

	foreach item in items {
		x += item;
	}
	

An optional else statement can be provided for when the collection is empty

	foreach item in items {
		x += item;
	}
	else {
		x = 'None';
	}
	

An optional iteration variable can be declared that provides commonly used information about the current iteration.
The iteration variable provides the following properties:

  • index - iteration # starting from 0
  • count - iteration # starting from 1
  • even - true if it is an even numbered iteration
  • odd - true if it is an odd numbered iteration
  • hasNext - true if this is not the last iteration
	foreach item,it in items {
		x += item.name + ' ' + it.count;
	}
	

While

Execute a statement while a value is true

	while value < 5 {
		value += 1;
	}
	

Switch/Case/Default

Select one of several blocks based on a value

	switch value {
		case 0:
			x=5;
		case 1:
			x=10;
		default:
			x=0;
	}
	

With

Add properties of one or more expressions to the current scope

	with stock,group {
		x += group;	$* for group.title	*$
		x += name;	$* for stock.name 	*$
		x += price;	$* for stock.price 	*$
	}
	

break

Breaks out of the nearest loop

	while x < 10 {
		if x == 3
			break;
		x += 1;
	}
	

continue

Continues on to the next iteration of the nearest loop

	while x < 10 {
		x += 1;
		if x == 3
			continue;
		x += 3;		$* this gets skipped *$
	}