Template Engine SupportIntroductionThe Spring Framework features integration classes for templating
engine support. Spring 1.3 provides support for the NVelocity
templating engine.DependenciesThe Spring NVelocity support depends on the Castle project's
NVelocity implementation which is located in the lib directory of the
Spring release.Configuring a VelocityEngineThe NVelocity template engine is set up using a
IFactoryObject with optional configuration parameters
to define where templates reside, define logging and more. For more
information on IFactoryObjects see . A custom namespace
parser is provided to simplify the configuration of a NVelocity template
engine. For more information on custom namespace parser see .Simple file based template engine definitionYou create a simple definition of the template engine that uses
the default resource loader as follows:<objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity">
<!-- Simple no arg file based configuration use's NVeclocity default file resource loader -->
<nv:engine id="velocityEngine" />
</objects>The velocity engine could then be used to load and merge a local
template using a simple relative path (the default resource loader path
is the current execution directory):StringWriter stringWriter = new StringWriter();
Hashtable modelTable = new Hashtable();
modelTable.Add("var1", TEST_VALUE);
VelocityContext velocityContext = new VelocityContext(modelTable);
velocityEngine.MergeTemplate("Template/Velocity/MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);
string mergedContent = stringWriter.ToString();To disable the use of NVelocity's file loader that tracks runtime
changes, set the element prefer-file-system-access of
<engine/> to false.Configuration OptionsYou can define several attributes on the <engine> element to
control how the factory is configured:
Engine Factory Configuration OptionsAttributeDescriptionRequiredDefault Valueconfig-fileA uri of a properties file defining the NVelocity
configuration. This value accepts all spring resource loader
uri (e.g., file://, http://). See noN/Aprefer-file-system-accessInstructs the NVelocity engine factory to attempt use
NVelocity's file loader. When set to false the provided
SpringResourceLoader will be used (and the
ResourceLoaderPath property must be
set)notrueoverride-loggingInstructs the NVelocity engine factory to use the
provided spring commons logging based logging system. See
notrue
Assembly based template loadingWhen templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:<nv:engine id="velocityEngine" >
<nv:resource-loader>
<nv:assembly name="MyAssembly" />
</nv:resource-loader>
</nv:nvelocity>Using the example above the template would be loaded using a
namespace syntax for the template resource:velocityEngine.MergeTemplate("MyAssembly.MyNamespace.MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);Using Spring's IResourceLoader to load
templatesIn some cases Spring's IResource
abstraction can be beneficial to load templates from a variety of
resources. A Spring IResource loader extension to the NVelocity resource
loader implementation is provided for this use case. The following
object definition loads the NVelocity templates from a single
path<nv:engine id="velocityEngine">
<nv:resource-loader>
<nv:spring uri="file://Template/Velocity/"/>
</nv:resource-loader>
</nv:engine>Or with multiple locations<nv:engine id="velocityEngine">
<nv:resource-loader>
<nv:spring uri="file://Template/Velocity/"/>
<nv:spring uri="assembly://MyAssembly/MyNameSpace"/>
</nv:resource-loader>
</nv:engine>
By default spring will attempt to load resources using
NVelocity's file based template loading (useful for detection of
template changes at runtime). If this is not desirable you set the
prefer-file-system-access property of the factory
object to false which will cause the factory to
utilize the supplied spring resource loader.Using the example above when resource loader paths are defined
templates can be loaded using their name:string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "MyFileTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from file://Template/Velocity/
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "MyAssemblyTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from assembly://MyAssembly/MyNameSpaceDefining a custom resource loaderThe following defines a custom resource loader (the type is an
extension of NVelocity's ResourceLoader
class):<nv:engine id="velocityEngine">
<nv:resource-loader>
<nv:custom name="myResourceLoader"
description="A custom resource loader"
type="MyNamespace.MyResourceLoader, MyAssembly"
path="Template/Velocity/"/>
</nv:resource-loader>
</nv:engine>
Resource Loader configuration optionsThe <nv:resource-loader> element has additional attributes
which define how NVelocity's resource manager and resource loader
behave.
Resource Loader Configuration OptionsAttributeDescriptionRequiredDefault Valuedefault-cache-sizedefines resource manager global cache size, applies when
caching is turned on. This maps to NVelocity's resource
manager resource.manager.defaultcache.size
propertyno89template-cachingEnables template caching for the defined resource
loader. This maps to NVelocity's resource loader
<name>.resource.loader.cache
propertynofalsemodification-check-intervalThe modification check interval value (seconds) of the
resource loader, applies only to resource loader with change
detection capabilities (file or custom). This maps to
NVelocity's resource loader
<name>.resource.loader.modificationCheckInterval
propertyno2
Using a custom configuration fileIf so desired one could provide a custom configuration resource to
customize the NVelocity configuration:<nv:engine id="velocityEngine" config-file="file://Template/Velocity/config.properties"/>You can override specific properties by providing the
VelocityProperties property to the NVelocity factory
object (shown above)<nv:engine id="velocityTemplate" >
<nv:nvelocity-properties>
<entry key="input.encoding" value="ISO-8859-1"/>
<entry key="output.encoding" value="ISO-8859-1"/>
</nv:nvelocity-properties>
</nv:engine>LoggingBy default Spring will override NVelocity's default
ILogSystem implementation with its own
CommonsLoggingLogSystem implementation so that the
logging stream of NVelocity will go to the same logging subsystem that
Spring uses. If this is not desirable, you can specify the following
property of the NVelocity factory object:<template:nvelocity id="velocityEngine" override-logging="false" />
Merging a templateSpring provides the VelocityEngineUtils utility
for merging templates using an engine instance:string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "MyTemplate.vm", Encoding.UTF8.WebName, model);Configuring a VelocityEngine without a custom namespaceWhile most users will prefer to use the NVelocity custom namespace
to configure a VelocityEngine, you can also use standard <object/>
definition syntax as shown below:To create a VelocityEngine using the default file resource loader
use the definition:<!-- Simple no arg file based configuration use's NVelocity default file resource loader -->
<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" />For convenience in defining NVelocity engine instances a custom
namespace is provided, for example the resource loader definition could be
done this way:
<objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity">
<nv:nvelocity id="velocityEngine" >
<nv:resource-loader>
<nv:file path="Template/Velocity/" />
</nv:resource-loader>
</nv:nvelocity>
</objectsWhen templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:<!-- Assembly based template loading with NVelocity assembly resource loader -->
<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity">
<property name="VelocityProperties">
<dictionary key-type="string" value-type="object">
<entry key="resource.loader" value="assembly"/>
<entry key="assembly.resource.loader.class" value="NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader"/>
<entry key="assembly.resource.loader.assembly" value="MyAssembly"/>
</dictionary>
</property>
</object>To load NVelocity templates from a single path use the
definition:<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
<property name="ResourceLoaderPath" value="file://MyTemplateFolder/AnotherFolder/" />
</object>
To load NVelocity templates from multiple paths use the
definition:<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
<property name="ResourceLoaderPaths" >
<list>
<value>file://MyTemplateFolder/</value>
<value>file://MyOtherTemplateFolder/</value>
</list>
</property>
</object>By default spring will attempt to load resources using NVelocity's
file based template loading (useful for detection of template changes at
runtime). If this is not desirable you set the
preferFileSystemAccess property of the factory object
to false which will cause the factory to utilize the
supplied spring resource loader.To refer to a property file based configuration of the
TemplateEngine use the definition:<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
<property name="ConfigLocation " value="file://Template/Velocity/config.properties" />
</object>You can override specific properties by providing the
VelocityProperties property.To not integrate with the Common.Logging subsystem, set the
OverrideLogging property to false:<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
<property name="OverrideLogging" value="false" />
</object>