Overview
Templates provide a mechanism where a template document is created and stored in a template library. Templates can be implemented as a OpenPTK Plugin
Requirements
The initial requirement for Templates is to support the creation of an email's body content. Various Use Cases need to send an email. These Use Cases can leverage the SendEmailPlugin to facilitate the actual "sending" of the email once it is created. Templates would allow the Use Cases to "specify" a pre-configured template document and run-time data which would be "processed" and generate a unique document.
Architecture
Templates will leverage the Plugin mechanism of OpenPTK. The interface will use the following data structures:
Plugin Interface |
StructureIF output = Plugin.execute(StructureIF input) throws PluginException |
input |
|
document |
String |
<template_document_name> |
|
attributes |
|
|
attribute1 |
String |
<attribute_value> |
|
|
attributeN |
String |
<attribute_value> |
output |
|
document |
String |
<merged_document> |
|
status |
String |
<execute_message> |
Template Plugin Configuration:
<Plugins>
<Plugin id="template" enabled="true" classname="org.openptk.plugin.template.TemplatePlugin">
<Properties>
<Property name="template.library" value="WEB-INF/templates"/>
<Property name="missing.attribute" value="variable"/>
</Properties>
</Plugin>
</Plugins>
Implementation
The Plugin architecture supports a startup() method which is called when OpenPTK is initialized. The Template Plugin will override the startup() method to perform the following tasks:
- Verify required attributes
The Plugin interface uses the execute() method to process requests. The Template Plugin will implement the execute() method and perform the following tasks:
- Validate input structure
- Contains document child (sub-structure)
- Contains attributes child (sub-structure)
- Read each attribute child (sub-structure). Load name/value into attribute map
- Merge document and attributes
- Open document
- Read document looking for variables
- For each variable, obtain a value. The variable name should find a matching attribute name in the map
- Generate output structure
- Create structure
- Add "merged" document as a child (sub-structure)
- Add "status" String as a child (sub-structure)
- Set output State to SUCCESS
|
missing attribute
How should the Plugin handle the situation when a template document contains a variable ${varaible_name} but there is not matching attribute in the map. Option:
- Thrown an Exception
- Leave the variable syntax "in place", record warning
- Convert the variable to be blank, record warning
|
A <Property> named missing.attribute will used to determine the behavior should an a Template Document contain a variable that does not have a matching value. Valid choices for this property are:
Value |
Description |
exception |
An PluginException is thrown with the first occurrence of a missing attribute name/value |
variable |
(default) The variable syntax will be left in the document, processing will continue |
blank |
The variable is removed and the value is "blank", processing will continue |
Variables can be obtained their value from a number of sources (scopes). Variables in a Template Document declare a variable with this syntax: ${scope:name}. The table below lists the scopes that are available at run-time:
scope |
name |
type |
description |
example |
template |
library
document |
internal |
The "Template Library Path" that is being used
The "Template Document" that is being used |
${template:library}
${template:document} |
attribute |
<attribute_name> |
input |
The name of an Attribute under the Input's "data" structure |
${attribute:lastname} |
Considerations
Library Path
The required property template.library contains the path of the directory/folder that contains the Template Documents. This property is set when the Plugin is defined. It currently is a fully qualified absolute path in the file system where it is being used. The property can not be a relative path because the "working directory" of the Java process (which calls the Plugin) is not known.
It would be nice to support a relative path, such as WEB-INF/templates when the Template Plugin is used within a Servlet Context. A possible option would be to "build" the Library Path "on demand" and pass it to the plugin:
- Get the deployment path of the Servlet war file
- Add the deployment path as a new "base path" structure to plugin input]
- The plugin would look for the new "base path" input structure
- If exists it would use assemble the "fully qualified path" from the "base path" and the "library path (property)"
|