# Zusammengesetzte Seiten

> Das Markdown zusammengesetzter Seiten: die Seitenbegrenzung aus vier Doppelpunkten, die eine Seitenvorlage nennt, Rahmen und das Attribut slot, die Inhalt in die Rahmen der Vorlage schicken, Abbildungen mit Beschriftungen an den Ankern eines Bilds und die Warnungen, die den Inhalt mit der Vorlage abgleichen

- HTML-Fassung: https://postext.dev/de/docs/composed-pages
- Zuletzt aktualisiert: 2026-10-16
- Lesezeit: 9 min
- Andere Sprachen: [en](https://postext.dev/en/docs/composed-pages.md), [es](https://postext.dev/es/docs/composed-pages.md), [ca](https://postext.dev/ca/docs/composed-pages.md), [fr](https://postext.dev/fr/docs/composed-pages.md), [it](https://postext.dev/it/docs/composed-pages.md), [pt](https://postext.dev/pt/docs/composed-pages.md), [zh](https://postext.dev/zh/docs/composed-pages.md), [ja](https://postext.dev/ja/docs/composed-pages.md), [ar](https://postext.dev/ar/docs/composed-pages.md)

## Kurz gesagt

Manche Seiten bestehen nicht aus einer Spalte Fließtext, sondern aus mehreren Feldern, so wie eine Schulbuchseite mit einem Titelband, einem Text und drei farbigen Kästen mit Fotos. Postext nennt sie zusammengesetzte Seiten. Die Form der Seite ist eine Vorlage in der Konfiguration, und das Markdown sagt nur, welches Stück Text in welches Feld gehört. Diese Seite zeigt, wie Sie dieses Markdown schreiben: die Seitenbegrenzung, die Rahmen, die Slot-Namen und Bilder mit Beschriftungen wie den Namen auf einer Landkarte. Sie führt außerdem die Warnungen auf, die Postext ausgibt, wenn Text und Vorlage nicht zusammenpassen.

**Die Vorlage bestimmt die Form der Seite; das Markdown liefert den Inhalt und sagt, in welchen Rahmen jedes Stück kommt.**

Eine zusammengesetzte Seite wird nach einer Vorlage umbrochen: benannte Rahmen (ein Titelband, ein Text, ein Kasten mit seinem Foto), Gruppen, die sich gemeinsam verschieben, und ein Dekor, alles in der Konfiguration unter `pageTemplates` festgelegt. Das Markdown der Seite ist ein abgegrenzter Block, der seine Vorlage nennt und den Inhalt über die Namen auf die Rahmen verteilt. Im Markdown stehen nie Positionen oder Größen, und in der Konfiguration steht nie Inhaltstext; eine Übersetzung ist deshalb dieselbe Vorlage mit anderen Wörtern.

Diese Seite behandelt das Markdown und wie die Seite daraus gesetzt wird. Die Vorlage selbst (ihre Rahmen, Größen, Stile und ihr Dekor) beschreibt [Konfiguration › Zusammengesetzte Seiten](https://postext.dev/de/docs/configuration-composed-pages.md). Ein Dokument ohne zusammengesetzte Seiten wird genau wie zuvor umbrochen.

## Die Seitenbegrenzung

```md
::::page{template="tema-cajas" fondo="banda-retos"}
# La actividad económica y el dinero

Las personas utilizan :chip[recursos]{style="clave"} que se obtienen de la naturaleza…
::::
```

Eine zusammengesetzte Seite beginnt mit einer Zeile aus **vier Doppelpunkten**, gefolgt von `page` und den Attributen, und endet mit einer Zeile, die nur **ebenso viele Doppelpunkte** enthält. Darin öffnen und schließen sich Container mit drei Doppelpunkten (`:::frame`, `:::callout`, `:::figure`, `:::columns`, `:::paper`) wie immer; ein bloßes `:::` schließt also den innersten von ihnen und nie die Seite. Eine Seite mit fünf Doppelpunkten (`:::::page`) endet mit fünf; eine Zeile aus vier Doppelpunkten ist darin dann gewöhnlicher Text.

| Attribut | Wirkung |
| --- | --- |
| `template="…"` | Pflicht. Die ID eines Eintrags von `pageTemplates`. |
| `spread` | Die Seite ist eine Doppelseite aus zwei gegenüberliegenden Seiten; auch die Vorlage muss eine Doppelseitenvorlage sein. |
| `id="…"`, `#id` | Ein Anker: Ein `:ref` darauf druckt die Seite, auf der die zusammengesetzte Seite landet. |
| jedes andere | Ein Wert, den die Vorlage als `{attr.name}` liest, etwa ein Hintergrundbild, das Seite für Seite gewählt wird: `fondo="banda-retos"` mit `resourceId: "{attr.fondo}"` im Dekor. |

Eine zusammengesetzte Seite beginnt immer eine neue Seite (oder Doppelseite), und der Text nach ihrer schließenden Zeile beginnt auf der nächsten.

Das `:::page{split=…}` mit drei Doppelpunkten ist eine Comicseite (siehe [Comics](https://postext.dev/de/docs/comics.md)) und behält diese Bedeutung. Ein `:::page` mit drei Doppelpunkten, das `template=` trägt, wird weiterhin als Comicseite gelesen, und die Warnung `pageFenceLength` weist darauf hin, dass eine zusammengesetzte Seite vier Doppelpunkte braucht.

Fehlt eine Begrenzung, fängt sich der Parser, ohne Text zu verlieren:

- eine offen gelassene Seite reicht bis zum Ende des Kapitels und wird an ihrer öffnenden Zeile als nicht geschlossener Container gemeldet;
- eine Zeile `::::page`, die bei offener Seite auftaucht, schließt dort zuerst die offene Seite (und wird ebenso gemeldet);
- die schließende Zeile schließt jeden Rahmen und jeden Kasten, der in der Seite noch offen ist, und meldet jeden davon;
- eine schließende Zeile mit einer anderen Zahl von Doppelpunkten gehört nicht zur Seite und bleibt im Text stehen, wo Sie sie sehen.

## Rahmen und Slots

```md
:::frame{slot="dinero" label="El dinero"}
Es el instrumento utilizado como medio de pago…

Hasta hace pocos años, lo más normal era pagar con dinero en **efectivo**…
:::
```

Ein **Slot** ist der Name, den ein Stück Inhalt anfordert; er entspricht dem Namen eines Rahmens der Vorlage. `:::frame{slot="…"}` schickt alles, was darin steht, in diesen Rahmen. Der Inhalt ist vollständiges Markdown: Absätze, Listen, Überschriften, Chips, `::resource`-Einbettungen, `:ref`-Verweise, Fußnoten, `:::columns` und verschachtelte Kästen. `label` und `title` geben dem Etikett oder dem Titel des Rahmens den Wortlaut, wie bei einem `:::callout`; das Aussehen des Rahmens bestimmt das Kastenformat, das die Vorlage ihm zuweist.

Ein einzelner Block kann seinen Slot selbst nennen:

| Block | Schreibweise |
| --- | --- |
| Eine Überschrift | `## Retos {slot="retos-titulo"}` |
| Eine Ressourceneinbettung | `::resource{id="dinero-pago" slot="dinero-fotos"}` (die beiden Attribute in beliebiger Reihenfolge) |
| Ein Code-Listing | `````js {slot="codigo"}`` |
| Ein Kasten oder ein anderer Container | `:::callout{type="nota" slot="aside"}`: Der ganze Kasten kommt in den Slot. |
| Eine Abbildung | `:::figure{resource="mapa" slot="mapa"}` (siehe unten) |

So wird der Inhalt verteilt:

- Mehrere Stücke mit demselben Slot werden in der Reihenfolge des Markdowns aneinandergefügt.
- Inhalt ohne Slot kommt in den **Flussrahmen** der Vorlage (den mit `flow` markierten Rahmen).
- Eine Überschrift ohne Slot kommt zuerst in den Rahmen, der ihre Ebene übernimmt (`takes: "h1"`), sofern die Vorlage einen solchen hat; der Titel eines Schulbuchthemas ist also einfach `# Titel` oben auf der Seite.
- Inhalt, der einen Slot nennt, den die Vorlage nicht kennt, kommt in den Flussrahmen und wird gemeldet (`slotUnknown`).

Außerhalb einer zusammengesetzten Seite wird ein `slot` gelesen und ändert nichts.

## Abbildungen mit Beschriftungen

```md
:::figure{resource="mapa-europa" slot="mapa"}
::label[OCÉANO ATLÁNTICO]{at="atlantico" style="mar"}
::label[**Madrid**]{at="madrid"}
::label[Mar Negro]{at="62% 48%"}
:::
```

`:::figure{resource="…"}` setzt eine Ressource mit Legende und Nummer, wie `::resource` es tut, und führt die Beschriftungen auf, die auf das Bild kommen: je Beschriftung eine Zeile `::label[TEXT]{…}`, Leerzeilen dazwischen sind erlaubt.

- `at` nennt einen Anker der Ressource (einen Punkt, der einmal auf dem Bild festgelegt wird und für alle Sprachen gilt) oder gibt für eine Beschriftung ohne Anker einen Punkt in Prozent des Bilds an, `at="x% y%"`.
- `style` nennt ein Beschriftungsformat und hat Vorrang vor dem des Ankers.
- Der Text in den eckigen Klammern ist Inline-Markdown: fett, kursiv, Chips.

Eine Abbildung funktioniert im Fließtext ebenso wie in einem Rahmen. Die Beschriftungen werden gelesen und mit ihrer Quelle aufbewahrt; auf das Bild gezeichnet werden sie erst in einer späteren Version, und bis dahin wird eine Abbildung so gesetzt wie ihre Ressource. Eine Zeile in einer Abbildung, die weder eine Beschriftung noch leer ist, beendet eine Abbildung, deren schließendes `:::` fehlt, und wird als nicht geschlossener Container gemeldet.

## Beispiel

Die Seite eines Schulbuchs mit einem Titelband, einem Text mit seiner Liste und drei farbigen Kästen, jeder mit seinem Foto daneben:

```md
::::page{template="tema-cajas" fondo="banda-retos"}
# La actividad económica y el dinero

## La actividad económica

Las personas utilizan :chip[recursos]{style="clave"} que se obtienen de la naturaleza…

- Las :chip[empresas.]{style="clave"} Ofrecen bienes y servicios a cambio de un beneficio.
- Las :chip[personas y familias.]{style="clave"} Adquieren lo que ofrecen las empresas…

:::frame{slot="dinero" label="El dinero"}
Es el instrumento utilizado como medio de pago, ya que su valor es conocido…
:::

::resource{id="dinero-pago" slot="dinero-fotos"}

:::frame{slot="gasto" label="El gasto"}
- **Fijo:** es el que se produce todos los meses…
- **Variable:** puede cambiar según las necesidades…
:::

::resource{id="gasto-compras" slot="gasto-fotos"}

:::frame{slot="ahorro" label="Préstamos y ahorro"}
Si necesitas o quieres comprar algo muy caro…
:::

::resource{id="ahorro-balanza" slot="ahorro-fotos"}
::::
```

Der Titel kommt in den Rahmen, der `h1` übernimmt; die Zwischenüberschrift, der Absatz und die Liste kommen in den Flussrahmen; jeder Kasten und jedes Foto kommt in den Rahmen seines Slots. Die katalanische Ausgabe besteht aus denselben Zeilen mit anderen Wörtern: Vorlage, Slots und Fotos bleiben unverändert.

## Wie die Seite gesetzt wird

Eine zusammengesetzte Seite belegt eine eigene Seite (Rolle `composed` für den Filter `pages` der Gestaltungselemente). Die Vorlage wird passend zur Lage der Seite gewählt, rechts oder links; es gilt also ihr `variants.recto` oder ihr `variants.verso`. Danach wird ein Rahmen nach dem anderen platziert und gefüllt, mit der Typografie des übrigen Buchs: Absatz- und Überschriftenformate, Listen, Chips, Fußnotenzeichen und das Kastenformat des Rahmens.

### Rahmen platzieren

Ein Rahmen steht in seiner Rasterzelle oder dort, wo sein `placement` ihn hinsetzt (ein Anker, eine Kante und ein Versatz, wie bei einem Gestaltungselement); hat er beides nicht, steht er in der oberen linken Ecke des Vorlagenbereichs und ist so breit wie der Bereich. Ein Rahmen, der an einem anderen verankert ist (`"to": "#dinero"`), wird nach diesem platziert und bewegt sich mit ihm: `below` hängt ihn unter den anderen Rahmen, `right-of` stellt ihn daneben, und eine Ecke wie `top-right` heftet ihn an diese Ecke des anderen Rahmens.

Seine Höhe ist fest (eine Länge oder ein Prozentwert), `fill` (bis an den Rand des Bereichs) oder `auto`, der Standard: die Höhe des Inhalts, den er erhält, zwischen `minHeight` und `maxHeight` und nie über den Fuß des Bereichs hinaus. In einem Rahmen, der höher ist als sein Inhalt, legt `verticalAlign` fest, wo der Inhalt steht (`top`, `middle`, `bottom` oder `justify`, um den Raum zwischen seinen Blöcken zu verteilen). Das Kastenformat des Rahmens zeichnet Hintergrund, Kontur, abgerundete Ecken, Streifen und Symbol in der vollen Größe des Rahmens; das `label` der Begrenzung `:::frame` steht im Reiter des Formats.

### Der Flussrahmen und die Überschriften

Inhalt, der keinen Slot nennt, kommt in den mit `flow` markierten Rahmen; die erste Überschrift einer Ebene kommt in den Rahmen, der sie mit `takes` übernimmt. Die Rahmen einer Seite werden in der Reihenfolge gelesen, in der ihr Inhalt zum ersten Mal im Markdown auftaucht, jeder als Ganzes: Ein Screenreader, das getaggte PDF und die Ausgaben mit fließendem Layout lesen einen Kasten nach dem Text, mit dem die Seite beginnt, nicht mitten darin.

### Rahmen verketten

`next` schickt, was ein Rahmen nicht fasst, in einen anderen Rahmen derselben Seite und von dort weiter in den nächsten, wie verkettete Textrahmen im Layoutprogramm:

```json
{ "name": "columna-1", "flow": true, "next": "columna-2", "height": { "value": 120, "unit": "mm" } },
{ "name": "columna-2", "placement": { "anchor": { "to": "#columna-1", "edge": "right-of" } } }
```

Der Text wird zwischen zwei Zeilen geteilt und läuft im nächsten Rahmen weiter, neu umbrochen auf dessen Breite, ohne dass etwas verloren geht oder doppelt erscheint. `overflow.continueIn: "#frame"` bedeutet dasselbe. Das Weiterlaufen auf der nächsten Seite ist geplant (`"next-page"`).

### Rahmen, die Text verdrängen

Ein Rahmen mit `exclude: "push"` hält den Text der anderen Rahmen aus seinem Rechteck heraus: Eine Zeile eines anderen Rahmens, die darauf trifft, wird auf der Seite, die das Rechteck abdeckt, kürzer gesetzt, so wie der Fließtext ein Bild umfließt. Ein Foto, das an der Ecke eines Kastens verankert und mit `push` markiert ist, lässt den Text des Kastens neben sich herlaufen. Ein Kasten, der eine feste Spalte für seine Bilder freihalten soll, kann stattdessen `padding` verwenden.

### Dekor, Kolumnentitel und Ebenen

Das Dekor der Vorlage (`decoration`: Bilder, Linien, Kästen und kurze Texte) wird gesetzt, sobald die Rahmen ihre endgültige Box haben; ein Element kann sich daher an einem Rahmen verankern (`"to": "#gasto"`) und ihm folgen. Seine Texte lesen die Attribute der Seite selbst: `fondo="banda-retos"` an der Seitenbegrenzung ergibt `{attr.fondo}`, etwa für ein Hintergrundbild, das Seite für Seite mit `"resourceId": "{attr.fondo}"` gewählt wird. Auch die Kolumnentitel lesen sie. Das `header` oder `footer` einer Vorlage ersetzt das des Abschnitts, `false` blendet es aus, und ohne beides erscheinen die Kolumnentitel des Abschnitts.

Rahmen werden in der Reihenfolge ihrer `layer` gezeichnet: das Dekor auf Ebene 0, Rahmen standardmäßig auf Ebene 1, eine höhere Ebene über einer niedrigeren, eine negative Ebene unter dem Dekor. `rotate` dreht einen Rahmen samt Inhalt um einen beliebigen Winkel um seinen Mittelpunkt, im Canvas, im PDF, im HTML-Betrachter und im EPUB mit festem Layout.

### Inhalt, der nicht passt

Ein Rahmen, dessen Inhalt höher ist als der Rahmen und der keinen Folgerahmen hat, behält den ganzen Inhalt im Dokument, zeigt aber nur, was hineinpasst: Der Rest wird in der paginierten Ausgabe am Fuß des Rahmens abgeschnitten, und die Warnung [`frameOverflow`](https://postext.dev/de/docs/composed-pages.md#frameoverflow) nennt die Menge. Inhalt, den kein Rahmen aufnimmt (kein Flussrahmen, oder auf dieser Seite fehlt ein Rahmen), wird im Fließtext auf der Seite nach der zusammengesetzten Seite gesetzt.

## Warnungen

Die Prüfungen lesen Markdown und Konfiguration vor jedem Umbruch. Deshalb erscheinen sie schon beim Tippen im Bedienfeld Prüfungen, außerdem in `postext check` und in den `contentWarnings` des Dokuments, jede mit dem Quellbereich dessen, was sie betrifft (siehe [Konfiguration › Warnungen im Dokument](https://postext.dev/de/docs/configuration-programmatic-usage.md#warnungen-im-dokument)).

| Art | Ursache | Abhilfe |
| --- | --- | --- |
| `templateUnknown` | Die Seitenbegrenzung nennt eine Vorlage, die es unter den Einträgen von `pageTemplates` nicht gibt, oder gar keine. Ihre Slots werden nicht geprüft. | Korrigieren Sie die ID, oder fügen Sie die Vorlage der Konfiguration hinzu. |
| `slotUnknown` | Ein `slot="…"` nennt keinen Rahmen der Vorlage der Seite (über `extends` geerbte Rahmen und die Rahmen einer Seite aus `variants` zählen mit). Der Inhalt kommt in den Flussrahmen. | Korrigieren Sie den Slot-Namen, oder fügen Sie der Vorlage einen Rahmen mit diesem Namen hinzu. |
| `slotEmpty` | Ein Rahmen der Vorlage erhält auf dieser Seite nichts: Kein Slot nennt ihn, er übernimmt keine Überschrift, und beim Flussrahmen bleibt kein Inhalt ohne Slot übrig. Ein Rahmen, der nur die Fortsetzung eines anderen Rahmens aufnimmt (`next`), wird nicht gemeldet. `postext check` führt ihn als Hinweis auf. | Schreiben Sie Inhalt mit seinem Slot für ihn, oder markieren Sie den Rahmen in der Vorlage mit `optional: true`. |
| `pageFenceLength` | Ein `:::page` mit drei Doppelpunkten trägt `template=`. Es wird wie bisher als Comicseite gelesen. | Öffnen Sie die Seite mit vier Doppelpunkten, `::::page{template="…"}`, und schließen Sie sie mit `::::`. |
| `unclosedContainer` | Eine zusammengesetzte Seite, ein Rahmen oder eine Abbildung wird nie geschlossen (siehe oben, wie sich der Parser fängt). Das Bedienfeld Prüfungen nennt die zusammengesetzte Seite `::::page`. | Ergänzen Sie die schließende Zeile: so viele Doppelpunkte wie in der öffnenden Zeile der Seite, oder `:::` für einen Rahmen oder eine Abbildung. |

### frameOverflow

Diese Warnung kommt aus dem Umbruch, nicht aus den Quellprüfungen oben: Sie erscheint, sobald die Seite gesetzt ist, im Bedienfeld Prüfungen, in `postext check` und in den `contentWarnings` des Dokuments.

**Ursache.** Der Inhalt, der in einen Rahmen fließt (über seinen Slot oder als Inhalt des Fließrahmens), ist höher als der Rahmen, und der Rahmen hat kein `next` mehr, in dem es weitergeht. Meist ist es mehr Text, als der Rahmen fasst: eine Übersetzung, die länger läuft als das Original, oder ein Rahmen mit festem `height` oder `maxHeight`. Was nicht passt, wird in der paginierten Ausgabe am Fuß des Rahmens abgeschnitten; im Dokument, in der Quellzuordnung und im EPUB mit fließendem Layout bleibt es erhalten. Die Warnung nennt die Vorlage, den Rahmen, die Seite, die abgeschnittene Höhe (`overflowMm`) und `configPath`, den JSON-Zeiger des Rahmens in der Konfiguration (`/pageTemplates/0/frames/2`).

**Behebung.** Geben Sie dem Rahmen mehr Platz (erhöhen oder entfernen Sie `height` oder `maxHeight`), verketten Sie ihn mit `next` mit einem weiteren Rahmen, kürzen Sie den Text oder setzen Sie die Seite mit einer anderen Vorlage. Der Umbruch verkleinert den Text bisher nicht, damit er passt.

## Aus dem Code

`composedPages(blocks)` liest die geparsten Blöcke eines Kapitels (`parseMarkdownWithIssues(markdown).blocks`) und gibt der Reihe nach je Seitenbegrenzung einen Knoten zurück: `template`, `spread`, `attrs` mit dem Quellbereich jedes Werts (`attrSources`), `fenceIndex` (die Ordnungszahl der Begrenzung im Kapitel, in jeder Sprache dieselbe), `slots` (die Indizes der Blöcke jedes Slots, in der Reihenfolge des Markdowns), `unassigned` (die Blöcke ohne Slot) und den Quellbereich der ganzen Seite. Ein Block trägt den Slot, den er nennt, in `ContentBlock.slot`, mit dem Quellbereich des Werts; eine Abbildung ist ein `resourceBlock`, dessen `figure` ihre Attribute und Beschriftungen enthält, jede Beschriftung mit ihrem Text, ihren Inline-Spans und einer Zuordnung zurück zur Quelle im Markdown. `checkComposedSlots(pages, config)` gibt die drei Slot-Warnungen für diese Seiten zurück.

Nach dem Umbruch hält `VDTPage.composed` einer zusammengesetzten Seite ihre Vorlage fest, die angewandte Variante, die Attribute der Seitenbegrenzung und für jeden Rahmen seine ID (`cp0:dinero`: die Ordnungszahl der Seitenbegrenzung und der Name des Rahmens, in jeder Sprache dieselbe), seine Box, Ebene und Drehung, die Höhe des Inhalts, der nicht hineinpasste (`overflowPx`), den Rahmen, aus dem er weiterläuft oder in den er weiterläuft, seinen Konfigurationspfad (`/pageTemplates/0/frames/2`) und die IDs seiner Blöcke. Diese Blöcke sind gewöhnliche Kastenblöcke in `page.floats` und `doc.blocks` mit ihren Quellbereichen, sodass ein Klick in einen ungedrehten Rahmen der Sandbox-Vorschau zu seinem Markdown führt. `composedPaintOrder(page)` liefert die Reihenfolge, in der ein Renderer Rahmen und Dekor zeichnet, und `frameMatrix(frame)` die Drehung eines Rahmens.
