Stencil

Advanced template engine for Java

View project onGitHub

Engine API

Stencil features an API that is simple to use but provides many powerful features if the need arises.

Rendering

Rendering a template from the filesystem is a fairly easy task.

	StencilEngine engine = new StencilEngine();
	
	String text = engine.render("myTemplate.st");
	
	System.out.println(text);	
	

Passing parameters to a template is also easy.

	StencilEngine engine = new StencilEngine();
	
	Map<String,Object> params = new HashMap<>();
	params.put("title", "My Page!");
	
	String text = engine.render("myTemplate.st", params);
	
	System.out.println(text);
	
NOTE: A template will ignore any parameters not declared in its header.

You may want to render the same template multiple times or lookup a template to render in advance. You can do that with the 'load' method.

	
	StencilEngine engine = new StencilEngine();
	
	Template myTemplate = engine.load("myTemplate.st");
	
	String text = engine.render(myTemplate);
	
	System.out.println(text);
	

Stencil also supports rendering directly to a character stream.

	StencilEngine engine = new StencilEngine();
	
	Template myTemplate = engine.load("myTemplate.st");
	StringWriter out = new StringWriter();
	
	engine.render(myTemplate, out);
	
	System.out.println(out.toString());
	

Loading

Stencil supports a pluggable template loading system. You can plugin any template loading system you'd like by implementing the interface

	public interface TemplateSourceLoader {
	  
	  TemplateSource find(String path) throws IOException;
	
	}
	
and return a TemplateSource object for the requested path. From there Stencil handles loading the template from source and caching it.

To use a custom loader you simply provide it in the engine constructor

	StencilEngine engine = new StencilEngine(myTemplateSourceLoader);
	

The default source loader can load source from any URI (including files). In the servlet project another source loader is available that can load from servlet resources.

Globals

Stencil supports global scopes that free you from having to pass all your variables and extensions into the template at rendering time. These global scopes can lookup variables in any imaginable way simply by name.

To implement your own global scope you implement the interface

	public interface GlobalScope {
	  
		Object get(String name);
	
	}
	

To use one or more global scopes you set them against the engine after it has been constructed.

	StencilEngine engine = new StencilEngine();
	
	engine.setGlobalScopes(Arrays.asList(myGlobalScope));
	

To make global location even easier. Stencil uses the Java Service Provider Interface to locate GlobalScope implementations.

CDI Globals

As an extension, and provided in a separate library, Stencil Supports CDI named Beans as globals.

This means when you have the Stencil CDI library included you only need to name your beans for them to be available in templates.

Stencil CDI integration uses the GlobalScope service provider interface. This means to enable it you only need to include Stencil's engine-cdi library in your class path.

Caching

Stencil has primetime support for caching. By default it caches the loaded templates until it detects that it has been modified.

Complete Check

To determine if a template has been modified the engine asks the source loader. The default loader uses a combination of modification dates and MD5 hashes to determine when a template has change.

The engine also has one feature that really helps during development. When checking if a template has been modified it also checks all includes and imports as well. This feature can save a lot of time hunting down why a modified template didn't update.

Since the complete modification check can be time consuming it can be turned enabled/disabled at anytime using this method

	StencilEngine.setCompleteModificationCheck(boolean enabled);
	

Custom Caching

When Stencil's default caching scheme doesn't suit your needs you can alter the caching behavior with a custom caching scheme.

To implement your own caching scheme you implement the interface

	public interface TemplateCache {
	  
	  CachedTemplate get(URI uri);
	  CachedTemplate update(URI uri, CachedTemplate cachedTemplate);
	  void remove(URI uri);
	
	}
	

To use your custom caching scheme you provide it in the engine constructor.

	StencilEngine engine = new StencilEngine(myTemplateLoader, myTemplateCache);