Worum es geht
Ein Bericht braucht oft Bilder: das Logo des Kunden, eine Unterschrift, Fotos einer Begehung, ein Diagramm. CRMS lädt nie etwas aus dem Netz oder vom Dateisystem nach. Ein Bild kommt auf genau einem von drei Wegen ins Dokument.
Die drei Wege
| Asset | Anhang | SVG | |
|---|---|---|---|
| Gehört zu | der Revision der Vorlage | der einen Anfrage | der Payload, als Text |
| In der Vorlage | asset:<name> | attachment:<name> | ${crms.svg(feld)} |
| Erlaubte Arten | was die Vorlage freigegeben hat, z. B. Logo, Schrift | image/png, image/jpeg | SVG innerhalb der Erlaubnisliste |
| Formate | HTML, PDF, DOCX | nur PDF | HTML, PDF, DOCX |
| Bei FINAL | ja | nein | ja |
Assets lädst du mit der Vorlage hoch, siehe Wie eine Vorlage aufgebaut ist. Die beiden Namensräume asset: und attachment: bleiben getrennt. Ein Anhang kann ein Asset der freigegebenen Revision nie ersetzen, auch nicht bei gleichem Namen.
Anhänge: Bilder dieser einen Anfrage
Ein Anhang ist ein Bild, das nur für diesen Aufruf existiert. Welches Bild die Vorlage zeigt, bestimmt meist die Payload: Die Vorlage schreibt <img src="attachment:${signature}"/>, und du schreibst den Namen in die Payload.
POST /crms/render
Content-Type: application/json
Content-Encoding: gzip
{
"template": "inspection-report",
"format": "PDF",
"mode": "TRANSIENT",
"data": { "signature": "signature-inspector.png" },
"attachments": [
{ "name": "signature-inspector.png",
"contentType": "image/png",
"content": "iVBORw0KGgo…" }
]
}HTTP 200
Content-Type: application/pdf
%PDF-1.7 … ← die Unterschrift steht im PDFÜber REST kommt jeder Anhang mit name, contentType und content in Base64. Base64 macht die Daten um ein Drittel größer. Mit Content-Encoding: gzip holst du das fast ganz zurück, crms-client packt Anfragen mit Anhängen von selbst. Eingebettet gibst du die Bytes direkt als RenderAttachment mit.
CRMS prüft die Anhänge zusammen mit der Payload und meldet alle Verstöße in einer Antwort (422 payload-rejected). Das Feld heißt attachments[<i>], die Stelle in der Liste, oder attachments bei einer Grenze.
| Regel | Wann |
|---|---|
attachments-too-many|<max> | mehr Anhänge als erlaubt (Standard 200, CODAMAI_CRMS_ATTACHMENTS_MAX_COUNT) |
attachments-too-large|<max> | zusammen größer als erlaubt (Standard 50 MiB, CODAMAI_CRMS_ATTACHMENTS_MAX_BYTES) |
name-invalid | kein einfacher Dateiname: erlaubt sind Buchstaben, Ziffern, ., _, -, höchstens 128 Zeichen, nicht mit . am Anfang |
name-duplicate | ein früherer Anhang dieser Anfrage hat schon denselben Namen |
type-not-allowed | nicht image/png und nicht image/jpeg |
empty | keine Bytes |
content-mismatch | die Bytes beginnen nicht wie eine PNG- oder JPEG-Datei, so wie angegeben |
Über einer Grenze schaut CRMS die einzelnen Anhänge nicht mehr an.
| Anhänge dabei? | Modus | Format | Ergebnis |
|---|---|---|---|
| nein | – | – | keine Prüfung der Anhänge |
| ja | FINAL | – | 422 attachments-not-for-final |
| ja | PREVIEW oder TRANSIENT | HTML, DOCX, XLSX, CSV, ODS | 422 attachments-not-for-format|<format> |
| ja | PREVIEW oder TRANSIENT | Anhänge werden geprüft und gezeichnet |
Nennt die Vorlage ein attachment:<name>, das die Anfrage nicht mitbringt, scheitert das PDF mit render-resource-refused. Ein Dokument mit Lücken, wo Bilder sein sollten, gibt CRMS nicht heraus.
SVG aus der Payload: crms.svg
Ein Diagramm, das deine Anwendung selbst zeichnet, etwa eine Topologie, schickst du als SVG-Text in der Payload. Normalerweise schreibt eine Vorlage Text aus der Payload immer als Text, nie als Markup: ${diagram} zeigt die spitzen Klammern. Ins Dokument als Grafik kommt es nur über die Funktion crms.svg, die jede Vorlage hat:
<div class="figure">${crms.svg(diagram)}</div>
crms gehört CRMS. Ein Payload-Feld mit dem Namen crms ersetzt die Funktion nicht.
CRMS liest das SVG als XML, ohne DTD und ohne Entities außer den fünf vordefinierten, und prüft es gegen eine Erlaubnisliste:
| Was | Erlaubt | Nicht erlaubt |
|---|---|---|
| Wurzel | <svg> im SVG-Namensraum | alles andere |
| Elemente | svg, g, defs, symbol, use, path, rect, circle, ellipse, line, polyline, polygon, text, tspan, textPath, linearGradient, radialGradient, stop, marker, clipPath, title, desc, style | unter anderem script, foreignObject, image, a, Animationen, filter, metadata |
| Attribute | Geometrie, Farbe und Strich, Text, Verläufe, Marker, id, class, style, aria-*, dazu xlink:href, xml:space, xml:lang | jedes on…-Attribut, Attribute aus anderen Namensräumen |
| Verweise | nur auf eine Stelle im selben SVG: href="#id", url(#id) | jede Adresse nach außen |
| CSS | in style-Attributen und <style> | @import, CSS-Escapes mit \ |
Eine XML-Deklaration am Anfang entfernt CRMS. Der Rest geht genau so ins Dokument, wie er geprüft wurde. Ist etwas nicht erlaubt, scheitert das Rendern mit 422 template-svg-rejected. CRMS putzt nichts heraus, denn ein Diagramm mit still entfernten Teilen wäre ein falsches Diagramm. Auch ein Wert, der kein Text ist, etwa eine Zahl, ist template-svg-rejected.
| Ausgabetyp | Was crms.svg daraus macht |
|---|---|
DOCUMENT | HTML zeigt das SVG inline. PDF zeichnet es als Vektorgrafik, ohne Skripte und ohne externe Ressourcen. Kann es nicht gezeichnet werden, ist das render-pdf-failed |
WORD | Die Funktion schreibt einen Platzhalter, der dort stehen muss, wo in Word ein Textlauf steht, also in einem <w:p>. CRMS prüft das SVG noch einmal, rechnet es in ein PNG um und setzt es als Bild in der angegebenen Größe ein. Der <title> des SVG wird zur Bildbeschreibung |
TABLE | abgelehnt: template-svg-not-for-output-type|table |
Für DOCX liest CRMS die Größe aus width und height der Wurzel (px, pt, pc, mm, cm, in). Fehlen sie, nimmt es die viewBox, sonst 300 × 150 Pixel. Das PNG hat die doppelte Pixelzahl, damit es im Druck scharf bleibt, höchstens 4096 Pixel je Seite.