Creating Word Freemarker based templates#
A Freemarker based Word template is an ordinary Word document (.docx) that contains
Freemarker expressions. You design the
document in MS Word, with its own styles, headers, footers, and tables, and type the
expressions wherever item data should appear. On export, Allegra fills in the
expressions and returns a Word document.
Unlike legacy templates (see Creating Word Legacy templates), you do not need a Word plug-in or content controls. The template controls the whole layout of the document.
Turning a Word document into a Freemarker template#
Allegra uses the Freemarker engine only for Word templates that ask for it. You set this up with custom document properties:
In MS Word, open the document you want to use as a template.
Go to
File>Info>Properties>Advanced Propertiesand open theCustomtab.Add a property named
allegraTemplateEngineof typeTextwith the valuefreemarker.Add any other settings you need from the list below.
Save the document and upload it under
Administration>Templates>Export templates.
A Word template without allegraTemplateEngine=freemarker is treated as a legacy template.
Note
Allegra removes its own allegra… properties from the exported document. Custom properties
that you define yourself are kept.
Template settings#
These settings match the HTML template settings (see Creating HTML templates), with an allegra
prefix added. For yes/no settings, you can use the Word property type Yes or no, or
enter true, yes, or 1 as text.
Property |
Default |
Description |
|---|---|---|
|
Must be |
|
|
(none) |
|
|
yes |
Loads the item history, comments, and internal comments. |
|
yes |
Loads the booked costs. |
|
yes |
Loads the budget and planned value entries. |
|
no |
Loads the linked items. |
|
no |
Adds the child items of the exported items to |
|
no |
With |
|
no |
With |
Loading history, costs, and budget makes the export slower. If your template does not use
them, set these properties to no.
Writing expressions in Word#
Word templates use Freemarker’s square bracket syntax for directives, because Word escapes the angle brackets that you type:
[#list items as item]
${item.no} ${item.synopsis}
[/#list]
[#if item.fields["Status"] == "closed"]closed[/#if]
[#-- a comment --]
Interpolations still use ${...}. You can type expressions straight into the document text,
and you can format them with any Word formatting. Allegra fixes the typographic quotes and
dashes that Word’s AutoCorrect puts into expressions, so you do not have to turn AutoCorrect off.
Paragraphs and table rows#
If a paragraph contains only directives such as
[#list ...]or[/#if], Allegra removes the paragraph itself. As a result, a directive on its own line does not leave an empty line in the output.A paragraph with at least one
${...}interpolation is kept. So[#if item.project??]Project: ${item.project}[/#if]on its own line becomes a line that appears only when the condition is true.To repeat a table row, put the opening
[#list ...]in a row of its own above it and the closing[/#list]in a row of its own below it. Allegra removes these directive-only rows, and the row between them is repeated once per entry.
| Type | Item | Title |
| [#list item.links as link] | | |
| ${link.type} | ${link.itemNo} | ${link.title} |
| [/#list] | | |
Important
Every directive must open and close within the same structure. A loop that opens inside a table cell and closes outside the table produces an invalid document, and the export fails with the message “The rendered template is not valid WordprocessingML”.
Rich text#
Item descriptions, comments, and history differences are HTML. Write them with the html()
function, which converts the HTML into Word content and embeds any images it contains:
${html(item.description)}
Written as ${item.description}, the description shows its HTML markup as text.
The converted text uses the template’s default font (the Normal style font), unless the
rich text sets a font of its own.
You can also pass your own HTML to html(). This is how you create a clickable link to an item:
${html('<a href="' + item.url + '">' + item.no + '</a>')}
${item.url} on its own is only the address as plain text. item.url is empty if the
server URL is not configured in Allegra.
To show a person’s avatar, embed it as an image and always give it a size. Without a size, the avatar is shown at full size:
[#if comment.avatar??]${html('<img src="' + comment.avatar + '" style="width:18pt;height:18pt"/>')}[/#if]
Freemarker variables#
The template receives the following top-level variables:
Variable |
Description |
|---|---|
|
The exported items (a list of items, see below). In a Wiki document export, these are the items that make up the document. |
|
The exported Wiki document as an item, or null in an item export. Check it with
|
|
Converts rich text (HTML) into Word content. See Rich text. |
|
Returns the localized text of an Allegra resource key in the exporting user’s language. If the key is not found, the key itself is shown. |
|
The name of the person who runs the export. |
|
The export time as a date value, which you can format with Freemarker, e.g.
|
|
The export time, already formatted for the user’s locale. |
|
The user’s language code, e.g. |
|
The configured server URL of Allegra. |
|
The license holder. |
Dates in the model (created, lastModified, createdOn, and so on) are already formatted
for the exporting user’s locale. You can print them as they are.
Item#
Attribute |
Description |
|---|---|
|
The internal item ID. |
|
The item number as shown in Allegra. |
|
The absolute link to the item, or empty if no server URL is configured. |
|
The title. |
|
The description as HTML, with Allegra macros already expanded. Use |
|
The project name. |
|
The ID of the project type. |
|
Creation and last change time. |
|
The project’s currency, e.g. “Euro” and “EUR”. Empty if the project has none. |
|
|
|
All field values by field name, e.g. |
|
All field values by |
|
Linked items (see below). Requires |
|
Child items, with the same structure. Requires |
|
Field changes, newest first. Requires |
|
Comments and internal comments. Require |
|
Booked costs. Requires |
|
Budget and planned value entries. Requires |
Link#
Attribute |
Description |
|---|---|
|
The link type name. |
|
ID, number, title, and status of the linked item. |
|
The absolute link to the linked item, or empty. |
|
|
Comment#
Attribute |
Description |
|---|---|
|
The author’s name and ID. |
|
When the comment was written. |
|
The comment as HTML. Use |
|
The author’s avatar as an embedded image (data URI), or null. |
History entry#
Attribute |
Description |
|---|---|
|
The name and ID of the person who made the change. |
|
When the change was made. |
|
The name of the changed field. |
|
The old and new value as HTML, as on the history tab. Use |
|
The avatar of the person who made the change, or null. |
Cost#
effortDate, person, subject, description, hours, cost, currency.
Budget entry#
changedOn, changedBy, description, estimatedHours, estimatedCost, currency,
and plannedValue (true for a planned value entry, false for a budget entry).
Note
Freemarker stops with an error when an expression is null. For values that may be missing,
such as document or avatar, use [#if x??] or a default value like ${x!""}.
Examples#
Items with their fields and description:
[#list items as item]
${item.no} ${item.synopsis}
Project: ${item.project} Status: ${item.fields["Status"]!""}
${html(item.description)}
[/#list]
Item hierarchy with a recursive macro (requires allegraIncludeChildren):
[#macro render item]
${item.no} ${item.synopsis}
${html(item.description)}
[#list item.children as child][@render child/][/#list]
[/#macro]
[#list items as item][@render item/][/#list]
Comments:
[#if item.comments?has_content]
Comments
[#list item.comments as comment]
${comment.author}, ${comment.createdOn}
${html(comment.text)}
[/#list]
[/#if]
Wiki document title, falling back to the first item:
[#if document??]${document.synopsis}[#else]${items[0].synopsis}[/#if]
Troubleshooting#
If a template cannot be processed, the export shows Freemarker’s error message, including the expression that caused it. For other errors, the message contains a short reference code. Give this code to your administrator, who can use it to find the cause in the server log.
An expression appears literally in the output: check the spelling and that the directive uses square brackets (
[#if], not<#if>).The export fails with “not valid WordprocessingML”: a directive opens and closes in different paragraphs or tables. See Paragraphs and table rows.
A list is empty: check that the corresponding
allegraInclude…property is set.