Um Events aus co*pilot exportieren zu können, wurde ein flexibler Event Export geschaffen. Export werden auf Basis von Export-Konfigurationen durchgeführt. In einer solchen Export-Konfiguration wird festgelegt, welche Daten eines Events in welchem Format ausgespielt werden.
Über den Unterpunkt „Exporte“ des Event-Menus können im Anschluss Events selektiert und exportiert werden. Zudem lassen sich einzelne Events auch über die Event-Detail-Seite exportieren.
Export-Konfiguration
Beim Anlegen einer neuen Export-Konfiguration in den Einstellungen werden folgende Felder belegt:

(1) Name
Name der Konfiguration
(2) Format
- Markdown
- CSV
Markdown
Markdown ist eine sehr einfache Seitenbeschreibungssprache um Text zu formatieren. Dieses Format eignet sich sehr gut, um Detailseiten auszugeben.
Ein Markdown-Export kann als Word oder PDF File ausgegeben werden.
- https://markdown.de/
- Markdown Editor
CSV
CSV ist ein gängiges Format um Informationen tabellarisch darzustellen. Hierbei werden Spalten mittels Komma oder Semikolon separiert.
- https://de.wikipedia.org/wiki/CSV_(Dateiformat)
(3) Vorlage
Die Vorlage wird in der Templating Language Handlebars verfasst. Auf Basis dieser Vorlage und den Input-Daten wird die Ausgabe generiert. Daten werden mittels Platzhalter (= „Handlebars Expressions“) übergeben, die in „{{ }}“ eingeschlossen sind.
(4) Perspektive
Perspektive auswählen um Events für die Vorschau zu laden.
(5) Vorschau
Vorschau der Ausgabe
(4) Default Vorlagen
Hinterlegte Default Vorlagen laden.
Input-Daten
Aktuell steht die Liste an Events in der Vorlage zur Verfügung. Das können die selektierten Events auf der Export-Seite sein, alle Events, die eine Perspektive zurückliefert oder auch nur ein einzelnes Event, wenn ein Export von einer Event-Detail-Seite aus gestartet wird.
{
events: Event[]
}
Event
export interface EventExportPayload {
slug: string
status: string
optionEnd?: Date
kind: string
start: Date
name: string
subTitle?: string
eventType: string
memo?: string
createdAt: Date
updatedAt: Date
displayNames: {
eventTitleWithArtists: string
eventTitleWithArtistsAndShows: string
artists: string
artistsAndShows: string
rooms: string
locationsWithRooms: string
locationsWithCityAndRooms: string
}
images?: EventExportPayloadImage[]
files?: EventExportPayloadFile[]
links?: EventExportPayloadLink[]
locations?: {
name: string
address: {
street: string
addStreet: string
zip: string
city: string
country: string
lat: string
lng: string
}
operator?: {
displayName: string
email: string
phone: string
}
rooms?: {
name: string
images?: EventExportPayloadImage[]
files?: EventExportPayloadFile[]
}[]
}[]
artists?: {
name: string
description: string
show?: {
slug: string
name: string
releasesAt?: Date
memo?: string
images?: ArtistExportPayloadImage[]
files?: ArtistExportPayloadFile[]
artistShowInformations?: (Information | undefined)[]
}
contacts?: {
role: string
displayName: string
address: {
street: string
addStreet: string
zip: string
city: string
country: string
lat: string
lng: string
}
email: string
phone: string
}[]
images?: EventExportPayloadImage[]
files?: EventExportPayloadFile[]
links?: EventExportPayloadLink[]
artistInformations?: (Information | undefined)[]
}[]
contacts?: {
role: string
displayName: string
address: {
street: string
addStreet: string
zip: string
city: string
country: string
lat: string
lng: string
}
email: string
phone: string
}[]
schedule?: {
name: string
date: Date
}[]
eventInformations?: (Information | undefined)[]
offersOnEvent?: {
offerStatus: string
name: string
description: string
discount: number
roomsOnOffer?: {
room: string
description: string
price: number
discount: number
vat: number
sum: number
}[]
resourcesOnOffer?: {
resource: string
description: string
amount: number
unit: string
price: number
discount: number
vat: number
sum: number
}[]
}[]
ticketing?: {
ticketOffice: string
contingent: number
price: number
timestamp: Date
soldTickets: number
saleTotal: number
}[]
}
export type EventExportPayloadImage = {
name: string
description: string
tags: string[]
sizes: Record<string, string>
}
export type EventExportPayloadFile = {
name: string
description: string
path: string
preview: string
download: string
tags: string[]
}
export type EventExportPayloadLink = {
type: string
value: string
}
Helper-Funktionen
Standard
Folgend ein Auszug der zur Verfügung stehenden Standar-Helper. Siehe https://handlebarsjs.com/guide/builtin-helpers.html für weitere und Details.
each
Die each Funktion iteriert (Schleife) über ein angegebenes Array. Sie beginnt immer mit {{#each}} und endet mit {{/each}}
Sie verlangt das Array als Parameter.
Beispiel
Eine Schleife über alle events. Die Daten eines Events müssen dann mit this.* angesprochen werden
{{#each events}}
# {{{this.name}}}
Datum: {{formatDate this.start "P"}}
{{/each }}
if
Die if Funktion überprüft, ob ein Element vorhanden ist. Sie beginnt immer mit {{#if}} und endet mit {{/if}}
Sie verlangt das zu prüfende Element als Parameter.
Beispiel
Alle Event Informationen ausgeben, sofern ein Wert gesetzt ist:
{{#each this.eventInformations}}
{{#if this.value}}
### {{ this.name }}
{{ this.value }}
{{/if}}
{{/each}}
lookup
Funktion, um Elemente aus einem Objekt zu extrahieren.
Die Funktion verlangt 2 Parameter:
- Ein Objekt, z.B. einen Kontakt
- den Namen des Elements
Beispiel
{{ lookup (contactByRole this.contacts "Mieter") "displayName" }}
Custom
formatDate
Funktion um Datum und Uhrzeit spezifisch auszugeben.
Die Funktion verlangt 2 Parameter:
- das Datum (Date ISO)
- das Datumsformat im Unicode Technical Standard
https://date-fns.org/v2.9.0/docs/format
Beispiel
{{ formatDate this.start "P" }}
=> Ausgabe: deutsches Datum, z.B. 03.08.2022
{{ formatDate this.start "E P" }}
=> Ausgabe: deutsches Datum mit Wochentag,
z.B. Mi. 03.08.2022
{{ formatDate this.start "p" }}
=> Ausgabe: Uhrzeit, z.B. 20:00
{{ formatDate this.start "Pp" }}
=> Ausgabe: Datum mit Uhrzeit, z.B. 20.11.2021 20:00
contactByRole
Funktion, um einen Kontakt aus einem Array anhand seiner Rolle zu extrahieren.
Die Funktion verlangt 2 Parameter:
- Ein Array mit Kontakten
- Den Namen der Rolle
Beispiel
{{#each (contactByRole this.contacts "Veranstalter:in")}}
{{@key}}: {{this}}
{{/each}}
=> Ausgabe
role: Veranstalter:in
displayName: ABC Firma
email: info@abc.de
phone: +030 8877665
{{ lookup (contactByRole this.contacts "Veranstalter:in") "displayName" }}
=> Ausgabe: ABC Firma
scheduleValueByName
Funktion, um einen Schedule-Eintrag anhand des Namens zu extrahieren.
Die Funktion hat 3 Parameter:
- Den Schedule
- Den Namen des Schedule-Eintrags
- Datum einblenden (optional): default true, auf false setzen um nur Uhrzeit anzuzeigen
Beispiel
{{ scheduleValueByName this.schedule "Curfew" }}
=> Ausgabe
20.09.2023 22:00
{{ scheduleValueByName this.schedule "Curfew" false }}
=> Ausgabe
22:00
linkByType
Funktion, um einen Eintrag der Links anhand des Typs zu extrahieren.
Die Funktion verlangt 2 Parameter:
- Die Links
- Den Typ des Eintrags (z.B. Web, Facebook)
{{ linkByType @root.baseData.links "Web" }}
eventInformationByName
Funktion, um einen Eintrag der Event Informationen anhand des Namens zu extrahieren.
Die Funktion verlangt 2 Parameter:
- Die Event Informationen
- Den Namen des Eintrags
{{ eventInformationByName this.eventInformations "Hotel" }}
Beispiele
Einfaches Markdown Beispiel
{{#each events}}
# {{this.name}}
Type: {{this.eventType}}
Status: {{this.status}}
Datum: {{ formatDate this.start "P" }} | {{ formatDate this.start "p" }} Uhr
Name: {{this.displayNames.eventTitleWithArtistsAndShows}}
Ort: {{this.displayNames.locationsWithRooms}}
{{/each}}
Einfaches CSV Beispiel
Status;Datum;Titel
{{#each events}}
{{this.status}};{{formatDate this.start "P"}};{{{this.name}}}
{{/each }}
VVK-Zahlen
# Verkäufe
Event: {{this.name}} | {{ formatDate this.start "P" }}
Location: {{this.displayNames.locationsWithRooms}}
{{#if this.ticketing}}
## Tickets
<table>
<thead>
<tr>
<th>VVK-Stelle</th>
<th>Kategory</th>
<th>Ticketpreis (brutto)</th>
<th>Verkauft</th>
<th>Kontingent</th>
<th>Gesamt (brutto)</th>
</tr>
</thead>
<tbody>
{{#each this.ticketing}}
<tr>
<td>{{ this.ticketOffice }}</td>
<td>{{ this.category }}</td>
<td>{{ formatEuro this.grossPrice }}</td>
<td>{{ this.soldTickets }}</td>
<td>{{ this.contingent }}</td>
<td>{{ formatEuro this.saleTotal }}</td>
</tr>
{{/each}}
<tr>
<th>Summe</th>
<th></th>
<th></th>
<th>{{ sumBy this.ticketing "soldTickets" }}</th>
<th>{{ sumBy this.ticketing "contingent" }}</th>
<th>{{ formatEuro (sumBy this.ticketing "saleTotal" ) }}</th>
</tr>
</tbody>
</table>
{{/if}}

Event-Informationen
Alle Event-Informationen außer „Gästeliste“ auflisten.
## Event Informationen
{{#each this.eventInformations}}
{{#unless (isEqual name "Gästeliste")}}
### {{this.name}}
{{this.value}}
{{/unless}}
{{/each}}
Artist-Tabelle mit Bilder
## Artists
<table class="artistTable">
<thead>
<tr>
<th>Pic</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{{#each this.artists}}
<tr>
<td><img src="{{ lookup this.images.0.sizes "640" }}" /></td>
<td>
<h3>{{ this.name }}</h3>
<p>{{ this.description }}</p>
</td>
</tr>
{{/each}}
</tbody>
</table>
Dateien verlinken
## Dateien
{{#each this.files}}
### {{this.name}}
<a href="{{this.path}}">{{this.path}}</a>
{{/each}}
Anmerkung: Nur als „öffentlich“ gekennzeichnete Dateien können im Export eingebunden werden. „Öffentlich“ bedeutet hierbei lediglich, dass eine Datei ohne Login verfügbar wird. Ohne die URL bzw. konkreter die zufallsgenerierte ID besteht aber trotzdem keine Zugriffsmöglichkeit. D.h. es können durchaus Dateien wie Tech Rider auf öffentlich gesetzt und somit in einen Export eingebunden werden.
Tipps
Bedingte Darstellung
Um eine Sektion nur anzuzeigen, wenn das entsprechende Feld gesetzt ist, kann sie mit einem #if Block-Helper umschlossen werden:
{{#if (eventInformationByName this.eventInformations "Hotel")}}
### Hotel
{{eventInformationByName this.eventInformations "Hotel"}}
{{/if}}
Seitenumbruch
Für PDF-Exporte können Seitenumbrüche eingefügt werden. Bei Word-Exporten hat das allerdings keinen Effekt.
Inhalt vor dem Seitenumbruch
{{pagebreak}}
Inhalt nach dem Seitenumbruch
Die Leerzeile vor {{pagebreak}}
ist notwendig.
Styling
Styling von Exporten ist via CSS möglich. Globale Stile können ganz am Anfang einer Exportvorlage in einem Style-Tag angegeben werden:
<style>
...
</style>
Alternativ sind auch Inline-Stile auf z.B. einzelnen Absätzen oder Paragraphen anwendbar. Hierfür muss die entsprechende Passage dann allerdings in HTML statt Markdown geschrieben werden:
<p style="...">...</p>
Schriften
Folgende Schriftarten stehen zur Verfügung:

Beispiel: Überschriften mit Serifen, Absätze serifenlos
<style>
h1, h2, h3, h4 {
font-family: DM Serif Display;
}
body, p, th, td {
font-family: Ubuntu;
}
</style>
# Globale Stile
Ein Absatz
- eine
- Liste
## Tabelle
| Spalte A | Spalte B | Spalte C |
| -------- | -------- | -------- |
| A1 | B1 | B3 |
| A2 | B | B4 |

Beispiel: Einzelner Absatz in anderer Schriftart
Erster Absatz
<p style="font-family: Indie Flower">Zweiter Absatz</p>

Weitere Möglichkeiten
<p style="color: blue">blau</p>
<p style="color: blue; font-weight: bold;">blau & fettgedruckt</p>
<mark>highlighted</mark>
<p style="text-decoration: underline;">unterstrichen</p>
