|
| 1 | +# Templates v2 — CV, cover letter, invoice, proposal |
| 2 | + |
| 3 | +GraphCompose v1.6 ships a rebuilt canonical template surface for the four |
| 4 | +business document shapes: **CV, cover letter, invoice, proposal**. Every |
| 5 | +preset is one final class with one `create(BusinessTheme)` factory, and |
| 6 | +the spec / preset / theme split is the same across all four domains so a |
| 7 | +caller learns it once and reuses it everywhere. |
| 8 | + |
| 9 | +This page is a landing reference. For a full conceptual walk-through |
| 10 | +(four-layer architecture, when to extend a preset vs. write your own, |
| 11 | +how rendering decisions cascade through theme tokens), read |
| 12 | +[`docs/template-authoring.md`](./template-authoring.md). For the v1 → v2 |
| 13 | +upgrade table (every old class → its v2 replacement, with before/after |
| 14 | +code), read [`docs/migration-v1-5-to-v1-6.md`](./migration-v1-5-to-v1-6.md). |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Architecture in four layers |
| 19 | + |
| 20 | +Every Templates v2 preset is composed in four layers, top-to-bottom: |
| 21 | + |
| 22 | +1. **Theme tokens** — `BusinessTheme` + `Spacing` + `Typography`. Colours, type scale, gutters, accent rules. |
| 23 | +2. **Layout slots** — `SingleColumn`, `TwoColumnSidebar`, `ThreeColumnMagazine`, `LetterFormat`. The page geometry strategy. |
| 24 | +3. **Components + blocks** — `Header`, `Module`, `MarkdownText`; sealed `Block` hierarchy (`ParagraphBlock`, `BulletListBlock`, `KeyValueBlock`, `IndentedBlock`, `MultiParagraphBlock`). |
| 25 | +4. **Spec data** — `CvSpec`, `CoverLetterSpec`, `InvoiceSpec`, `ProposalSpec`. The plain-Java record carrying the document's content. |
| 26 | + |
| 27 | +Presets glue 1+2+3 together; a caller hands them 4. Adjusting one visual |
| 28 | +decision is one method on one preset, never a fork of a 600-line composer. |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +## Quick start |
| 33 | + |
| 34 | +```java |
| 35 | +import com.demcha.compose.document.templates.cv.presets.ModernProfessional; |
| 36 | +import com.demcha.compose.document.templates.cv.spec.CvSpec; |
| 37 | +import com.demcha.compose.document.templates.api.DocumentTemplate; |
| 38 | +import com.demcha.compose.document.theme.BusinessTheme; |
| 39 | + |
| 40 | +DocumentTemplate<CvSpec> template = ModernProfessional.create(BusinessTheme.modern()); |
| 41 | +template.compose(session, mySpec); |
| 42 | +``` |
| 43 | + |
| 44 | +Same shape for cover letters, invoices, and proposals — swap the |
| 45 | +package, the spec type, and the preset class. |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## CV preset gallery (14) |
| 50 | + |
| 51 | +Each preset is a one-class final type with `RECOMMENDED_MARGIN` and |
| 52 | +`create(BusinessTheme)`. Visual baselines are pixel-diff verified against |
| 53 | +v1 reference renders. |
| 54 | + |
| 55 | +| Preset | Layout | Notes | |
| 56 | +|---|---|---| |
| 57 | +| `ModernProfessional` | Single column | Slate-blue name + royal-blue underlined links; canonical default | |
| 58 | +| `NordicClean` | Two-column sidebar | Soft-tinted profile panel on the left | |
| 59 | +| `ClassicSerif` | Two-page editorial | Serif-only typography, restrained accents | |
| 60 | +| `CompactMono` | Single column | Tight grid for technical CVs | |
| 61 | +| `Executive` | Two-column sidebar | Larger accent rule + uppercase section heads | |
| 62 | +| `EngineeringResume` | Two-column sidebar | Dense skill stack, code-friendly mono | |
| 63 | +| `TimelineMinimal` | Single column | Vertical rule + dot timeline along the left margin | |
| 64 | +| `BoxedSections` | Single column | Section headers in tinted boxes with full-width rule | |
| 65 | +| `CenteredHeadline` | Single column | Centered name + bullet & key-value sections | |
| 66 | +| `BlueBanner` | Single column | Full-width section banners in theme accent | |
| 67 | +| `EditorialBlue` | Single column | Slab subtitle + jobTitle line + uppercase rule | |
| 68 | +| `Panel` | Two-column sidebar | Soft-tinted panel for sidebar; project-leader shape | |
| 69 | +| `SidebarPortrait` | Two-column sidebar | Portrait + sidebar fill to page bottom | |
| 70 | +| `MonogramSidebar` | Two-column sidebar | Monogram badge + sidebar fill | |
| 71 | + |
| 72 | +## Cover-letter preset gallery (14, paired) |
| 73 | + |
| 74 | +Each cover-letter preset pairs visually with its same-named CV preset |
| 75 | +(palette, header rhythm, accent rule). Mix-and-match is supported but the |
| 76 | +default pairing produces the cleanest visual. |
| 77 | + |
| 78 | +`ModernProfessional` · `NordicClean` · `ClassicSerif` · `CompactMono` |
| 79 | +· `Executive` · `EngineeringResume` · `TimelineMinimal` · `BoxedSections` |
| 80 | +· `CenteredHeadline` · `BlueBanner` · `EditorialBlue` · `Panel` |
| 81 | +· `SidebarPortrait` · `MonogramSidebar` |
| 82 | + |
| 83 | +Render any preset against a sample spec to inspect the output: |
| 84 | + |
| 85 | +```bash |
| 86 | +./mvnw -f examples/pom.xml exec:java \ |
| 87 | + -Dexec.mainClass=com.demcha.examples.templates.cv.CvTemplateGalleryFileExample |
| 88 | +``` |
| 89 | + |
| 90 | +The runnable gallery writes one PDF per preset under |
| 91 | +`examples/target/generated-pdfs/templates/cv/`. The cover-letter gallery |
| 92 | +mirrors the layout under `templates/coverletter/`. |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | +## Invoice + proposal (minimal v2 surface) |
| 97 | + |
| 98 | +`ModernInvoice` and `ModernProposal` ship as the canonical builder seam |
| 99 | +for invoices and proposals respectively. Cinematic feature parity |
| 100 | +(rich hero blocks, accent-driven section bands) lives in |
| 101 | +`InvoiceTemplateV2` / `ProposalTemplateV2` under |
| 102 | +`templates/builtins/` — those remain the recommended path when full |
| 103 | +visual styling is required, while the v2 builders provide a smaller, |
| 104 | +copy-and-tweak entry point for callers extending their own branding. |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +## Authoring features built into every preset |
| 109 | + |
| 110 | +- **Inline markdown** — body strings carrying `**bold**` and `*italic*` markers render with proper `DocumentTextDecoration` via `templates.components.MarkdownText`. |
| 111 | +- **Active hyperlinks** — header email + LinkedIn / GitHub labels become clickable `mailto:` / `https:` runs via `DocumentLinkOptions`. |
| 112 | +- **Slot-based layouts** — multi-column presets (`Panel`, `SidebarPortrait`, `MonogramSidebar`) declare named slots (`MAIN`, `SIDEBAR`); custom presets rearrange modules via `.place(slot, "Module Name", ...)`. |
| 113 | +- **Adaptive sidebar fill** — sidebar layouts size the trailing spacer dynamically from `canvas().innerHeight()` so background panels reach the page bottom on A4 / Letter / smaller fixtures without overflow. |
| 114 | +- **`CvHeader.jobTitle` subtitle** — presets that surface a subtitle (`EditorialBlue`, `Panel`, `SidebarPortrait`, `MonogramSidebar`) read it from the spec; an empty value falls back to a placeholder. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +## Visual parity & regression coverage |
| 119 | + |
| 120 | +- **28 layout-snapshot baselines** under `src/test/resources/layout-snapshots/canonical-templates/{cv-v2,coverletter-v2}/` lock the rendered tree of every preset. |
| 121 | +- **29 pixel-diff baselines** under `src/test/resources/visual-baselines/{cv-v2,coverletter-v2}/` enforce per-channel rendering parity against the v1 reference renders. The gate runs on every CI build with a calibrated `mismatchedPixelBudget` for cross-platform PDFBox font drift. |
| 122 | +- Re-bless after a deliberate visual change with `-Dgraphcompose.visual.approve=true`. |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +## Migration from v1 templates |
| 127 | + |
| 128 | +Legacy CV / cover-letter classes (`CvTemplateV1`, `NordicCleanCvTemplate`, |
| 129 | +`MonogramSidebarCvTemplate`, ...) are **deleted**, not deprecated, in |
| 130 | +v1.6. Any code constructing those classes must switch to the matching v2 |
| 131 | +preset's `create(BusinessTheme)` factory. The full mapping (every old |
| 132 | +class → its v2 replacement, with side-by-side code) is documented in |
| 133 | +[`docs/migration-v1-5-to-v1-6.md`](./migration-v1-5-to-v1-6.md). |
0 commit comments