Word-Vorlagen
Rezepte für Word-Vorlagen
Die Muster stammen aus Vorlagen, die im Betrieb laufen: Zustandsprotokolle, Kistenschilder, Etiketten, Leihverträge. Die Feldnamen sind die eines Beispielprojekts. In Ihrem Projekt heißen die Felder vermutlich anders, der Aufbau bleibt gleich.
Leihvertrag
Ein Vertrag für alle Leihgaben eines Leihgebers. Vor dem Export die Objektauswahl auf diesen Leihgeber
filtern; die Schleife über objects macht daraus ein Dokument.
Leihvertrag zur Ausstellung „{#p.projektname ?? ``#}“, {#p.projektort ?? ``#} Laufzeit der Ausstellung: {#fdate(p.projektbeginn, `T. Monat JJJJ`)#} bis {#fdate(p.projektende, `T. Monat JJJJ`)#} Leihgeber: {#ffmt(objects[0], `Leihgeber`) ?? ``#} Der Leihgeber überlässt {#objects.length#} {#pluralize(`de`, objects.length, { one: `Leihgabe`, other: `Leihgaben` })#}: {# FOR obj IN objects #} {#$idx + 1#}. {#$obj[`RegNr`] ?? ``#}, {#$obj[`Originaltitel`] ?? ``#} Maße: {#ffmt($obj, `Maße`) ?? `k. A.`#} Versicherungswert: {#imask($obj[`Versicherungswert`], f[`Versicherungswert`]) ?? `nach Vereinbarung`#} Kurierbegleitung: {#fcheck($obj[`Kurierbegleitung`], `ja`, `nein`)#} {# END-FOR obj #}
ffmt statt $fmt, weil $fmt in einer Schleife über objects immer das erste Objekt zeigt. Die
Beschriftungen von fcheck stehen fest im Befehl, damit der Vertrag bei jedem Exportierenden gleich
aussieht.
Objektliste als Tabelle
Eine Tabelle mit vier Zeilen: Kopfzeile, eine Zeile nur mit dem Anfang der Schleife, die Datenzeile und eine Zeile nur mit dem Ende der Schleife. Die Datenzeile wiederholt sich dann für jedes Objekt. Die Demo-Vorlage Objektliste ist so aufgebaut.
Zeile 1: Nr. | Abbildung | Objekt | Maße Zeile 2: {# FOR obj IN objects #} (erste Zelle, die übrigen leer) Zeile 3: Zelle 1 {#$idx + 1#} Zelle 2 {# IMAGE img(($obj[`Titelbild`] ?? null), { width: 3 }) #}{#$obj[`Titelbild`] ? `` : `ohne Abbildung`#} Zelle 3 {#$obj[`RegNr`] ?? ``#} {#$obj[`Originaltitel`] ?? ``#} Zelle 4 {#ffmt($obj, `Maße`) ?? ``#} Zeile 4: {# END-FOR obj #} (erste Zelle, die übrigen leer)
FOR und END-FOR stehen in eigenen Zeilen über und unter der Datenzeile. Stehen sie stattdessen in der
ersten und letzten Zelle derselben Zeile, wiederholt die eingebaute Engine nur die Zellen, nicht die Zeile.
Der Rückfall ohne Abbildung in Zelle 2 hat einen Grund: Hat ein Objekt kein Titelbild, bliebe die Zelle
leer, und eine leere Zelle entfernt die Engine. Mit dem Text bleibt sie stehen.
Die Reihenfolge folgt der Sortierung der Ansicht. Wer anders sortieren will, sortiert vorher: {#! liste = _.sortBy(objects, o => o[`RegNr`]) #} und dann FOR obj IN liste.
Zustandsprotokoll
Ein Protokoll je Objekt mit Eingangs- und Ausgangsfotos. Die Fotos sind in Moliri mit den Schlagworten EINGANG und AUSGANG versehen. Am Dokumentanfang entstehen daraus zwei benannte Listen:
{#! eingang = $f.filter(d => d.dateiSchlagworte && d.dateiSchlagworte.split(`,`).map(s => s.trim()).includes(`EINGANG`)).sort((a, b) => (a.dateiText ?? ``).localeCompare(b.dateiText ?? ``)) #} {#! ausgang = $f.filter(d => d.dateiSchlagworte && d.dateiSchlagworte.split(`,`).map(s => s.trim()).includes(`AUSGANG`)).sort((a, b) => (a.dateiText ?? ``).localeCompare(b.dateiText ?? ``)) #} Zustandsprotokoll {#$o[`RegNr`] ?? ``#}, {#$o[`Originaltitel`] ?? ``#} Eingang: {#fdate($o[`Eingangsdatum`]) ?? `offen`#} Rückgabe: {#fdate($o[`Rückgabedatum`]) ?? `offen`#} Zustand bei Eingang: {#$o[`Zustand Eingang`] ?? ``#} {# FOR i IN _.range(0, Math.max(eingang.length, ausgang.length)) #} {# IMAGE img(eingang[$i] ?? null, { width: 8 }) #} {# IMAGE img(ausgang[$i] ?? null, { width: 8 }) #} Abb. {#(($i+1)*2)-1#} {#eingang[$i]?.dateiText ?? ``#} Abb. {#($i+1)*2#} {#ausgang[$i]?.dateiText ?? ``#} {# END-FOR i #}
Das map(s => s.trim()) ist wichtig. Sonst scheitert der Vergleich an einem Leerzeichen nach dem Komma. ?. und ?? null fangen ab, dass eine Liste kürzer ist als die andere. Das Protokoll verwendet nur $o und $f, es entsteht also ein Dokument je Objekt. Als Abschnittsverhalten passt Abschnittsumbruch (neue Seite).
Im Vorlagen-Editor fügt Erweitert, Zwei Bildlisten nebeneinander dieses Muster mit wählbaren Schlagworten ein.
Maßzeile mit Rückfällen
Hat das Maßfeld einen Ausgabe-Formatter, genügt {#ffmt($o, `Maße`)#} mit Rückfall. Sonst drei verbreitete
Varianten mit Einzelfeldern, von einfach nach robust:
… einfach, leere Werte verschwinden: {#$o[`Hoehe`] ?? ``#} x {#$o[`Breite`] ?? ``#} x {#$o[`Tiefe`] ?? ``#} cm … mit Strich für fehlende Werte und optionaler Tiefe: {#$o[`Breite`] ? imask($o[`Breite`], FLOAT_FORMAT)+` cm` : `-`#}{#$o[`Tiefe`] ? ` x `+imask($o[`Tiefe`], FLOAT_FORMAT)+` cm` : ``#} … nur vorhandene Werte verbinden, Einheit nur wenn etwas dasteht: {#combine([parseFloat($o[`Hoehe`]), parseFloat($o[`Breite`]), parseFloat($o[`Tiefe`])].filter(Boolean).join(` x `), { post: ` cm` })#}
Dasselbe Muster filter(Boolean).join eignet sich für Namens- und Standortzeilen:
{#[$o[`Kuenstler_Vorname`], $o[`Kuenstler_Zuname`]].filter(Boolean).join(` `)#} {#[$o[`Standort`], $o[`RaumNr`], $o[`Wand_Nr`], $o[`Vitrinen_Nr`]].filter(Boolean).join(` / `)#}
Ein Zahlenformat einmal definieren
Am Dokumentanfang, danach überall als imask($o[`Feld`], FLOAT_FORMAT) verwendbar:
{#! FLOAT_FORMAT = { "mask": "Number", "scale": "2", "thousandsSeparator": " ", "radix": "," }#}
Gruppierung: je Raum eine Überschrift
{#! gruppen = _.groupBy(objects, o => o[`RaumNr`] ?? `ohne Raum`) #} {# FOR key IN Object.keys(gruppen) #} Raum {# $key #} {# FOR obj IN gruppen[$key] #} {# $obj[`RegNr`] ?? `` #}, {# $obj[`Originaltitel`] ?? `` #} {# END-FOR obj #} {# END-FOR key #}
gruppen entsteht aus objects, und die Schleife läuft über gruppen. Moliri erkennt das als Schleife
über die Objekte und erzeugt ein Dokument.
Bilder je Objekt in einem Bericht für alle
{# FOR obj IN objects #} {# INS $obj[`RegNr`] ?? `` #} {# FOR file IN files[$obj.objektID] #} {# IF [`image`, `image_other`, `svg`].includes($file.dateiArt) #} {# IMAGE img($file, { width: 6 }) #} {# END-IF #} {# END-FOR file #} {# END-FOR obj #}
$f folgt nicht der inneren Objektschleife. Innerhalb von FOR obj IN objects heißt es files[$obj.objektID].
Anzahl mit richtiger Pluralform
{#objects.length#} {#pluralize(`de`, objects.length, { one: `Objekt`, other: `Objekte` })#}
objects.length funktioniert auch in einer Vorlage je Objekt und ändert deren Modus nicht.
Verweis zurück in die Anwendung
Aus dem Bericht direkt in den Bildvergleich springen, im Zustandsprotokoll oben innerhalb der Schleife:
{# LINK ({ url: `https://beispiel.moliri.app/p/${p.projektID}/o/${$o.objektID}/compare?left=${eingang[$i] ? eingang[$i].dateiID : null}&right=${ausgang[$i] ? ausgang[$i].dateiID : null}`, label: `Vergleich öffnen` }) #}
p.projektID und $o.objektID machen den Verweis je Objekt richtig. Die Adresse der eigenen Instanz
steht an Stelle von beispiel.moliri.app.
Ereignisse ausgeben
{# FOR ev IN $e #} {# IF $ev.art === `ausstellung` #} {# INS $ev.titel #}{# INS combine($ev.rolle, { pre: ` (Kat. `, post: `)` }) #}, {#fdate($ev.von, `JJJJ`)#} {# END-IF #} {# END-FOR ev #}
Schalterfeld ausgeben
Kurierbegleitung: {#fcheck($o[`Kurierbegleitung`], `Ja`, `Nein`)#}
Die feste Beschriftung ist die sichere Wahl für Dokumente, die archiviert werden. Ohne die beiden Argumente kommen die Werte aus den Ansichtseinstellungen des Exportierenden, und das Dokument sieht bei jedem anders aus.
Ein Feld sichtbar machen
Wenn ein Feld nur so verwendet wird, dass Moliri es nicht erkennt (etwa als Zeichenkette in _.groupBy(objects, `Leihgeber`)), wird es nicht geladen. Eine nie ausgeführte Bedingung macht es
sichtbar:
{# IF false #} {# INS $o[`Leihgeber`] ?? `` #} {# END-IF #}
Häufige Stolperfallen
- In Schleifen immer
$file,$obj,$ev,$ischreiben, nie ohne das Dollarzeichen. - Backticks statt gerader Anführungszeichen.
- Bei verschachtelten Objektschleifen nicht annehmen,
$fzeige auf das innere Objekt. - In Schleifen
ffmt($obj, …)statt$fmt[…]. - Beim verschachtelten Zugriff
?.statt.verwenden. - Für komplexe Logik lieber einen vorbereitenden Befehl am Dokumentanfang als verschachtelte Einzeiler.
Weiterlesen
- Vorlagen-Funktionen : alle zehn Hilfen
- Vorlagen-Variablen : der Datenkontext
- Word-Vorlage erstellen : der Einstieg