Brand Kit
Das Brand Kit enthält, was alle Dokumente Ihrer Organisation gemeinsam haben: Firmenname, rechtlichen Fußtext, Farben, Schriften und Logos. Vorlagen lesen es, statt es zu wiederholen. Ein neues Logo oder eine geänderte Geschäftsadresse erreicht so jedes Dokument auf einmal, auch veröffentlichte Vorlagen, ohne dass Sie eine einzige neue Version speichern.
Jede Organisation hat genau ein Brand Kit, in jedem Plan. Es gilt für alle Workspaces der Organisation. Das Kit einer neuen Organisation beginnt mit dem Namen der Organisation als Firmenname und sonst nichts.
Einrichten in der App
Öffnen Sie Marke in der Navigation der Organisation. Die Seite hat eine Karte pro Teil des Kits:
| Karte | Was Sie festlegen |
|---|---|
| Identität | Firmenname (bis zu 120 Zeichen) und Rechtlicher Fußtext (Firma, Anschrift, Registernummer, USt-IdNr.; bis zu 2.000 Zeichen). Vorlagen lesen sie als brand.name und brand.legal_footer. |
| Logos | Drei Varianten: Primär (das vollständige Logo auf hellem Grund), Invertiert (für dunklen Grund) und Bildmarke (nur das Symbol, für Kopfzeilen und kleine Flächen). PNG, JPEG, WebP oder SVG bis 512 KB. Ein Logo wird gespeichert, sobald Sie es ablegen oder hochladen, und mit seiner eigenen Schaltfläche entfernt, ohne Brand Kit speichern. |
| Farben | Bis zu 24 benannte Tokens mit je einer Farbe: primary, accent, text, muted … Ein Token besteht aus 1 bis 32 Kleinbuchstaben, Ziffern und Bindestrichen und beginnt mit einem Buchstaben; eine Farbe ist #rgb, #rrggbb oder #rrggbbaa. Jedes Token wird zu brand.colors.<token> und zur CSS-Variable --brand-color-<token>. |
| Typografie | Schrift für Überschriften und Schrift für Fließtext (ein Familienname, bis zu 100 Zeichen) und Grundgröße, eine Zahl mit pt oder px (10pt, 14px). Die Auswahl bietet zuerst die Schriften der Organisation an, dann die Schriften, die jedes Rendering eingebaut hat (Noto Sans, Noto Serif, Liberation Sans, Liberation Serif, DejaVu Sans, DejaVu Serif); Sie können auch jeden anderen Familiennamen eintippen. |
| Vorschau | Ein Beispiel-Briefkopf mit den nicht gespeicherten Werten, so wie eine Vorlage das Kit liest. |
| Standards für neue Vorlagen | Papierformat (A3, A4, A5, A6, Letter, Legal oder Tabloid), Ausrichtung (Hochformat oder Querformat) und die vier Ränder als CSS-Längen in mm, cm, in, px oder pt (20mm). Jeder Wert kann Nicht festgelegt bleiben. |
Brand Kit speichern speichert alles außer den Logos, und die Seite warnt Sie, bevor Sie sie mit nicht gespeicherten Änderungen verlassen.
Inhaber und Admins bearbeiten das Brand Kit, auch die Logos; Editoren und Betrachter sehen es nur. Jede Änderung wird im Audit-Log der Organisation festgehalten.
Papier und Ränder sind nur ein Startpunkt: Eine neue PDF-Vorlage, die Sie in der App mit Neue Vorlage anlegen, beginnt mit ihnen. Beim Rendern werden sie nie angewendet. Eine Vorlage speichert ihre vollständigen Einstellungen, bestehende Vorlagen behalten also ihr eigenes Papier und ihre eigenen Ränder, wenn Sie die Standards ändern, ebenso Vorlagen aus einem Beispiel, einem Import oder der CLI. GET /brand liefert sie als page_defaults.
Die Variable brand
Jede Vorlage sieht das Kit in jeder Sprache als brand:
{
"version": 7,
"name": "Fennlor Studio GmbH",
"colors": { "primary": "#0f766e", "accent": "#f59e0b", "text": "#111827" },
"fonts": { "heading": "Inter", "body": "Source Serif 4" },
"font_size": "10pt",
"logo": {
"primary": "https://cdn.formfeed.dev/a/brand/…/primary-3f9a1c2b7d4e.svg",
"inverse": null,
"mark": null
},
"legal_footer": "Fennlor Studio GmbH · Musterstraße 1 · 12345 Musterstadt · HRB 00000 · USt-IdNr. DE000000000"
}
| Feld | Typ | Bedeutung |
|---|---|---|
version | Integer | Steigt mit jeder Änderung am Kit um eins (auch bei Logos). Ein Kit beginnt bei 1; 0 heißt, es gibt gar kein Kit, wie bei einem lokalen Rendering ohne gepulltes Kit. |
name | String oder null | Firmenname |
colors | Objekt | Ein Eintrag pro Farb-Token, { "primary": "#0f766e" }. Immer ein Objekt, leer, wenn es keine Tokens gibt. |
fonts.heading, fonts.body | String oder null | Die Familiennamen aus Typografie |
font_size | String oder null | Grundgröße, etwa 10pt |
logo.primary, logo.inverse, logo.mark | URL oder null | Öffentliche Adresse jedes Logos im CDN. Eine neue Datei bekommt eine neue Adresse, kein Cache zeigt also ein altes Logo. |
legal_footer | String oder null | Rechtlicher Fußtext |
Nicht gesetzte Werte sind null.
In Jinja2 und Liquid ist brand eine globale Variable, in Handlebars wird es der Wurzel der Daten hinzugefügt. Die Beispiele unten lesen dasselbe Kit in jeder Sprache:
- Jinja2
- Liquid
- Handlebars
<header style="border-bottom: 2px solid {{ brand.colors.primary }}">
{% if brand.logo.primary %}<img
src="{{ brand.logo.primary }}"
alt="{{ brand.name }}"
height="48"
/>{% endif %}
</header>
<h1 style="color: {{ brand.colors.primary | default('#111827') }}">
Rechnung {{ invoice.number }}
</h1>
<header style="border-bottom: 2px solid {{ brand.colors.primary }}">
{% if brand.logo.primary %}<img
src="{{ brand.logo.primary }}"
alt="{{ brand.name }}"
height="48"
/>{% endif %}
</header>
<h1 style="color: {{ brand.colors.primary | default: '#111827' }}">
Rechnung {{ invoice.number }}
</h1>
<header style="border-bottom: 2px solid {{brand.colors.primary}}">
{{#if brand.logo.primary}}<img src="{{brand.logo.primary}}" alt="{{brand.name}}" height="48">{{/if}}
</header>
<h1 style="color: {{default brand.colors.primary "#111827"}}">Rechnung {{invoice.number}}</h1>
Innerhalb von {{#each}} und anderen Blöcken wechselt der Kontext; dort erreichen Sie das Kit mit {{@root.brand.name}}.
Der rechtliche Fußtext gehört in den Tab Fußzeile, dann druckt Chromium ihn auf jede Seite:
<!-- Tab Fußzeile -->
<div style="width: 100%; font-size: 7pt; color: #666; text-align: center;">
{{ brand.legal_footer }} · Seite <span class="pageNumber"></span> von
<span class="totalPages"></span>
</div>
({{brand.legal_footer}} in Handlebars.)
Ihre Daten haben Vorrang. Enthalten die Daten der Anfrage auf oberster Ebene ein Feld brand, sieht die Vorlage dieses Feld und nicht das Kit. Vorlagen, die schon ein brand aus ihren Daten lesen, funktionieren also weiter; benennen Sie das Feld um, wenn Sie das Kit nutzen wollen.
Der Editor bietet brand.* in der Autovervollständigung an, und brand wird nie als Variable gemeldet, die in den Beispieldaten fehlt.
CSS-Variablen
Formfeed fügt das Kit außerdem als CSS Custom Properties ein, nach den Schriften der Organisation und vor dem Druck-Reset. Ihr CSS kann sie also nutzen und trotzdem überschreiben:
:root {
--brand-color-primary: #0f766e; /* eine pro Farb-Token: --brand-color-<token> */
--brand-color-accent: #f59e0b;
--brand-font-heading: 'Inter';
--brand-font-body: 'Source Serif 4';
--brand-font-size: 10pt;
}
Nur gesetzte Werte erzeugen eine Variable. Geben Sie deshalb einen Ersatzwert an, wo einer fehlen kann:
body {
font-family: var(--brand-font-body, 'Helvetica Neue', Arial, sans-serif);
font-size: var(--brand-font-size, 10pt);
}
h1,
h2 {
font-family: var(--brand-font-heading, inherit);
color: var(--brand-color-primary, #111827);
}
.total {
background: var(--brand-color-accent);
}
Mit Tailwind nutzen Sie beliebige Werte: class="bg-[var(--brand-color-primary)] text-white". Das funktioniert in der Vorschau im Editor und im Rendering gleichermaßen.
Schriften. Eine Schrift der Organisation, die das Kit nennt, wird in jedes Rendering eingebettet, das das Kit nutzt, auch wenn die Vorlage nur font-family: var(--brand-font-heading) schreibt. Google Fonts und andere Webfonts brauchen weiterhin ihren <link> im Tab Head; der Familienname allein lädt sie nicht.
Kopf- und Fußzeilen
Die CSS-Variablen stehen auch in Kopf- und Fußzeilen bereit, Inline-Styles wie style="color: var(--brand-color-primary)" funktionieren dort also.
Chromium lädt in Kopf- und Fußzeilen keine externen Bilder. Formfeed bettet die Logos des Brand Kits deshalb für Sie ein: <img src="{{ brand.logo.mark }}"> im Tab Kopfzeile druckt das Logo auf jede Seite. Das gilt nur für die Logo-URLs des Brand Kits; jede andere Bild-URL in einer Kopfzeile bleibt, wie sie ist.
Wie Änderungen Ihre Dokumente erreichen
- Live. Das nächste Rendering verwendet das aktuelle Kit, für Entwürfe und veröffentlichte Vorlagen gleichermaßen. Neu veröffentlichen müssen Sie nichts.
- Innerhalb einer Minute. API-Renderings lesen das Kit über einen Cache von bis zu 60 Sekunden; eine Änderung in der App erreicht sie also innerhalb einer Minute. Der Editor lädt das aktuelle Kit, wenn Sie eine Vorlage öffnen, für die Vorschau und für das echte Rendering.
- Festgehalten. Jedes Rendering hält die Version des Brand Kits, die es verwendet hat, als
brand_versionin seinem Nachweis zur Reproduzierbarkeit fest. So lässt sich später sagen, mit welchem Kit ein Dokument gedruckt wurde. Die Details des Renderings auf der Seite Renderings der App zeigen ihn unter Reproduzierbarkeit; das Render-Objekt der API enthält ihn nicht (es hatengine_version,template_checksumundoutput_sha256, siehe Reproduzierbarkeit). - Deduplizierung berücksichtigt es. Ein Rendering wird nur dann aus dem Cache der Deduplizierung beantwortet, wenn die Version des Brand Kits (und die der geteilten Partials) dieselbe ist wie zuvor; nach einer Änderung rendert die nächste Anfrage neu.
- Nie ohne Kit. Lässt sich das Kit nicht lesen, schlägt die Anfrage mit
500 worker_exhaustedfehl, bevor ein Rendering angelegt ist; sie kostet also nichts, und Sie können sie wiederholen. Ein Dokument wird nie ohne seinen rechtlichen Fußtext gedruckt.
Ad-hoc-html-Renderings mit engine bekommen das Kit ebenfalls, ebenso Word- und PowerPoint-Vorlagen (die keine geteilten Partials bekommen); reines HTML und url-Renderings nicht. Wie Renderings sie verwenden fasst das für die API zusammen.
Wenn Sie ein Logo entfernen, fehlt es ab dem nächsten Rendering: brand.logo.<variant> wird null. Schützen Sie <img>-Tags wie oben mit einem if, damit kein kaputtes Bild erscheint.
Aus Code lesen
GET /brand liefert das Kit so, wie Vorlagen es sehen, dazu page_defaults und updated_at. Bearbeitet wird das Kit nur in der App; die API liest es.
Lokal mit der CLI
Lokale Vorschauen und Renderings fragen das Kit nicht bei der API ab. Laden Sie es einmal ins Projekt:
npx formfeed brand pull
# brand v7 (Fennlor Studio GmbH) -> .formfeed/brand.json
Die Datei enthält, was GET /brand liefert. formfeed dev, formfeed render (aus lokalen Dateien), formfeed test, formfeed ci preview, formfeed renders pull --run und die Helfer von @formfeed/testing rendern mit .formfeed/brand.json als brand; ein laufendes formfeed dev lädt neu, wenn Sie erneut pullen. formfeed validate prüft, dass die Datei gültiges JSON ist. Ohne die Datei rendern Vorlagen mit einem leeren Kit: version 0, keine Farben und alle anderen Werte null. Das unterscheidet sich vom Kit Ihrer Organisation, das mit dem Firmennamen beginnt; pullen Sie also, bevor Sie lokale Ergebnisse mit denen der API vergleichen.
Pullen Sie erneut, nachdem Sie das Kit in der App geändert haben. Ob Sie .formfeed/brand.json committen, entscheiden Sie; committet bleiben Snapshot-Tests in der CI stabil.