function reference.

Functions are helpers that can be placed in:

  • evaluations
  • set commands
  • loop commands
  • if commands

And each of the functions can be arbitrarily nested

The list of available commands are as follows - which can be output by {dumpfunctions}

FunctionLessThanEqual fn:<=[ <#numArgs: 2> ] aliased as (lte)
FunctionNotEqual fn:<>[ <#numArgs: 2> ] aliased as (notEqual, ne, not=)
FunctionInstanceOf fn:instanceOf[ <#numArgs: 2> ]
FunctionAnd fn:and[ <#numArgs: 2> ]
FunctionIndexOf fn:indexOf[ <#numArgs: 2> ]
FunctionPower fn:^[ <#numArgs: 2> ]
FunctionOr fn:or[ <#numArgs: 2> ]
FunctionIsNotNull fn:notNull[ <#numArgs: 1> ] aliased as (isNotNull, !null, isnotnull, notnull, !Null)
FunctionFormatDate fn:fmtDate[ <#numArgs: 1 or 2> ]
FunctionModulus fn:%[ <#numArgs: 2> ]
FunctionAnd fn:&[ <#numArgs: 2> ]
FunctionLength fn:length[ <#numArgs: 1> ] aliased as (size)
FunctionFalse fn:false[ <#numArgs: 1> ]
FunctionMultiply fn:*[ <#numArgs: 2> ]
FunctionAdd fn:+[ <#numArgs: 2> ]
FunctionSubtract fn:-[ <#numArgs: 2> ]
FunctionOdd fn:odd[ <#numArgs: 1> ]
FunctionDivide fn:/[ <#numArgs: 2> ]
FunctionToJson fn:toJson[ <#numArgs: 1> ]
FunctionIsNull fn:null[ <#numArgs: 1> ] aliased as (isnull, isNull)
FunctionEven fn:even[ <#numArgs: 1> ]
FunctionTrue fn:true[ <#numArgs: 1> ]
FunctionLessThan fn:<[ <#numArgs: 2> ] aliased as (lt)
FunctionOr fn:|[ <#numArgs: 2> ]
FunctionEqual fn:=[ <#numArgs: 2> ] aliased as (eq, equal)
FunctionGreaterThan fn:>[ <#numArgs: 2> ] aliased as (gt)
FunctionGreaterThanEqual fn:>=[ <#numArgs: 2> ] aliased as (gt=)

Creating your own function

The functions should be fairly explanatory from the above list. However you may wish to add your own function, the example shown here is taken from h2zero FunctionRequiresImport.java.(with a lot more comments than are in the source)

package synapticloop.h2zero.templar.function;

import synapticloop.h2zero.model.BaseSchemaObject;
import synapticloop.templar.exception.FunctionException;
import synapticloop.templar.function.Function;
import synapticloop.templar.utils.ObjectUtils;
import synapticloop.templar.utils.TemplarContext;

public class FunctionRequiresImport extends Function {
	public static final String FUNCTION_NAME = "requiresImport";

	public FunctionRequiresImport() {
		// here we register the fixed number of arguments that are required
		super(2);
	}

	@Override
	public Object evaluate(Object[] args, TemplarContext templarContext) throws FunctionException {
		if(verifyArgumentLength(args)) {
			// do we have the correct number of arguments passed through?
			Object tableObject = null;
			if(args[0] instanceof BaseSchemaObject) {
				tableObject = args[0];
			} else {
				// the evaluateObjectToDefault should be the call that is used, this will de-quote any strings
				// and return them, or else it will look up the expression in the templarContext
				tableObject = ObjectUtils.evaluateObjectToDefault(args[0].toString(), templarContext);
			}

			Object fieldTypeObject = ObjectUtils.evaluateObjectToDefault(args[1], templarContext);

			if(tableObject instanceof BaseSchemaObject && fieldTypeObject instanceof String) {
				BaseSchemaObject baseSchemaObject = (BaseSchemaObject)tableObject;
				String fieldType = (String)fieldTypeObject;

				// here we are returning a boolean object for use in an {if fn:requiresImport[__class__, __import_package_name__]}
				// which if true, will then output everything up until the {else} or {endif} tokens

				return(baseSchemaObject.requiresImport(fieldType));
			} else {
				throw new FunctionException("The function '" + FUNCTION_NAME + "' takes exactly two arguments, which must be of type ['" + BaseSchemaObject.class.getCanonicalName() + "', '" + String.class.getCanonicalName() + "'], found arguments of ['" + tableObject.getClass().getCanonicalName() + "', '" + fieldTypeObject.getClass().getCanonicalName() + "']." );
			}
		} else {
			// at this point - we did not have the correct number of arguments
			throw new FunctionException("The function '" + FUNCTION_NAME + "' takes exactly 2 arguments.");
		}
	}

}

Once you have written your own function, you then need to add it to the templarContext for it to be callable

TemplarConfiguration templarConfiguration = new TemplarConfiguration();
templarConfiguration.setExplicitNewLines(true);
templarConfiguration.setExplicitTabs(true);

TemplarContext templarContext = new TemplarContext(templarConfiguration);

if(!templarContext.hasFunction("requiresImport")) {
	templarContext.addFunction("requiresImport", new FunctionRequiresImport());
}

Note that this will throw a FunctionExeption if the function name already exists.