Output.Rocks bietet spezielle Diagnosefunktionen zur Fehlersuche und Datenanalyse in Templates. Diese Werkzeuge machen die verfügbare oder gezielt ausgewählte Daten sichtbar.

Der Rendervorgang wird abgebrochen wenn Fehler in Syntax oder erwarteten Daten erkannt werden.

Die Fehlermeldungen werden an verschiedenen Stellen angezeigt:

Dump-Funktion

Das spezielle Output.Rocks-Feld dump: zeigt empfangene Daten im generierten Dokument an. Es kann verwendet werden, um den gesamten Datensatz oder Teile davon auszugeben.

Spezifische Objektausgabe:

<<dump:Wert>>

Vollständige Datenausgabe:

<<dump:$root>>

Produktionshinweis: Dump-Felder können große Datenmengen ausgeben und sollten vor der Produktivschaltung entfernt werden. Sie sind ausschließlich für die Template-Entwicklung gedacht.

Vollständige Dump-Struktur

Die Output.Rocks-Datenstruktur folgt der modularen Hierarchie und organisiert verschiedene Datentypen in spezifischen Bereiche.

<<dump:$top>> ist eine gültige alternative Schreibweise für <<dump:$root>>

Ein vollständiger Dump mit <<dump:$root>> zeigt die komplexe Struktur echter Output.Rocks-Daten:

JSON-Payload (Root-Ebene): Das übermittelte JSON-Payload wird mit seinen Objekten und Werten direkt in die Root-Ebene integriert. Im Beispiel sind das die Objekte kunde mit Kundendaten und andere payload-spezifische Daten.

Bilder (Root-Ebene): Im Backend hochgeladene Bilder liegen für Bildmarken mit ihrem Identifier und Pfad direkt in der Root-Ebene. Beispiel: "logoStrom": "[userImage:testclient/104_v1.png]"

Vorlagenkomponenten ('component'-Objekt): Wiederverwendbare Komponenten liegen mit ihrem Identifier im component-Objekt. Diese werden vor dem Template-Rendering vorverarbeitet und stehen dann zur Verfügung.

Standardwerte ('standard'-Objekt): Zentral verwaltete Standardwerte liegen mit ihrem Identifier im standard-Objekt. Diese sind global in allen Templates verfügbar.

System-Metadaten ('or'-Objekt): Das or-Objekt enthält Output.Rocks-spezifische Metadaten wie Client-Informationen.

Template-Referenzen ('template'-Objekt): Teil‑Vorlagen für Lookups liegen mit ihrem Identifier im template‑Objekt und können über <<refLookup:template.identifier>> eingebunden werden.

Erkennbar in der Ausgabe:

  • Bilder: [userImage:pfad/datei.ext] Syntax für Bild-Pfade
  • Gerenderte Komponenten: Komponenten, die eventuell selbst Daten nutzen, liegen bereits berechnet und formatiert vor
  • JSON-Escaping: Zeilenumbrüche als \n, Forward Slashes in HTML-Tags als <\/strong> escaped
  • Unicode-Escaping: Spezialzeichen wie \u2013 für En-Dash (–) und andere Unicode-Zeichen
  • HTML als Text: HTML-Tags wie <MdxStrong> und <MdxA> werden als Textinhalt ausgegeben, nicht als gerenderte Elemente
  • Module: Komponenten in component.*, Standardwerte in standard.* und Template-Pfade für 'refLookup:' in template.*
  • Systemdaten: or.* Felder enthalten Output.Rocks Metadaten

Payload-Werte diagnostizieren

Kunde Name: <<dump:kunde.name>>
Verbrauch: <<dump:verbrauch.kwh_aktuell>>
Adresse komplett: <<dump:kunde.adresse>>

Verwendung: Prüfen Sie einzelne Payload-Werte, um sicherzustellen, dass die erwarteten Daten ankommen und korrekt strukturiert sind.

Kontextbezogene Built-in Variablen

Output.Rocks bietet spezielle Built-in Variablen, die den aktuellen Kontext und die Datenstruktur im Template darstellen. Diese Variablen sind besonders nützlich bei verschachtelten Schleifen und komplexen Datenstrukturen.

Vollständige Datenstruktur:

<<dump:$top>>

Übergeordnete Hierarchie-Ebene:

<<dump:$parent>>

Aktueller Kontext:

<<dump:$this>>
  • $top/$root: Zugriff auf die Root-Ebene aller Daten, unabhängig von der aktuellen Schleifenposition
  • $parent: Zugriff auf die übergeordnete Ebene
  • $this: Repräsentiert das aktuelle Element

Diese Variablen sind besonders nützlich bei verschachtelten Schleifen und komplexen Datenstrukturen.

$this und $parent geben die Daten so aus, wie sie im Dokument zum Diagnosezeitpunkt verstanden werden. Inkorrekte Ausgaben können auf eine fehlerhafte Logik oder Syntax der Kontexterstellung zurückzuführen sein.

Weitere Built-In Variablen:

  • $itemnum: Aktuelle Iterationsnummer (beginnt bei 1)
  • $idx: Index des aktuellen Elements (beginnt bei 0)
  • $size: Gesamtanzahl der Elemente in der aktuellen Schleife
  • $groupKey: Schlüssel der aktuellen Gruppe (bei Gruppierungen)
  • $groupItems: Elemente der aktuellen Gruppe (bei Gruppierungen)

Verschachtelte Datenstrukturen

Bei mehrstufigen Hierarchien ermöglicht $parent Navigation zwischen den Ebenen:

<<rs_gebaeude>>
Gebäude: <<dump:$this.name>> (ID: <<dump:$this.id>>)
<<rs_$this.etagen>>
  Etage <<$this.nummer>>:
  Gebäude-Info via Parent: <<dump:$parent.name>>
  <<rs_$this.raeume>>
    Raum <<$this.nummer>>: <<$this.bezeichnung>>
    Etage via Parent: <<$parent.nummer>>
    Gebäude via Parent-Parent: <<dump:$root.gebaeude.name>>
  <<es_>>
<<es_>>
<<es_>>

Repeating Sections (rs_)

<<rs_verbrauch.zaehlerstaende>>
Eintrag <<$itemnum>> von <<$size>>:
Kompletter Datensatz: <<dump:$this>>
Datum einzeln: <<dump:$this.datum>>
Wert einzeln: <<dump:$this.wert>>
Validierung: <<cs_$this.wert>>Wert vorhanden<<else>>FEHLT!<<es_>>
<<es_>>

<<rs_rechnung.positionen>>
Position <<$itemnum>>:
- Beschreibung: <<dump:$this.beschreibung>>
- Menge: <<dump:$this.menge>>
- Einzelpreis: <<dump:$this.einzelpreis>>
- Parent-Rechnung: <<dump:$parent.nummer>>
<<es_>>

Tabellen-Repeating (rr_)

In Tabellen mit wiederholenden Zeilen sind $this und $parent besonders für die Spaltenlogik relevant:

VertragsnummerVertragstypKunde
<<rr_kunde.vertraege>>
<<dump:$this.nummer>><<dump:$this.typ>><<dump:$parent.nachname>>
<<er_>>

Range Specifiers und anonyme Lookups

Erste drei Zählerstände:
<<rs_zaehlerstaende[F3]>>
Index [<<$idx>>]: <<dump:$this>>
Anonymer Zugriff: <<dump:$current>>
<<es_>>

Alle außer den letzten zwei:
<<rs_zaehlerstaende[0-L2]>>
Position <<$itemnum>>: <<dump:$this.datum>> = <<dump:$this.wert>> kWh
<<es_>>

Gruppierte Daten

Bei Gruppierungen ermöglicht $this Zugriff auf Gruppen-Elemente:

<<rs_kunden:group(kategorie)>>
Kategorie: <<dump:$groupKey>>
<<rs_$groupItems>>
  - Kunde: <<dump:$this.name>> 
  - Gruppe: <<dump:$groupKey>>
  - Verbrauch: <<dump:$this.jahresverbrauch>> kWh
<<es_>>
<<es_>>

Template-Variablen validieren

<<$kunde_vollname=kunde.vorname + ' ' + kunde.nachname>>
<<$verbrauch_differenz=verbrauch.kwh_aktuell - verbrauch.kwh_vorjahr>>
<<$gesamtkosten=tarif.grundpreis * 12 + verbrauch.kwh_aktuell * tarif.arbeitspreis>>

Vollname: <<dump:$kunde_vollname>>
Verbrauchsdifferenz: <<dump:$verbrauch_differenz>>
Gesamtkosten: <<dump:$gesamtkosten>>

Validierung: Prüfen Sie Template-Variablen systematisch, bevor Sie sie in komplexeren Berechnungen verwenden.

Diagnose-Tipp: Verwenden Sie <<dump:$this>> in Schleifen, um den aktuellen Datensatz jeder Iteration zu überprüfen. Dies hilft besonders beim Debugging komplexer verschachtelter Datenstrukturen.

Logik und Null-Werte überprüfen

Defensive Programmierung

1. Logik-Funktionen nutzen:

  • ifBlank() für sichere Standardwerte in Berechnungen
  • isBlank() für präzise Diagnose-Ausgaben
  • map() für lesbare Status-Mappings und Klassifizierungen
  • mapi() für case-insensitive Werte-Zuordnungen

2. Sichere Template-Variablen:

// Statt unsicherer Variablen:
<<$unsicher=kunde.vorname + ' ' + kunde.nachname>>

// Verwende defensive Ansätze:
<<$sicher=ifBlank(kunde.vorname, 'N/A') + ' ' + ifBlank(kunde.nachname, 'N/A')>>

3. Intelligente Fallbacks:

  • Kombiniere map() mit Bedingungen für komplexe Logik
  • Nutze ifBlank() in Schleifen für robuste Array-Verarbeitung
  • Setze aussagekräftige Standardwerte

Diagnose-Anwendung

1. Systematisches Debugging:

// Template-Struktur für robuste Diagnose
========================================
1. <<dump:$top>>                    // Vollständige Daten
2. <<dump:hauptobjekt>>              // Spezifisches Objekt  
3. <<{isBlank(objekt.feld)}>>        // Leerheit-Prüfung
4. <<{ifBlank(objekt.feld, 'LEER')}>> // Sicherer Fallback
5. <<dump:$variablename>>            // Template-Variablen

2. Intelligente Problembehebung:

  • Status-Mapping: <<{map(fehlercode, 'E001', 'Datenfehler', 'E002', 'Verbindungsfehler', 'Unbekannt')}>>
  • Kategorisierung: <<{map(true, isBlank(wert), 'Leer', wert < 0, 'Negativ', 'Normal')}>>
  • Case-insensitive Tests: <<{mapi(status, 'ok', 'Alles gut', 'error', 'Fehler aufgetreten', 'Unbekannt')}>>

3. Kombinierte Logik-Tests:

Komplexe Validierung: <<{map(isBlank(kunde.email) || isBlank(kunde.telefon), 
  true, 'Kontaktdaten unvollständig', 
  'Kontaktdaten vollständig'
)}>>

Cross-Referenz: Weitere Details zu Logik-Funktionen finden Sie in Logik-Funktionen. Kombinieren Sie diese mit Bedingten Abschnitten für maximale Template-Robustheit.

Kritisch: Vergessen Sie niemals, alle <<dump:>> Felder vor der Produktivschaltung zu entfernen. Diese können sensible Daten preisgeben und die Dokumentgenerierung erheblich verlangsamen.

Performance-Hinweis: Verwenden Sie Dump-Funktionen sparsam in großen Templates. Jeder Dump-Aufruf kann die Template-Verarbeitung verlangsamen, besonders bei komplexen Datenstrukturen oder in Schleifen.

Praktische Diagnose-Beispiele

Elektrizitätsversorger-Rechnungsdiagnose

RECHNUNGSDIAGNOSE MIT LOGIK-FUNKTIONEN

Kundendaten prüfen:
Kunde vorhanden: <<{map(isBlank(kunde), true, 'FEHLER', 'JA')}>>
Vollname: <<{ifBlank(kunde.vorname + ' ' + kunde.nachname, 'Unvollständig')}>>
Status: <<{mapi(kunde.status, 'A', 'Aktiv', 'I', 'Inaktiv', 'P', 'Pausiert', 'Unbekannt')}>>
Vollständige Kundendaten: <<dump:kunde>>

Verbrauchsdaten analysieren:
Aktueller Verbrauch: <<{ifBlank(verbrauch.kwh_aktuell, 'FEHLT')}>> kWh
Vorjahresverbrauch: <<{ifBlank(verbrauch.kwh_vorjahr, 'FEHLT')}>> kWh
Verbrauchstyp: <<{map(true, 
  isBlank(verbrauch.kwh_aktuell), 'Keine Daten',
  verbrauch.kwh_aktuell < 1500, 'Niedrig',
  verbrauch.kwh_aktuell < 3500, 'Normal',
  'Hoch'
)}>>
Alle Verbrauchsdaten: <<dump:verbrauch>>

Rechnungsdaten überprüfen:
Rechnungsnummer: <<{ifBlank(rechnung.nummer, 'FEHLT')}>>
Betrag: <<{ifBlank(numFormat(rechnung.betrag, '#,##0.00'), 'FEHLT')}>> €
Status: <<{mapi(rechnung.status, 'OFFEN', 'Zahlung ausstehend', 'BEZAHLT', 'Bezahlt', 'Unbekannt')}>>
Alle Rechnungsdaten: <<dump:rechnung>>

Sichere Template-Variablen:
<<$sicher_differenz=ifBlank(verbrauch.kwh_aktuell, 0) - ifBlank(verbrauch.kwh_vorjahr, 0)>>
<<$sicher_kosten=sicher_differenz * 0.28>>
Sichere Differenz: <<dump:$sicher_differenz>>
Sichere Kosten: <<dump:$sicher_kosten>>

Logik-Funktionen Test:
isBlank(kunde.vorname): <<{isBlank(kunde.vorname)}>>
ifBlank für Fallback: <<{ifBlank(kunde.email, 'keine-email@kunde.de')}>>
map für Status: <<{map(kunde.status, 'A', '✓ Aktiver Kunde', '⚠ Inaktiver Kunde')}>>

Logik-Funktionen Vorteile: ifBlank() verhindert null-Werte in Berechnungen, map() macht Status-Codes lesbar, isBlank() ermöglicht präzise Diagnosen. Das Template ist robuster und produziert auch bei fehlerhaften Daten brauchbare Ausgaben.

Variable Validierung mit Logik-Funktionen

DEFENSIVE VARIABLEN MIT LOGIK-FUNKTIONEN

Sichere Variable Definition:
<<$kunde_name=ifBlank(kunde.vorname, 'Kein Vorname') + ' ' + ifBlank(kunde.nachname, 'Kein Nachname')>>
<<$sicher_jahresverbrauch=ifBlank(verbrauch.kwh_aktuell, 0) * 12>>
<<$sicher_durchschnitt=ifBlank(verbrauch.kwh_aktuell, 0) / 12>>

Variable Dumps:
Name: <<dump:$kunde_name>>
Jahresverbrauch: <<dump:$sicher_jahresverbrauch>>
Durchschnitt: <<dump:$sicher_durchschnitt>>

Intelligente Info-Variable:
<<$info_status={map(isBlank(kunde.vorname) || isBlank(kunde.nachname), true, 'Unvollständig', 'Vollständig')}>>
<<$info_text=kunde_name + ' (' + info_status + ') - ' + sicher_durchschnitt + ' kWh/Monat'>>
Info: <<dump:$info_text>>

Schleifenvariablen mit Fallback:
<<rs_verbrauch.historie>>
Item <<$itemnum>>: <<dump:$this>>
<<$eintrag_jahr=ifBlank($this.jahr, 'Unbekannt')>>
<<$eintrag_kwh=ifBlank($this.kwh, 0)>>
<<$eintrag=eintrag_jahr + ': ' + eintrag_kwh + ' kWh'>>
Eintrag: <<dump:$eintrag>>
<<else>>
FALLBACK: Keine Historie-Daten verfügbar
<<es_>>

Erweiterte Logik-Tests:
Vorname leer: <<{isBlank(kunde.vorname)}>>
Fallback-E-Mail: <<{ifBlank(kunde.email, 'support@energiespar.de')}>>
Verbrauchsklasse: <<{map(true,
  isBlank(verbrauch.kwh_aktuell), 'Keine Daten',
  verbrauch.kwh_aktuell == 0, 'Nullverbrauch',
  verbrauch.kwh_aktuell < 1000, 'Niedrig',
  'Normal/Hoch'
)}>>
Status-Symbol: <<{mapi(kunde.status, 'A', '✓', 'I', '⚠', 'P', '⏸', '?')}>>

Logik-Funktionen Erfolg: Alle Variablen sind robust gesetzt. ifBlank() verhindert null-Werte, map() ermöglicht intelligente Klassifizierung, mapi() macht case-insensitive Status-Mappings. Das Template funktioniert auch bei stark fehlerhaften Daten.

Produktionsvorbereitung

1. Template-Härtung:

  • Ersetze alle direkten Feldverweise durch ifBlank() Aufrufe
  • Nutze map() für alle Status-/Code-Zuordnungen
  • Verwende mapi() bei benutzergenerierten Eingaben

2. Dump-Optimierung:

  • Entferne <<dump:>> Aufrufe vor Produktion
  • Ersetze Diagnose-Ausgaben durch finale Inhalte
  • Behalte defensive Logik-Funktionen bei

3. Performance-Tests:

  • Teste mit leeren/null JSON-Objekten
  • Validiere mit großen Datensätzen
  • Prüfe case-sensitivity bei Mapping-Funktionen

Produktion: <<dump:>> Aufrufe müssen vor der Live-Schaltung entfernt werden.