Erstellen von HTML-Vorlagen#

Sie können PDF-Dokumente aus Vorgängen oder Wiki-Dokumenten mit HTML/Freemarker-Vorlagen erstellen. Dieser Abschnitt erklärt, wie Sie Text und Metadaten aus Ihren Dokumenten mit einer HTML/Freemarker-Vorlage in das PDF-Format konvertieren können.

HTML-Vorlage entwickeln#

Zur Entwicklung von HTML-Vorlagen genügt ein Webbrowser mit Debug-Funktionalität. Sie sollten Projekt-Administrator-Rechte haben oder als Systemmanager oder Systemadministrator angemeldet sein. Gehen Sie zu Verwaltung > Vorlagen > Wiki-Exportvorlagen. Öffnen Sie den Ordner „HTML-Vorlagen“ und darin den gewünschten Vorlagenordner.

Es ist am einfachsten, wenn Sie für die Entwicklung eigener Vorlagen von einer bestehenden ausgehen. Sie können die CSS-Stile direkt in Allegra ändern.

Die Vorlagen-Struktur#

Eine HTML-Vorlage besteht aus einer ZIP-Datei mit der Endung „.hlx“. Die Vorlage kann direkt im Wiki oder in der Verwaltung von dazu Berechtigten hochgeladen werden.

Die nächste Abbildung zeigt eine expandierte Vorlage. Die oberste Ebene muss die Template-Dateien direkt enthalten und darf nicht in einem Ordner verschachtelt sein.

Wichtig

Der Vorlagenname (z.B. Framed.hlx), die Haupt-Vorlagendatei (z.B. Framed.html) und die optionale Properties-Datei (z.B. Framed.properties) müssen alle denselben Basisnamen haben.

Sie können die ZIP-Datei mit folgendem Befehl im Vorlagenverzeichnis erzeugen:

zip -r ../Framed.hlx *

Im Folgenden werden die einzelnen Dateien und Ordner erklärt.

../../_images/html-template1.PNG

Expandierte Vorlage#

  • {Vorlagenname}.html: Beispiel: Framed.html. Die ZIP-Datei muss auf der obersten Ebene eine HTML-Vorlagendatei mit demselben Basisnamen wie die ZIP-Datei enthalten. Die HTML-Datei darf Freemarker-Ausdrücke enthalten.

  • {Vorlagenname}.properties: Beispiel: Framed.properties. Optionale Datei mit Parametern zur Steuerung der Anzeigeeigenschaften (siehe unten). Diese Datei kann ebenfalls Freemarker-Ausdrücke enthalten.

  • Verzeichnis resources: Muss exakt so heißen. Enthält Bilder und andere Ressourcen.

  • Verzeichnis fonts: Muss exakt so heißen. Enthält Schriftarten für die PDF-Dokumenterstellung.

  • Verzeichnis img: Optionales Verzeichnis für zusätzliche Bilder.

  • Eine oder mehrere CSS-Dateien für das Styling (z.B. base.css, style.css).

Die Vorlagen-Datei#

Die Vorlagendatei ist eine XHTML-Datei mit Freemarker-Ausdrücken. Bitte stellen Sie sicher, dass die Vorlagendatei gültiges XHTML ist (alle Tags müssen korrekt geschlossen sein). Der Name der Vorlagendatei und der Vorlagenname müssen identisch sein, mit der Erweiterung .html.

Alle Vorgangsfelder können als Freemarker-Ausdrücke verwendet werden, indem Sie deren eindeutigen Feldnamen eingeben. Feldnamen finden Sie unter Verwaltung > Anpassen > Vorgangsattribute oder in der Vorgangsübersicht über die Spaltenauswahl.

Freemarker-Variablen#

Die folgenden Freemarker-Variablen sind in Vorlagen verfügbar:

Vorlagen- und Ressourcenpfade

  • cssBasePath: Absoluter Pfad zum Vorlagenverzeichnis. Beispiel: href="${cssBasePath}/base.css"

  • imgBasePath: Absoluter Pfad zum resources-Verzeichnis. Beispiel: ${imgBasePath}/allegraLogo.png

  • serverUrl: Absolute Server-URL für den Zugriff auf Ressourcen.

Zeitstempel-Variablen

  • timeStamp: Vollständiges Datum und Uhrzeit des PDF-Exports (formatiert).

  • timeStampDate: Nur der Datumsteil des Export-Zeitstempels.

  • timeStampTime: Nur der Uhrzeitteil des Export-Zeitstempels.

  • currentYear: Aktuelles Jahr als 4-stellige Ganzzahl.

Lokalisierungsvariablen

  • locale: Sprachcode des Benutzers (z.B. „en“, „de“).

  • pageLbl: Lokalisiertes Wort für „Seite“.

  • ofLbl: Lokalisiertes Wort für „von“ (z.B. Seite 1 von 17).

Export-Metadaten

  • reportAuthorLbl: Name der Person, die das PDF exportiert.

  • licenseHolder: Name des Lizenzinhabers.

Wiki/Dokument-spezifische Variablen

  • wikiContent: HTML-Inhalt des Wiki-Dokuments (XHTML-Format).

  • summary: Zusammenfassung/Inhaltsverzeichnis des Wiki-Dokuments (XHTML-Format).

  • parentSynopsis: Titel des übergeordneten Dokuments, falls vorhanden.

  • parentSynopsisElided: Titel des übergeordneten Dokuments, auf 40 Zeichen gekürzt mit „…“.

Vorgangs-Variablen

  • workItems: Liste der zu exportierenden Vorgänge (siehe WorkItem-Struktur unten).

  • workItemID: ID des zu exportierenden Vorgangs.

  • workItemNo: Vorgangsnummer (bereichsspezifisch oder global).

  • IssueNo: Die Vorgangsnummer (berücksichtigt bereichsspezifische ID-Einstellung).

  • projectName: Name des Projekts.

  • projectTypeID: ID des Projekttyps.

  • projectTypeLbl: Bezeichnung/Name des Projekttyps.

Allgemeine Vorgangsfeld-Variablen

Diese Variablen sind direkt für Einzelvorgang- und Wiki-Exporte verfügbar:

  • Synopsis: Vorgangstitel/Zusammenfassung.

  • ItemType: Name des Vorgangstyps (z.B. „Aufgabe“, „Fehler“).

  • Originator: Name der Person, die den Vorgang erstellt hat.

  • Responsible: Name des Bearbeiters.

  • Manager: Name des Managers.

  • CreateDate: Erstellungsdatum des Vorgangs.

  • LastModifiedDate: Datum der letzten Änderung.

  • LastEditedBy: Name der Person, die den Vorgang zuletzt bearbeitet hat.

Benutzerdefinierte Felder sind über ihren konfigurierten Feldnamen verfügbar (z.B. ${MeetingTime}, ${MeetingLocation}, ${Participants}).

Dynamischer Feldzugriff

Felder können auf drei Arten zugegriffen werden:

  • Nach Feld-ID: ${f123} wobei 123 die Feld-ID ist.

  • Nach Feldname: ${priority} unter Verwendung des internen Feldnamens.

  • Nach Feldbezeichnung: ${Priority} unter Verwendung der lokalisierten Feldbezeichnung.

Für Rich-Text-Felder verwenden Sie das _unescaped-Suffix für XHTML-Inhalt: ${f456_unescaped}

Für Lookup-/Optionsfelder greifen Sie auf die rohe ID mit dem ID-Suffix zu: ${priorityID}

WorkItem-Objektstruktur#

Bei der Iteration über workItems bietet jedes Element:

  • synopsis: Vorgangstitel/Zusammenfassung.

  • workItemID: Eindeutige Vorgangs-ID (Integer).

  • workItemNo: Formatierte Vorgangsnummer (String).

  • projectName: Name des übergeordneten Projekts.

  • projectTypeID: ID des Projekttyps (Integer).

  • tabs: Liste der Formular-Tabs mit Feldgruppen.

  • fieldIdToValue: Map der Feldwerte nach Feld-ID (z.B. item.fieldIdToValue["f123"]).

  • fieldNameToValue: Map der Feldwerte nach Feldname (z.B. item.fieldNameToValue["priority"]).

  • comments: Liste der CommentRow-Objekte (falls im Export enthalten).

  • internalComments: Liste der internen/privaten CommentRow-Objekte (falls enthalten).

  • history: Liste der Historieneinträge (Map mit Schlüsseln: changedByID, changedByName, changedOn, diffFull, token).

  • costs: Liste der Aufwands-/Kosteneinträge (Map mit Schlüsseln: changedByID, changedByName, description, subject, effortDateAgoFormat, account, currency, cost, hours, token).

  • accountingBean: Budget- und Planungsinformationen (siehe AccountingBean-Struktur unten).

  • reportBeanLinksSet: Sortierte Menge der verknüpften Vorgänge (siehe ReportBeanLink-Struktur unten).

  • children: Liste der untergeordneten WorkItem-Objekte (Untervorgänge).

Tab-Struktur: Jeder Tab hat einen title (String) und enthält panels (Liste).

Panel-Struktur: Jedes Panel hat einen title (String) und enthält fields (Liste).

Feld-Struktur: Jedes Feld bietet:

  • name: Lokalisierte Feldbezeichnung (String).

  • value: Feldwert (String).

  • fieldID: Eindeutige Feld-ID (Integer).

  • hidden: Ob das Feld aufgrund von Zugriffsrechten verborgen ist (Boolean).

CommentRow-Struktur#

Jeder Kommentar in comments oder internalComments bietet:

  • id: Kommentar-ID (Integer).

  • comment: Kommentartext/HTML-Inhalt.

  • author: Name der letzten Person, die den Kommentar geändert hat.

  • authorID: ID des letzten Bearbeiters (für Avatar-Laden).

  • authorPhone: Telefonnummer des Autors.

  • createdBy: Name des ursprünglichen Kommentar-Erstellers.

  • createdByID: ID des ursprünglichen Erstellers.

  • created: Erstellungsdatum (Date-Objekt).

  • createdAgo: Lesbare Zeit seit Erstellung (z.B. „vor 2 Stunden“).

  • changedAt: Datum der letzten Änderung (Date-Objekt).

  • changedAgo: Lesbare Zeit seit letzter Änderung.

  • changedByName: Name der Person, die den Kommentar zuletzt geändert hat.

  • edited: Ob der Kommentar nach der Erstellung bearbeitet wurde (Boolean).

  • editable: Ob der aktuelle Benutzer den Kommentar bearbeiten kann (Boolean).

  • like: Ob der aktuelle Benutzer den Kommentar geliked hat (Boolean).

  • noOfLikes: Anzahl der Likes (Integer).

  • likedBy: Liste der Namen, die den Kommentar geliked haben.

  • internalComment: Ob dies ein interner Kommentar ist (Boolean).

  • token: Sicherheits-Token für Avatar-/Ressourcenladen.

  • hasOriginalEmail: Ob eine Original-E-Mail angehängt ist (Boolean).

  • attachments: Liste der E-Mail-Anhänge (falls aus E-Mail).

AccountingBean-Struktur#

Der accountingBean bietet Budget- und Zeiterfassungsinformationen:

Tracking-Flags

  • workTracking: Ob Arbeits-/Zeiterfassung aktiviert ist (Boolean).

  • costTracking: Ob Kostenerfassung aktiviert ist (Boolean).

Ausgaben-Summen

  • expenseHours: Insgesamt aufgewendete Stunden (String).

  • expenseCost: Insgesamt aufgewendete Kosten (String).

  • timeUnitExpenses: Zeiteinheit für Ausgaben (String).

  • currency: Währungscode (String).

Budget-Informationen

  • budgetTimeStr: Budgetierte Zeit als formatierter String.

  • budgetCostStr: Budgetierte Kosten als formatierter String.

  • budgetHoursDouble: Budgetierte Stunden (Double).

  • budgetCostDouble: Budgetierte Kosten (Double).

  • budgetByName: Name der Person, die das Budget festgelegt hat.

  • budgetDescription: Budget-Beschreibung.

  • budgetTimeUnitInt: Zeiteinheit für Budget (Integer).

  • seeBudget: Ob Benutzer das Budget sehen kann (Boolean).

  • modifyBudget: Ob Benutzer das Budget ändern kann (Boolean).

Planwerte

  • plannedTimeStr: Geplante Zeit als formatierter String.

  • plannedCostStr: Geplante Kosten als formatierter String.

  • plannedTimeDouble: Geplante Zeit (Double).

  • plannedCostDouble: Geplante Kosten (Double).

  • plannedByName: Name der Person, die den Plan festgelegt hat.

  • planDescription: Plan-Beschreibung.

  • plannedValueTimeUnit: Zeiteinheit für Planwerte (Integer).

  • seePlan: Ob Benutzer den Plan sehen kann (Boolean).

  • modifyPlan: Ob Benutzer den Plan ändern kann (Boolean).

Restaufwand

  • remainingPlannedHoursStr: Verbleibende geplante Stunden als String.

  • remainedPlannedCostStr: Verbleibende geplante Kosten als String.

  • remainingPlanTime: Verbleibende geplante Zeit (Double).

  • remainingPlanCost: Verbleibende geplante Kosten (Double).

  • remainedPlannedByName: Name der Person, die den Restaufwand festgelegt hat.

  • remainingTimeUnit: Zeiteinheit für Restwerte (Integer).

  • seeRemainingPlan: Ob Benutzer den Restaufwand sehen kann (Boolean).

  • modifyRemainingPlan: Ob Benutzer den Restaufwand ändern kann (Boolean).

Fertigstellungsgrad

  • timeCompletionDegree: Zeitlicher Fertigstellungsgrad (Double, 0-100).

  • costCompletionDegree: Kostenmäßiger Fertigstellungsgrad (Double, 0-100).

  • timeBarGraphicsList: HTML für Zeit-Fortschrittsbalken.

  • costBarGraphicsList: HTML für Kosten-Fortschrittsbalken.

Seitenlayout-Elemente#

Der PDF-Generator unterstützt spezielle div-Elemente mit bestimmten IDs für Kopf-, Fuß- und Randbereiche. Verwenden Sie die margin-box-Klasse zusammen mit diesen IDs:

Kopfbereich

  • topLeftCorner, topLeft, topCenter, topRight, topRightCorner

Fußbereich

  • bottomLeftCorner, bottomLeft, bottomCenter, bottomCenterFirst (nur erste Seite), bottomRight, bottomRightCorner

Seitenränder

  • leftTop, leftMiddle, leftBottom

  • rightTop, rightMiddle, rightBottom

Seitennummer-Platzhalter

Verwenden Sie diese Span-Elemente in Kopf-/Fußzeilen für automatische Seitennummerierung:

  • <span id="pagenumber"></span> - Aktuelle Seitennummer

  • <span id="pagecount"></span> - Gesamtseitenzahl

Server-Ressourcen laden

So laden Sie das Firmenlogo vom Server:

<img src="${serverUrl}/logoAction.action?convertSVGToPNG=true&amp;logoType=r" />

So laden Sie Benutzer-Avatare (z.B. in Kommentaren):

<img src="${serverUrl}/personAvatar.action?convertSvgToPng=true&amp;personID=${comment.authorID}&amp;token=${comment.token}" />

Lokalisierungsbasierte Inhalte

Verwenden Sie Freemarker-Bedingungen für lokalisierte Inhalte:

<#if (locale)?has_content && locale=="de">
  <#assign StrPage="Seite" StrOf="von">
<#else>
  <#assign StrPage="Page" StrOf="of">
</#if>

Seitenumbrüche

So erzwingen Sie einen Seitenumbruch zwischen Abschnitten:

<div style="page-break-after: always;"></div>

Oder verwenden Sie eine CSS-Klasse:

<div class="pagebreak"></div>

Beispiel für 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>

Die Vorlagen-Konfigurationsdatei#

Wenn das Vorlagenverzeichnis eine Datei {Vorlagenname}.properties enthält, wird sie vom System verwendet. Diese Datei ist optional und kann Freemarker-Ausdrücke enthalten. Alle Dokumentfelder können als Freemarker-Ausdrücke darin verwendet werden. Verfügbare Konfigurationsoptionen sind:

  • contentMaxWidth: Eine Ganzzahl in Pixeln. Wenn das „width“-Attribut eines Bildes oder einer Tabelle größer als dieser Wert ist, wird das entsprechende Objekt skaliert.

  • watermarkImgName: Der Name einer Bilddatei, deren Bild als Wasserzeichen verwendet werden soll.

  • watermarkText: Dieser Text wird auf jeder Seite mittig und ggf. gedreht als Wasserzeichen angezeigt.

  • watermarkTextSize: Wasserzeichen-Textgröße in Punkten.

  • watermarkTextColor: Wasserzeichen-Textfarbe in Hex-Notation (z.B. #000000).

  • watermarkTextRotation: Drehwinkel. 0 ist horizontal, 90 ist vertikal.

  • renderLinks: Auf true setzen, um die Liste der verknüpften Vorgänge anzuzeigen. Standard ist false.

  • equationSize: LaTeX-Gleichungs-Textgröße in Punkten (z.B. 20).

  • templateTarget: Gibt den Vorlagen-Zieltyp an:

    • 1 - Wiki-Dokument-Export

    • 2 - Einzelvorgang-Formular-Export

    • 3 - Mehrfachvorgang-Formular-Export

Alle Konfigurationsfelder sind optional. Wenn sowohl watermarkImgName als auch watermarkText definiert sind, hat watermarkImgName Priorität.

Beispiel Properties-Datei:

# Inhaltsbreite für Skalierung
contentMaxWidth=600

# Wasserzeichen-Einstellungen (optional)
#watermarkText=VERTRAULICH
#watermarkTextSize=48
#watermarkTextColor=#CCCCCC
#watermarkTextRotation=45

# Verknüpfte Vorgänge anzeigen
#renderLinks=true

# LaTeX-Gleichungsgröße
#equationSize=20

# Vorlagen-Ziel (1=Wiki, 2=Einzelvorgang, 3=Mehrere Vorgänge)
templateTarget=2

Praxisbeispiele#

Wiki-Dokument-Vorlage#

Grundstruktur für den Export von Wiki-Dokumenten:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link href="${cssBasePath}/style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <!-- Kopfzeile mit Logo -->
    <div id="topRight" class="margin-box">
      <img src="${serverUrl}/logoAction.action?convertSVGToPNG=true&amp;logoType=r" />
    </div>

    <!-- Fußzeile mit Seitennummern -->
    <div id="bottomCenter" class="margin-box footer">
      ${pageLbl} <span id="pagenumber"></span> ${ofLbl} <span id="pagecount"></span>
    </div>

    <!-- Deckblatt -->
    <div style="page-break-after: always;">
      <h1>${Synopsis}</h1>
      <p>Erstellt von: ${Originator}</p>
      <p>Zuletzt geändert: ${LastModifiedDate}</p>
    </div>

    <!-- Inhaltsverzeichnis -->
    <#if summary?? && summary?has_content>
      <h1>Inhalt</h1>
      ${summary}
    </#if>

    <!-- Dokumentinhalt -->
    <div class="content">
      ${wikiContent}
    </div>
  </body>
</html>

Vorgangs-Export-Vorlage#

Vorlage für den Export mehrerer Vorgänge mit Kommentaren und Historie:

<#if workItems?has_content>
  <#list workItems as workItem>
    <h1>${workItem.synopsis}</h1>

    <!-- Vorgangsfelder -->
    <#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>

    <!-- Kommentare -->
    <#if workItem.comments?has_content>
      <h2>Kommentare</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>

    <!-- Verknüpfte Vorgänge -->
    <#if workItem.reportBeanLinksSet?has_content>
      <h2>Verknüpfungen</h2>
      <table>
        <tr><th>Typ</th><th>Vorgang</th><th>Titel</th></tr>
        <#list workItem.reportBeanLinksSet as link>
          <tr>
            <td>${link.linkTypeName}</td>
            <td>${link.linkedItemNo}</td>
            <td>${link.linkedItemTitle}</td>
          </tr>
        </#list>
      </table>
    </#if>

    <!-- Seitenumbruch zwischen Vorgängen -->
    <#if workItem_index < workItems?size - 1>
      <div style="page-break-after: always;"></div>
    </#if>
  </#list>
</#if>

Prüfung auf undefinierte Attribute#

Verwenden Sie ein Makro, um benutzerdefinierte Felder sicher zu prüfen, die möglicherweise nicht definiert sind:

<#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>

<!-- Verwendung -->
<p>Besprechungszeit: <@checkdef "MeetingTime"/></p>
<p>Ort: <@checkdef "MeetingLocation"/></p>