Zum Hauptinhalt springen

Von apitemplate.io migrieren

Vorlagen importieren​

In der App: Vorlagen → Importieren → apitemplate.io. Es gibt zwei Wege, Vorlagen zu übernehmen.

Mit API-Schlüssel (viele Vorlagen auf einmal):

  1. Geben Sie den API-Schlüssel aus apitemplate.io (API Integration) und die Region ein, die Ihre Integration aufruft (rest-de.apitemplate.io ist Europa (Frankfurt)). Der Schlüssel wird nur zum Lesen Ihrer Vorlagen verwendet und nie gespeichert.
  2. Vorlagen auflisten zeigt alle Vorlagen des Kontos mit ihrer Gruppe. PDF-Vorlagen sind ausgewählt; filtern Sie nach Name oder Gruppe und wählen Sie mit Angezeigte auswählen oder Angezeigte abwählen eine Auswahl. Bildvorlagen sind Ebenen-Designs ohne HTML und lassen sich nicht importieren.
  3. Analysieren liest HTML, CSS, Einstellungen und Beispiel-JSON jeder ausgewählten Vorlage und prüft sie (siehe unten). Vorlagen, die apitemplate.io nicht liefert, stehen unter Nicht lesbar; kopieren Sie diese aus deren Editor und nutzen Sie Einfügen oder Dateien.
  4. Entwürfe anlegen erstellt je importierter Vorlage eine Jinja2-Vorlage, deren erste Version als Entwurf gespeichert ist (veröffentlicht wird nichts). Ihr Slug ist der Name der Vorlage in Kleinbuchstaben mit Bindestrichen (aus Statement of cost wird statement-of-cost); -2, -3 usw. kommen nur hinzu, wenn der Workspace den Slug schon hat, archivierte Vorlagen eingeschlossen. Der Entwurf merkt sich seine apitemplate.io-ID für die Kompatibilitätsendpunkte. Im Free-Plan, der fünf Vorlagen fasst, hält ein Import an der Grenze an, und der Bericht behält den Rest.

Das JSON aus dem JSON-Tab von apitemplate.io wird zum Datensatz default des Entwurfs, die Vorschau zeigt also sofort Daten. Eine Vorlage mit leerem JSON-Tab startet ohne Daten, und der Bericht prüft dann keine fehlenden Felder. apitemplate.io kennzeichnet den Endpunkt, der die Vorlagenquelle liefert, als experimentell.

Einfügen oder Dateien (eine Vorlage): Fügen Sie ein, was deren Editor zeigt, den HTML-Body, das CSS, das Einstellungs-JSON (Papier, Ränder, Kopf- und Fußzeilenvorlagen) und das Beispiel-JSON, oder legen Sie die exportierten Dateien ab (.html, .css, .json).

Auf beiden Wegen gilt:

  1. Analysieren kompiliert jede Vorlage mit der Jinja2-Engine und prüft sie gegen die Beispieldaten. Der Bericht listet Fehler (unbekannte Filter, von der Engine abgelehnte Syntax), Prüfpunkte (Python-spezifische Konstrukte, Einstellungen ohne Gegenstück, fehlende Beispielschlüssel) und was der Importer abgebildet hat.
  2. Mit apitemplate.io vergleichen (optional): Geben Sie Ihren apitemplate.io-Schlüssel und die apitemplate.io-ID der Vorlage ein, und Original rendern rendert das Original dort mit denselben Beispieldaten, damit Sie deren PDF neben die Editor-Vorschau legen können. Der Schlüssel wird für diesen einen Aufruf verwendet und nie gespeichert.
  3. Entwurf anlegen erstellt eine Jinja2-Vorlage mit den abgebildeten Einstellungen und den Beispieldaten. Prüfen Sie sie im Editor und veröffentlichen Sie sie dann.

Eine so eingefügte Vorlage kennt ihre apitemplate.io-ID nicht; sie reagiert nur auf ihren Slug und ihre Formfeed-ID, auch an den Kompatibilitätsendpunkten.

Mit der CLI​

In einem Vorlagenprojekt legt der Import je Vorlage einen lokalen Vorlagenordner an; prüfen Sie sie mit formfeed dev und führen Sie dann formfeed templates push aus. Mit API-Schlüssel (--key oder APITEMPLATE_API_KEY) wählen Sie die Vorlagen nach ID, nach Gruppe oder alle auf einmal und geben die Region mit --source-region oder APITEMPLATE_REGION an (default, de, us, au, alt, alt-de, alt-us; default, wenn keins von beiden gesetzt ist):

export APITEMPLATE_API_KEY=...
export APITEMPLATE_REGION=de
formfeed import apitemplate --all
formfeed import apitemplate --group Invoices
formfeed import apitemplate --template 3a677b23217dd954 69c77b2365e90a12

Vorlagen mit gleichem Namen erhalten nummerierte Ordner (overview, overview-2); Vorlagen, die apitemplate.io nicht liefert, werden gemeldet und übersprungen. --all und --group nehmen nur die PDF-Vorlagen und überspringen Bildvorlagen mit einem Hinweis. Aus exportierten Dateien (--css, --settings und --sample sind optional; --name ist ohne Angabe der Name der HTML-Datei und --slug einer, der aus dem Namen gebildet wird):

formfeed import apitemplate --name "Invoice" --html body.html --css style.css --settings settings.json --sample sample.json

Zu jeder importierten Vorlage gibt die CLI Fehler, Warnungen und Hinweise aus, denselben Bericht, den die App zeigt.

Einstellungen​

Diese Einstellungen werden auf die Einstellungen der Vorlage abgebildet (Seiteneinrichtung im Editor):

apitemplate.ioFormfeed
paper_size (A3, A4, A5, Letter, Legal, Tabloid, Ledger)paper.format; jede andere Größe wird mit einem Hinweis zu A4
custom_width, custom_heightpaper.width, paper.height
orientationpaper.landscape
margin_top, margin_right, margin_bottom, margin_leftmargin
header_template, footer_template, custom_header, custom_footer, header_left … footer_rightKopf- und Fußzeile (siehe unten)
print_background, scale, page_ranges, prefer_css_page_sizeprintBackground, scale, pageRanges, preferCssPageSize
output_image_type, viewport_width, viewport_height, device_scaleimage.format, image.width, image.height, image.deviceScaleFactor

Eine Einstellung ohne Gegenstück wird verworfen und im Bericht genannt. JPEG- und PNG-Vorlagen werden zu Bildvorlagen. Ränder ohne Einheit ("margin_top": "40") sind Pixel, so wie der Renderer von apitemplate.io sie liest: 40 wird zu 40px (etwa 10,6 mm), nicht zu 40 mm.

Kopf- und Fußzeilen gespeicherter Vorlagen: Markup aus custom_header und custom_footer bleibt erhalten, wenn es etwas anzeigt. Sonst werden die Textfelder header_left, header_center, header_right (und die footer_*-Felder) zu einer Zeile in header_font_size bzw. footer_font_size (9px, wenn keine gesetzt ist). Die Platzhalter {{pageNumber}} oder {{page_number}}, {{totalPages}} oder {{total_pages}}, {{date}}, {{title}} und {{url}} werden wie bisher zu Seitenzahl, Seitenanzahl, Datum, Titel und Adresse. Ein display_header_footer, das falsch ist, lässt Kopf- und Fußzeile weg.

apitemplate.io setzt Kopf- und Fußzeilenvorlagen in 75 % der Seitenbreite und skaliert sie um 4/3 hoch, eine Länge in px fällt dort also ein Drittel größer aus. Der Importer legt das Markup in eine Box, die genauso skaliert, damit ein importierter Logo-Kopf seine Größe behält. Markup, das den Innenabstand der Kopf- oder Fußzeile aufhebt (#header, #footer { padding: 0 }), bekommt in den Einstellungen padding: 0 und läuft wie bisher bis an den Rand.

Das CSS-Feld von apitemplate.io enthält oft <link>- und <script>-Tags (Google Fonts, Icon-Fonts, Diagramm-Bibliotheken). Der Importer verschiebt sie in den Tab Head und übernimmt den Inhalt von <style>-Blöcken als CSS, damit Schriften und Icons wie bisher laden. apitemplate.io füllt das CSS-Feld mit den Daten, Head und CSS von Formfeed sind dagegen statisch: <script>- und <style>-Blöcke mit Template-Syntax (ein Chart-Skript mit "data": {{ values }}) kommen deshalb ans Ende der Vorlage, wo sie gefüllt werden. Eine Liste oder ein Dict wird wie in Python ausgegeben ([1, 2]), wie bei apitemplate.io.

Zeichenketten​

Python-Formatierung von Zeichenketten mit % ("%.2f" % value) hat kein Gegenstück; nutzen Sie "{:.2f}".format(value), number() oder money(). .upper(), .replace(), .split(), .strip() und .format() funktionieren über die Kompatibilitätsschicht, und .format() versteht Pythons Formatangaben einschließlich Tausendertrennzeichen und verschachtelter Felder ("{:,.{}f}".format(value, places)). truncate(length, killwords, end), map(attribute='name') und selectattr('field', 'equalto', value) nehmen ihre Jinja2-Argumente.

Schleifen​

loop.cycle() ist nicht verfügbar; nutzen Sie cycler() oder loop.index % n. Ein {% set %} in einer Schleife, das eine vor der Schleife gesetzte Variable ändert, behält in Nunjucks den neuen Wert nach der Schleife, während Python-Jinja2 ihn verwirft; der Bericht zeigt auf jedes solche set. namespace() funktioniert wie in Jinja2, Zähler wie {% set ns.total = ns.total + 1 %} laufen also unverändert.

Der Import versteckt außerdem die Wrapper-Elemente, die der visuelle Editor von apitemplate.io um Schleifen-Tags legt (Klasse apitemplate-is-content-hidden), mit einer Regel im CSS der Vorlage.

Makros, call-Blöcke, filter-Blöcke und autoescape-Blöcke laufen nach den Regeln von Nunjucks; der Bericht bittet deshalb, ihre Ausgabe zu prüfen. {% import %} und {% from … import %} verweisen auf Dateien, die bei apitemplate.io geblieben sind: Verschieben Sie die Makros in die Vorlage oder in ein Partial.

Tests​

Jinja2-Tests nehmen in Nunjucks Klammern: is divisibleby(2) statt is divisibleby 2, das sich nicht lesen lässt. sequence gibt es nicht; nutzen Sie is iterable. sameas vergleicht mit ===, was für Listen und Objekte der Identitätsprüfung von Jinja2 entspricht. Der Bericht markiert jede Verwendung von divisibleby, sameas, escaped, mapping, sequence und callable, damit Sie sie prüfen können.

Beispieldaten​

Schlüssel, die die Vorlage liest, die aber im Beispiel fehlen, werden gemeldet, damit die Vorschau jeden Pfad zeigt. Der Editor leitet beim Speichern ein Datenschema aus dem Beispiel ab.

Filter​

Formfeed hat Helfer gleichen Namens für qrcode und barcode von apitemplate.io; ihre Optionen sind die von Formfeed, prüfen Sie also jeden Aufruf an der Helfer-Referenz. currency_format ist ein Alias von money(value, currency, locale): Er rendert, und der Editor markiert ihn mit einer Warnung und bietet an, ihn umzubenennen. Einen Filter table gibt es nicht: Eine Vorlage, die ihn verwendet, scheitert, bis Sie die Tabelle als HTML mit einer {% for %}-Schleife schreiben. Jeden Filter, den Formfeed nicht kennt, nennt der Bericht als Fehler.

API​

Stellen Sie Basis-URL und Header um oder nutzen Sie während der Migration die Kompatibilitätsendpunkte:

apitemplate.ioFormfeed
/v2/create-pdf?template_id=…POST /v1/renders mit template
/v2/create-image?template_id=…POST /v1/renders mit template und output: "png" oder "jpg"
/v2/create-pdf-from-htmlPOST /v1/renders mit html und engine: "jinja2"
/v2/create-pdf-from-urlPOST /v1/renders mit url
/v2/list-objectsGET /v1/renders
/v2/delete-objectDELETE /v1/renders/{id}/outputs
X-API-KEY: …Authorization: Bearer … (oder X-API-Key)
Kompatibilitäts-ShimPOST /v1/compat/apitemplate/create-pdf, create-image, create-pdf-from-html und create-pdf-from-url antworten im Format von apitemplate.io

Jede Region von apitemplate.io entspricht https://api-eu.formfeed.dev/v1: Formfeed rendert in Frankfurt und speichert in der EU. api-us.formfeed.dev ist für eine US-Region reserviert, die noch nicht offen ist.

Mit den Kompatibilitätsendpunkten ist eine Migration drei Schritte: Vorlagen mit Ihrem API-Schlüssel importieren, veröffentlichen und die Integration auf https://api-eu.formfeed.dev/v1/compat/apitemplate/… umstellen, mit einem Formfeed-Schlüssel im selben Header X-API-KEY. So in der App importierte Vorlagen reagieren weiter auf ihre template_id von apitemplate.io, die Anfrage bleibt also unverändert; mit formfeed import importierte und aus einem Projekt hochgeladene Vorlagen reagieren nur auf ihren Slug oder ihre Formfeed-ID. Siehe die Kompatibilitätsendpunkte.

Die Post Action S3 Storage von apitemplate.io hat kein Gegenstück in der API, das sich importieren ließe, weil ihre Zugangsdaten apitemplate.io nie verlassen: Verbinden Sie Ihren Bucket stattdessen einmal in den Einstellungen des Workspace (eigener Speicher, ab dem Pro-Plan). Renderings über die Kompatibilitätsendpunkte werden dann dorthin kopiert wie jedes andere Rendering, nur schreibt eines, das aus dem Cache der Deduplizierung beantwortet wird, keine zweite Kopie, und cloud_storage wird ignoriert, weil Formfeed seine eigene Kopie immer für die Aufbewahrungsfrist des Workspace behält.