Files
spring-net/doc/reference/src/templating.xml
2009-08-01 17:20:44 +00:00

465 lines
18 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!--
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<chapter version="5" xml:id="templating" xmlns="http://docbook.org/ns/docbook"
xmlns:ns5="http://www.w3.org/1999/xhtml"
xmlns:ns42="http://www.w3.org/2000/svg"
xmlns:ns4="http://www.w3.org/1999/xlink"
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
xmlns:ns="http://docbook.org/ns/docbook">
<title>Template Engine Support</title>
<section xml:id="templating-introduction">
<title>Introduction</title>
<para>The Spring Framework features integration classes for templating
engine support. Spring 1.3 provides support for the <ulink
url="http://www.castleproject.org/others/nvelocity/index.html">NVelocity</ulink>
templating engine.</para>
</section>
<section xml:id="templating-nvelocity-dependencies">
<title>Dependencies</title>
<para>The Spring NVelocity support depends on the Castle project's
NVelocity implementation which is located in the lib directory of the
Spring release.</para>
</section>
<section xml:id="templating-nvelocity-factory">
<title>Configuring a VelocityEngine</title>
<para>The NVelocity template engine is set up using a
<literal>IFactoryObject</literal> with optional configuration parameters
to define where templates reside, define logging and more. For more
information on <literal>IFactoryObjects</literal> see <xref
linkend="objects-factory-lifecycle-factoryobject" />. A custom namespace
parser is provided to simplify the configuration of a NVelocity template
engine. For more information on custom namespace parser see <xref
linkend="context-custom-parsers" />.</para>
<section xml:id="templating-nvelocity-file">
<title>Simple file based template engine definition</title>
<para>You create a simple definition of the template engine that uses
the default resource loader as follows:</para>
<programlisting language="myxml">&lt;objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity"&gt;
&lt;!-- Simple no arg file based configuration use's NVeclocity default file resource loader --&gt;
&lt;nv:engine id="velocityEngine" /&gt;
&lt;/objects&gt;</programlisting>
<para>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):</para>
<programlisting language="csharp">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();</programlisting>
<para>To disable the use of NVelocity's file loader that tracks runtime
changes, set the element <literal>prefer-file-system-access</literal> of
&lt;engine/&gt; to false.</para>
</section>
<section xml:id="templating-nvelocity-engine-configuration">
<title>Configuration Options</title>
<para>You can define several attributes on the &lt;engine&gt; element to
control how the factory is configured:</para>
<table id="template-velocity-engine-config-tbl">
<title>Engine Factory Configuration Options</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="2*" />
<colspec colname="c2" colwidth="4*" />
<colspec colname="c3" colwidth="1*" />
<colspec colname="c4" colwidth="1*" />
<thead>
<row>
<entry>Attribute</entry>
<entry>Description</entry>
<entry>Required</entry>
<entry>Default Value</entry>
</row>
</thead>
<tbody>
<row>
<entry>config-file</entry>
<entry>
<para>A uri of a properties file defining the NVelocity
configuration. This value accepts all spring resource loader
uri (e.g., file://, http://). See <xref
linkend="templating-nvelocity-resource-config" /></para>
</entry>
<entry>no</entry>
<entry>N/A</entry>
</row>
<row>
<entry>prefer-file-system-access</entry>
<entry>
<para>Instructs the NVelocity engine factory to attempt use
NVelocity's file loader. When set to false the provided
<literal>SpringResourceLoader</literal> will be used (and the
<literal>ResourceLoaderPath</literal> property must be
set)</para>
</entry>
<entry>no</entry>
<entry>true</entry>
</row>
<row>
<entry>override-logging</entry>
<entry>
<para>Instructs the NVelocity engine factory to use the
provided spring commons logging based logging system. See
<xref
linkend="templating-nvelocity-resource-logging" /></para>
</entry>
<entry>no</entry>
<entry>true</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section xml:id="templating-nvelocity-assembly">
<title>Assembly based template loading</title>
<para>When templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:</para>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine" &gt;
&lt;nv:resource-loader&gt;
&lt;nv:assembly name="MyAssembly" /&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:nvelocity&gt;</programlisting>
<para>Using the example above the template would be loaded using a
namespace syntax for the template resource:</para>
<programlisting language="csharp">velocityEngine.MergeTemplate("MyAssembly.MyNamespace.MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);</programlisting>
</section>
<section xml:id="templating-nvelocity-spring-resource-loader">
<title>Using Spring's <literal>IResourceLoader</literal> to load
templates</title>
<para>In some cases Spring's <link linkend="resources">IResource</link>
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</para>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine"&gt;
&lt;nv:resource-loader&gt;
&lt;nv:spring uri="file://Template/Velocity/"/&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:engine&gt;</programlisting>
<para>Or with multiple locations</para>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine"&gt;
&lt;nv:resource-loader&gt;
&lt;nv:spring uri="file://Template/Velocity/"/&gt;
&lt;nv:spring uri="assembly://MyAssembly/MyNameSpace"/&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:engine&gt;
</programlisting>
<note>
<para>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
<literal>prefer-file-system-access</literal> property of the factory
object to <literal>false</literal> which will cause the factory to
utilize the supplied spring resource loader.</para>
</note>
<para>Using the example above when resource loader paths are defined
templates can be loaded using their name:</para>
<programlisting language="csharp">string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyFileTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from file://Template/Velocity/
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyAseemblyTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from assembly://MyAssembly/MyNameSpace</programlisting>
</section>
<section xml:id="templating-nvelocity-custom-resource-loader">
<title>Defining a custom resource loader</title>
<para>The following defines a custom resource loader (the type is an
extension of NVelocity's <literal>ResourceLoader</literal>
class):</para>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine"&gt;
&lt;nv:resource-loader&gt;
&lt;nv:custom name="myResourceLoader"
description="A custom resource loader"
type="MyNamespace.MyResourceLoader, MyAssembly"
path="Template/Velocity/"/&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:engine&gt;
</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-loader-configuration">
<title>Resource Loader configuration options</title>
<para>The &lt;nv:resource-loader&gt; element has additional attributes
which define how NVelocity's resource manager and resource loader
behave.</para>
<table id="templating-nvelocity-resource-loader-configuration-tbl">
<title>Resource Loader Configuration Options</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="2*" />
<colspec colname="c2" colwidth="4*" />
<colspec colname="c3" colwidth="1*" />
<colspec colname="c4" colwidth="1*" />
<thead>
<row>
<entry>Attribute</entry>
<entry>Description</entry>
<entry>Required</entry>
<entry>Default Value</entry>
</row>
</thead>
<tbody>
<row>
<entry>default-cache-size</entry>
<entry>
<para>defines resource manager global cache size, applies when
caching is turned on. This maps to NVelocity's resource
manager <literal>resource.manager.defaultcache.size</literal>
property</para>
</entry>
<entry>no</entry>
<entry>89</entry>
</row>
<row>
<entry>template-caching</entry>
<entry>
<para>Enables template caching for the defined resource
loader. This maps to NVelocity's resource loader
<literal>&lt;name&gt;.resource.loader.cache</literal>
property</para>
</entry>
<entry>no</entry>
<entry>false</entry>
</row>
<row>
<entry>modification-check-interval</entry>
<entry>
<para>The 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
<literal>&lt;name&gt;.resource.loader.modificationCheckInterval</literal>
property</para>
</entry>
<entry>no</entry>
<entry>2</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section xml:id="templating-nvelocity-resource-config">
<title>Using a custom configuration file</title>
<para>If so desired one could provide a custom configuration resource to
customize the NVelocity configuration:</para>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine" config-file="file://Template/Velocity/config.properties"/&gt;</programlisting>
<para>You can override specific properties by providing the
<literal>VelocityProperties</literal> property to the NVelocity factory
object (shown above)</para>
<programlisting language="myxml">&lt;nv:engine id="velocityTemplate" &gt;
&lt;nv:nvelocity-properties&gt;
&lt;entry key="input.encoding" value="ISO-8859-1"/&gt;
&lt;entry key="output.encoding" value="ISO-8859-1"/&gt;
&lt;/nv:nvelocity-properties&gt;
&lt;/nv:engine&gt;</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-logging">
<title>Logging</title>
<para>By default Spring will override NVelocity's default
<literal>ILogSystem</literal> implementation with its own
<literal>CommonsLoggingLogSystem</literal> 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:</para>
<programlisting language="myxml">&lt;template:nvelocity id="velocityEngine" override-logging="false" /&gt;
</programlisting>
</section>
</section>
<section xml:id="templating-nvelocity-resource-merging">
<title>Merging a template</title>
<para>Spring provides the <literal>VelocityEngineUtils</literal> utility
for merging templates using an engine instance:</para>
<programlisting language="myxml">string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyTemplate.vm", Encoding.UTF8.WebName, model);</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-namespace">
<title>Configuring a VelocityEngine without a custom namespace</title>
<para>While most users will prefer to use the NVelocity custom namespace
to configure a VelocityEngine, you can also use standard &lt;object/&gt;
definition syntax as shown below:</para>
<para>To create a VelocityEngine using the default file resource loader
use the definition:</para>
<programlisting language="myxml">&lt;!-- Simple no arg file based configuration use's NVelocity default file resource loader --&gt;
&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" /&gt;</programlisting>
<para>For convenience in defining NVelocity engine instances a custom
namespace is provided, for example the resource loader definition could be
done this way:</para>
<programlisting language="myxml">
&lt;objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity"&gt;
&lt;nv:nvelocity id="velocityEngine" &gt;
&lt;nv:resource-loader&gt;
&lt;nv:file path="Template/Velocity/" /&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:nvelocity&gt;
&lt;/objects</programlisting>
<para>When templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:</para>
<programlisting language="myxml">&lt;!-- Assembly based template loading with NVelocity assembly resource loader --&gt;
&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity"&gt;
&lt;property name="VelocityProperties"&gt;
&lt;dictionary key-type="string" value-type="object"&gt;
&lt;entry key="resource.loader" value="assembly"/&gt;
&lt;entry key="assembly.resource.loader.class" value="NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader"/&gt;
&lt;entry key="assembly.resource.loader.assembly" value="MyAssembly"/&gt;
&lt;/dictionary&gt;
&lt;/property&gt;
&lt;/object&gt;</programlisting>
<para>To load NVelocity templates from a single path use the
definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPath" value="file://MyTemplateFolder/AnotherFolder/" /&gt;
&lt;/object&gt;
</programlisting>
<para>To load NVelocity templates from multiple paths use the
definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPaths" &gt;
&lt;list&gt;
&lt;value&gt;file://MyTemplateFolder/&lt;/value&gt;
&lt;value&gt;file://MyOtherTemplateFolder/&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/object&gt;</programlisting>
<note>
<para>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
<literal>preferFileSystemAccess</literal> property of the factory object
to <literal>false</literal> which will cause the factory to utilize the
supplied spring resource loader.</para>
</note>
<para>To refer to a property file based configuration of the
TemplateEngine use the definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ConfigLocation " value="file://Template/Velocity/config.properties" /&gt;
&lt;/object&gt;</programlisting>
<para><note>
<para>You can override specific properties by providing the
<literal>VelocityProperties</literal> property.</para>
</note></para>
<para>To not integrate with the Common.Logging subsystem, set the
OverrideLogging property to false:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="OverrideLogging" value="false" /&gt;
&lt;/object&gt;</programlisting>
<para></para>
</section>
</chapter>