Creating HTML Templates#
You can create PDF documents from items or wiki documents using HTML/Freemarker templates. This section explains how to convert text and metadata from your documents into PDF format using an HTML/Freemarker template.
Developing an HTML Template#
A web browser with debug functionality is sufficient for developing HTML templates. You should have project administrator rights or be logged in as a system manager or system administrator. Go to Administration > Templates > Wiki Export Templates. Open the “HTML Templates” folder and the desired template folder within it.
It’s easiest to start developing your own templates based on an existing one. You can change the CSS styles directly in Allegra.
The Template Structure#
An HTML template consists of a ZIP file with the extension “.hlx”. The template can be uploaded directly to the wiki or to the administration by authorized individuals.
The next figure shows an expanded template. The top level must contain the template files directly and cannot be nested in a folder.
Important
The template name (e.g., Framed.hlx), the main template file (e.g., Framed.html), and the optional properties file (e.g., Framed.properties) must all have the same base name.
You can create the ZIP file with the following command executed in the template directory:
zip -r ../Framed.hlx *
The individual files and folders are explained below.
Expanded template#
{template name}.html: Example:Framed.html. The ZIP file must contain an HTML template file at the top level with the same base name as the ZIP file. The HTML file may contain Freemarker expressions.{template name}.properties: Example:Framed.properties. Optional file containing parameters for controlling display properties (see below). This file can also contain Freemarker expressions.Directory
resources: Must be named exactly like this. Contains images and other resources.Directory
fonts: Must be named exactly like this. Contains fonts for PDF document generation.Directory
img: Optional directory for additional images.One or more CSS files for styling (e.g.,
base.css,style.css).
The Template File#
The template file is an XHTML file with Freemarker expressions.
Please ensure that the template file is valid XHTML (all tags must be properly closed).
The template file name and template name must be identical, with the extension .html.
All item fields can be used as Freemarker expressions by entering their unique field name. Field names can be found via Administration > Customize > Item Attributes, or in the item overview via column selection.
Freemarker Variables#
The following Freemarker variables are available in templates:
Template and Resource Paths
cssBasePath: Absolute path to the template directory. Example:
href="${cssBasePath}/base.css"imgBasePath: Absolute path to the
resourcesdirectory. Example:${imgBasePath}/allegraLogo.pngserverUrl: Server absolute URL for accessing resources.
Timestamp Variables
timeStamp: Full date and time when the PDF was exported (formatted).
timeStampDate: Only the date portion of the export timestamp.
timeStampTime: Only the time portion of the export timestamp.
currentYear: Current year as a 4-digit integer.
Localization Variables
locale: The user’s locale language code (e.g., “en”, “de”).
pageLbl: Localized word for “Page”.
ofLbl: Localized word for “of” (e.g., Page 1 of 17).
Export Metadata
reportAuthorLbl: Name of the person exporting the PDF.
licenseHolder: Name of the license holder.
Wiki/Document Specific Variables
wikiContent: HTML content of the wiki document (XHTML format).
summary: Wiki document summary/table of contents section (XHTML format).
parentSynopsis: Title of the parent document, if present.
parentSynopsisElided: Parent document title truncated to 40 characters with “…”.
Item Variables
workItems: List of work items being exported (see WorkItem structure below).
workItemID: ID of the work item being exported.
workItemNo: Work item number (project-specific or global ID).
IssueNo: The item number (respects project-specific ID setting).
projectName: Name of the project.
projectTypeID: ID of the project type.
projectTypeLbl: Label/name of the project type.
Common Item Field Variables
These variables are directly available for single-item and wiki exports:
Synopsis: Item title/summary.
ItemType: Item type name (e.g., “Task”, “Bug”).
Originator: Name of the person who created the item.
Responsible: Name of the responsible person.
Manager: Name of the manager.
CreateDate: Creation date of the item.
LastModifiedDate: Date of the last modification.
LastEditedBy: Name of the person who last edited the item.
Custom fields are available by their configured field name (e.g., ${MeetingTime}, ${MeetingLocation}, ${Participants}).
Dynamic Field Access
Fields can be accessed in three ways:
By field ID:
${f123}where 123 is the field ID.By field name:
${priority}using the field’s internal name.By field label:
${Priority}using the localized field label.
For rich text fields, use the _unescaped suffix to get XHTML content: ${f456_unescaped}
For lookup/option fields, access the raw ID with the ID suffix: ${priorityID}
WorkItem Object Structure#
When iterating over workItems, each item provides:
synopsis: Work item title/summary.
workItemID: Unique work item identifier (Integer).
workItemNo: Formatted work item number (String).
projectName: Name of the parent project.
projectTypeID: ID of the project type (Integer).
tabs: List of form tabs containing field groups.
fieldIdToValue: Map of field values by field ID (e.g.,
item.fieldIdToValue["f123"]).fieldNameToValue: Map of field values by field name (e.g.,
item.fieldNameToValue["priority"]).comments: List of CommentRow objects (if included in export).
internalComments: List of internal/private CommentRow objects (if included).
history: List of history entries (Map with keys:
changedByID,changedByName,changedOn,diffFull,token).costs: List of cost/effort records (Map with keys:
changedByID,changedByName,description,subject,effortDateAgoFormat,account,currency,cost,hours,token).accountingBean: Budget and planning information (see AccountingBean structure below).
reportBeanLinksSet: Sorted set of linked items (see ReportBeanLink structure below).
children: List of child WorkItem objects (sub-tasks).
Tab Structure: Each tab has a title (String) and contains panels (List).
Panel Structure: Each panel has a title (String) and contains fields (List).
Field Structure: Each field provides:
name: Localized field label (String).
value: Field value (String).
fieldID: Unique field identifier (Integer).
hidden: Whether field is hidden due to access restrictions (boolean).
CommentRow Structure#
Each comment in comments or internalComments provides:
id: Comment ID (Integer).
comment: Comment text/HTML content.
author: Name of the last person who modified the comment.
authorID: ID of the last modifier (for avatar loading).
authorPhone: Phone number of the author.
createdBy: Name of the original comment creator.
createdByID: ID of the original creator.
created: Creation date (Date object).
createdAgo: Human-readable time since creation (e.g., “2 hours ago”).
changedAt: Last modification date (Date object).
changedAgo: Human-readable time since last change.
changedByName: Name of the person who last changed the comment.
edited: Whether the comment was edited after creation (boolean).
editable: Whether the current user can edit the comment (boolean).
like: Whether the current user liked the comment (boolean).
noOfLikes: Number of likes (Integer).
likedBy: List of names who liked the comment.
internalComment: Whether this is an internal comment (boolean).
token: Security token for avatar/resource loading.
hasOriginalEmail: Whether there’s an original email attached (boolean).
attachments: List of email attachments (if from email).
ReportBeanLink Structure#
Each link in reportBeanLinksSet provides:
objectID: Link object ID (Integer).
workItemID: ID of the linked work item (Integer).
linkedItemNo: Item number of the linked item (String).
linkedItemTitle: Title of the linked item (String).
linkedItemIncluded: Whether linked item is included in export (boolean).
linkedItemStatusID: Status ID of the linked item (Integer).
linkTypeID: Type of the link (Integer).
linkDirection: Direction of the link (Integer).
linkTypeName: Name of the link type (String).
AccountingBean Structure#
The accountingBean provides budget and time tracking information:
Tracking Flags
workTracking: Whether work/time tracking is enabled (boolean).
costTracking: Whether cost tracking is enabled (boolean).
Expense Totals
expenseHours: Total hours expended (String).
expenseCost: Total cost expended (String).
timeUnitExpenses: Time unit for expenses (String).
currency: Currency code (String).
Budget Information
budgetTimeStr: Budgeted time as formatted string.
budgetCostStr: Budgeted cost as formatted string.
budgetHoursDouble: Budgeted hours (Double).
budgetCostDouble: Budgeted cost (Double).
budgetByName: Name of person who set the budget.
budgetDescription: Budget description.
budgetTimeUnitInt: Time unit for budget (Integer).
seeBudget: Whether user can see budget (boolean).
modifyBudget: Whether user can modify budget (boolean).
Planned Values
plannedTimeStr: Planned time as formatted string.
plannedCostStr: Planned cost as formatted string.
plannedTimeDouble: Planned time (Double).
plannedCostDouble: Planned cost (Double).
plannedByName: Name of person who set the plan.
planDescription: Plan description.
plannedValueTimeUnit: Time unit for planned values (Integer).
seePlan: Whether user can see plan (boolean).
modifyPlan: Whether user can modify plan (boolean).
Remaining Plan
remainingPlannedHoursStr: Remaining planned hours as string.
remainedPlannedCostStr: Remaining planned cost as string.
remainingPlanTime: Remaining planned time (Double).
remainingPlanCost: Remaining planned cost (Double).
remainedPlannedByName: Name of person who set remaining plan.
remainingTimeUnit: Time unit for remaining values (Integer).
seeRemainingPlan: Whether user can see remaining plan (boolean).
modifyRemainingPlan: Whether user can modify remaining plan (boolean).
Completion Progress
timeCompletionDegree: Time completion percentage (Double, 0-100).
costCompletionDegree: Cost completion percentage (Double, 0-100).
timeBarGraphicsList: HTML for time progress bar.
costBarGraphicsList: HTML for cost progress bar.
Page Layout Elements#
The PDF generator supports special div elements with specific IDs for headers, footers, and margins.
Use the margin-box class along with these IDs:
Header Area
topLeftCorner,topLeft,topCenter,topRight,topRightCorner
Footer Area
bottomLeftCorner,bottomLeft,bottomCenter,bottomCenterFirst(first page only),bottomRight,bottomRightCorner
Side Margins
leftTop,leftMiddle,leftBottomrightTop,rightMiddle,rightBottom
Page Number Placeholders
Use these span elements within headers/footers for automatic page numbering:
<span id="pagenumber"></span>- Current page number<span id="pagecount"></span>- Total page count
Loading Server Resources
To load the company logo from the server:
<img src="${serverUrl}/logoAction.action?convertSVGToPNG=true&logoType=r" />
To load user avatars (e.g., in comments):
<img src="${serverUrl}/personAvatar.action?convertSvgToPng=true&personID=${comment.authorID}&token=${comment.token}" />
Locale-based Content
Use Freemarker conditionals to provide localized content:
<#if (locale)?has_content && locale=="de">
<#assign StrPage="Seite" StrOf="von">
<#else>
<#assign StrPage="Page" StrOf="of">
</#if>
Page Breaks
To force a page break between sections:
<div style="page-break-after: always;"></div>
Or use a CSS class:
<div class="pagebreak"></div>
Example template iteration:
<#list workItems as item>
<h1>${item.synopsis}</h1>
<#list item.tabs as tab>
<h2>${tab.title}</h2>
<#list tab.panels as panel>
<h3>${panel.title}</h3>
<#list panel.fields as field>
<#if !field.hidden>
<p><strong>${field.name}:</strong> ${field.value}</p>
</#if>
</#list>
</#list>
</#list>
</#list>
The Template Configuration File#
If the template directory contains a file {templateName}.properties, it is used by the system.
This file is optional and can contain Freemarker expressions. All document fields can be used as
Freemarker expressions within it. Available configuration options are:
contentMaxWidth: An integer in pixels. If the “width” attribute of an image or table is greater than this value, the corresponding object is scaled.
watermarkImgName: The name of an image file, whose image should be used as a watermark
watermarkText: This text is displayed as a watermark in the center and possibly rotated on each page
watermarkTextSize: Watermark text size in points.
watermarkTextColor: Watermark text color in hex notation (e.g.,
#000000).watermarkTextRotation: Rotation angle. 0 is horizontal, 90 is vertical.
renderLinks: Set to
trueto render the list of linked items. Default isfalse.equationSize: LaTeX equation text size in points (e.g.,
20).templateTarget: Specifies the template target type:
1- Wiki document export2- Single item form export3- Multiple item form export
All configuration fields are optional. If both watermarkImgName and watermarkText are defined,
watermarkImgName takes precedence.
Example properties file:
# Content width for scaling
contentMaxWidth=600
# Watermark settings (optional)
#watermarkText=CONFIDENTIAL
#watermarkTextSize=48
#watermarkTextColor=#CCCCCC
#watermarkTextRotation=45
# Enable linked items rendering
#renderLinks=true
# LaTeX equation size
#equationSize=20
# Template target (1=Wiki, 2=Single item, 3=Multiple items)
templateTarget=2
Practical Examples#
Wiki Document Template#
Basic structure for exporting wiki documents:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="${cssBasePath}/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- Header with logo -->
<div id="topRight" class="margin-box">
<img src="${serverUrl}/logoAction.action?convertSVGToPNG=true&logoType=r" />
</div>
<!-- Footer with page numbers -->
<div id="bottomCenter" class="margin-box footer">
${pageLbl} <span id="pagenumber"></span> ${ofLbl} <span id="pagecount"></span>
</div>
<!-- Cover page -->
<div style="page-break-after: always;">
<h1>${Synopsis}</h1>
<p>Created by: ${Originator}</p>
<p>Last modified: ${LastModifiedDate}</p>
</div>
<!-- Table of contents -->
<#if summary?? && summary?has_content>
<h1>Contents</h1>
${summary}
</#if>
<!-- Document content -->
<div class="content">
${wikiContent}
</div>
</body>
</html>
Item Export Template#
Template for exporting multiple items with comments and history:
<#if workItems?has_content>
<#list workItems as workItem>
<h1>${workItem.synopsis}</h1>
<!-- Item fields -->
<#if workItem.tabs?has_content>
<#list workItem.tabs as tab>
<#list tab.panels as panel>
<#list panel.fields as field>
<#if !field.hidden>
<p><strong>${field.name}:</strong> ${field.value}</p>
</#if>
</#list>
</#list>
</#list>
</#if>
<!-- Comments -->
<#if workItem.comments?has_content>
<h2>Comments</h2>
<#list workItem.comments as comment>
<div class="comment">
<strong>${comment.author}</strong>
<span class="date">${comment.changedAgo}</span>
<div>${comment.comment}</div>
</div>
</#list>
</#if>
<!-- Linked items -->
<#if workItem.reportBeanLinksSet?has_content>
<h2>Links</h2>
<table>
<tr><th>Type</th><th>Item</th><th>Title</th></tr>
<#list workItem.reportBeanLinksSet as link>
<tr>
<td>${link.linkTypeName}</td>
<td>${link.linkedItemNo}</td>
<td>${link.linkedItemTitle}</td>
</tr>
</#list>
</table>
</#if>
<!-- Page break between items -->
<#if workItem_index < workItems?size - 1>
<div style="page-break-after: always;"></div>
</#if>
</#list>
</#if>
Checking for Undefined Attributes#
Use a macro to safely check for custom fields that may not be defined:
<#macro checkdef attribute>
<#if (attribute?eval)?has_content>
${attribute?eval}
<#else>
<span style="color: red;">
<#if locale == "de">
Bitte Attribut "${attribute}" konfigurieren
<#else>
Please configure attribute "${attribute}"
</#if>
</span>
</#if>
</#macro>
<!-- Usage -->
<p>Meeting Time: <@checkdef "MeetingTime"/></p>
<p>Location: <@checkdef "MeetingLocation"/></p>