Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 40 additions & 39 deletions docs/templates/v2-layered/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ GraphCompose's templates v2 (layered) gives you:
- **Themes describing visuals** — `BrandTheme` (palette + typography +
spacing + decoration). Swap a theme to change colours, fonts,
bullet glyphs without touching renderers.
- **Widgets as visual LEGO bricks** — `Headline`, `Subheadline`,
`ContactLine`, `SectionHeader`. Each one is a named visual decision
you can drop into a preset.
- **Widgets as visual LEGO bricks** — the neutral header bricks
(`Headline`, `Subheadline`, `ContactLine`) live in the shared
`templates.core.identity`; CV-specific ones (`SectionHeader` and
friends) in `cv.v2.widgets`. Each is a named visual decision you
drop into a preset.
- **Presets as compositions** — a preset orchestrates widgets in a
page flow. `BoxedSections`, `MinimalUnderlined`,
`ModernProfessional`, `CenteredHeadline`, `BlueBanner`,
`EditorialBlue`, `ClassicSerif`, `NordicClean`, and `CompactMono`
ship today; writing your own is ~150 lines.
page flow. Sixteen ship today (`BoxedSections`, `ModernProfessional`,
`NordicClean`, `EditorialBlue`, `Executive`, `EngineeringResume`,
`TimelineMinimal`, …); writing your own is ~150 lines.

You hand a `CvDocument` to a preset, you get a PDF. The preset
internally composes widgets that read theme tokens that ultimately
Expand Down Expand Up @@ -84,50 +85,50 @@ Same data, different visual. That's the layering.

---

## The 5 layers
## The layers

```
┌─────────────────────────────────────────────────────────────┐
│ presets/ BoxedSections, MinimalUnderlined, │
│ ModernProfessional, CenteredHeadline, │
│ BlueBanner, EditorialBlue, ClassicSerif, │
│ NordicClean, CompactMono │
│ — composition of widgets in a page flow │
└─────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ presets/ 16 CV compositions │
│ BoxedSections, ModernProfessional, NordicClean, ... │
│ -- widgets composed in a page flow │
└────────────────────────────────────────────────────────────────────────────┘
│ compose from widgets
┌─────────────────────────────────────────────────────────────┐
│ widgets/ Headline, Subheadline, ContactLine, │
│ SectionHeader │
│ — named visual LEGO bricks │
└─────────────────────────────────────────────────────────────┘
│ delegate to ↓ │ read tokens from ↓
▼ ▼
┌─────────────────────┐ ┌──────────────────────────────────┐
│ components/ │ │ theme/ │
│ SectionDispatcher │ │ Palette (colours) │
│ EntryRenderer │ │ Typography (fonts + sizes) │
│ RowRenderer │ │ Spacing (margins + gaps) │
│ ParagraphRenderer │ │ Decoration (bullet, sep) │
│ + primitives │ │ BrandTheme (bundle + factories) │
└─────────────────────┘ └──────────────────────────────────┘
│ renders into DSL
┌────────────────────────────────────────────────────────────────────────────┐
│ widgets/ CV-specific visual bricks │
│ SectionHeader, FlowSectionHeader, SkillBar, SectionModule, ... │
│ (neutral header bricks -- Headline, Subheadline, ContactLine, │
│ Masthead, SvgGlyph -- live in core.identity) │
└────────────────────────────────────────────────────────────────────────────┘
│ delegate to
┌─────────────────────────────────────────────────────────────┐
│ data/ CvDocument, CvIdentity, CvSection (sealed), │
│ ParagraphSection / SkillsSection / RowsSection │
│ / EntriesSection, │
│ CvRow, CvEntry, Slot │
│ — pure records, zero rendering deps │
└─────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
│ components/ CV section renderers │
│ SectionDispatcher, EntryRenderer, RowRenderer, ParagraphRenderer │
└────────────────────────────────────────────────────────────────────────────┘
│ render into
┌────────────────────────────────────────────────────────────────────────────┐
│ data/ CvDocument, CvIdentity, CvSection (sealed), │
│ ParagraphSection / SkillsSection / RowsSection / EntriesSection, │
│ CvRow, CvEntry, Slot -- pure records, zero rendering deps │
└────────────────────────────────────────────────────────────────────────────┘

...all built on the shared, family-neutral core (templates.core.*):
┌────────────────────────────────────────────────────────────────────────────┐
│ core.theme BrandTheme = Palette / Typography / Spacing / Decoration │
│ core.identity Headline, Subheadline, ContactLine, Masthead, SvgGlyph │
│ core.text MarkdownText, RichParagraphRenderer, TextStyles │
└────────────────────────────────────────────────────────────────────────────┘
```

**What each layer is for** (in plain English):

| Layer | "Answers the question…" |
|---|---|
| `data/` | "What goes on the page?" — content, no styling. |
| `theme/` | "How does it look?" — colours, fonts, glyphs. |
| `core.theme` | "How does it look?" — colours, fonts, glyphs (shared `BrandTheme`). |
| `components/` | "How is one element drawn?" — paragraph, row, entry primitives. |
| `widgets/` | "Which visual building block do I want here?" — named LEGO bricks. |
| `presets/` | "In what order, with which widgets, on which page flow?" — composition. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,22 @@
* {@link DocumentSession}. The interface is intentionally minimal — just
* identity (for registry lookup) and one composition seam.</p>
*
* <p><strong>Templates v2 contract</strong> (introduced in v1.6 alongside
* the templates restructure):</p>
* <p>Implementation contract:</p>
* <ul>
* <li>Implementations should be plain factory-style classes whose
* {@code create(BusinessTheme)} method returns a configured
* {@code DocumentTemplate<S>}.</li>
* <li>Implementations are plain factory-style classes — a static
* {@code create(theme)} method returns a configured
* {@code DocumentTemplate<S>}. The theme type is the family's own:
* the layered cv / cover-letter presets take a {@code BrandTheme};
* the layered invoice / proposal presets take a
* {@code BusinessTheme}.</li>
* <li>Implementations are stateless after construction — composing the
* same spec twice produces the same output.</li>
* <li>Implementations do not call {@code session.buildPdf()}; the caller
* owns session lifecycle. They only place semantic nodes via the
* session DSL.</li>
* </ul>
*
* <p>Domain-specific interfaces ({@code CvTemplate}, {@code InvoiceTemplate},
* etc.) remain in this package during the v1.6 migration window for
* backward compatibility. New templates should implement
* {@code DocumentTemplate<S>} directly.</p>
*
* @param <S> the spec type rendered by this template (e.g. {@code CvSpec},
* @param <S> the spec type rendered by this template (e.g. {@code CvDocument},
* {@code InvoiceSpec}, {@code ProposalSpec})
*/
public interface DocumentTemplate<S> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ on top of the v2 surface. It complements the JavaDoc in
`package-info.java` with longer, copy-pasteable recipes.

If you have never used this package before, read
[the package overview](./package-info.java) first. The four layers
(`data/` · `theme/` · `components/` · `presets/`) and what each is for
[the package overview](./package-info.java) first. The four CV layers
(`data/` · `components/` · `widgets/` · `presets/`) — plus the shared
theme / text / identity in `templates.core.*` — and what each is for
are explained there.

This guide answers the **"how do I…"** questions.
Expand Down
Loading
Loading