Conversation
Replace modules_<lang>/ with profile_<name>/ folders, each containing its own complete metadata.toml. This enables per-profile customization of personal info, header quotes, keywords, and all other metadata. - Rename modules_* folders to profile_* in template - Add per-profile metadata.toml with flat structure (no [lang] nesting) - Add fallback logic in src/ for backward compatibility with old format - Replace --input language=xx with --input profile=xx in template - Remove top-level metadata.toml (each profile is self-contained) Closes #142 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a profile-based template layout where each profile folder contains its own metadata.toml and module .typ files, and updates the package code to resolve certain metadata fields from either the new flat schema or the legacy [lang.*] schema.
Changes:
- Update
template/cv.typandtemplate/letter.typto loadprofile_<profile>/metadata.tomland include modules from the selected profile folder. - Add new per-profile template module files and per-profile
metadata.tomlforen,fr,de,it,zh. - Implement fallback resolution in
src/forheader_quote,cv_footer,letter_footer,non_latin_name,non_latin_font(top-level first, legacy paths second).
Reviewed changes
Copilot reviewed 10 out of 40 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| template/cv.typ | Switches template entrypoint to profile-based metadata/modules loading. |
| template/letter.typ | Switches letter template entrypoint to profile-based metadata loading. |
| template/profile_en/metadata.toml | Moves footer/quote fields to top-level for the English profile. |
| template/profile_en/education.typ | Adds English profile education module. |
| template/profile_en/professional.typ | Adds English profile professional module. |
| template/profile_en/projects.typ | Adds English profile projects module. |
| template/profile_en/publications.typ | Adds English profile publications module. |
| template/profile_en/skills.typ | Adds English profile skills module. |
| template/profile_en/certificates.typ | Adds English profile certificates module. |
| template/profile_fr/metadata.toml | Adds French profile metadata. |
| template/profile_fr/education.typ | Adds French profile education module. |
| template/profile_fr/professional.typ | Adds French profile professional module. |
| template/profile_fr/projects.typ | Adds French profile projects module. |
| template/profile_fr/publications.typ | Adds French profile publications module. |
| template/profile_fr/skills.typ | Adds French profile skills module. |
| template/profile_fr/certificates.typ | Adds French profile certificates module. |
| template/profile_de/metadata.toml | Adds German profile metadata. |
| template/profile_de/education.typ | Adds German profile education module (currently includes local metadata loading). |
| template/profile_de/professional.typ | Adds German profile professional module (currently includes local metadata loading). |
| template/profile_de/projects.typ | Adds German profile projects module (currently includes local metadata loading). |
| template/profile_de/publications.typ | Adds German profile publications module (currently includes local metadata loading). |
| template/profile_de/skills.typ | Adds German profile skills module (currently includes local metadata loading). |
| template/profile_de/certificates.typ | Adds German profile certificates module (currently includes local metadata loading). |
| template/profile_it/metadata.toml | Adds Italian profile metadata. |
| template/profile_it/education.typ | Adds Italian profile education module. |
| template/profile_it/professional.typ | Adds Italian profile professional module. |
| template/profile_it/projects.typ | Adds Italian profile projects module. |
| template/profile_it/publications.typ | Adds Italian profile publications module. |
| template/profile_it/skills.typ | Adds Italian profile skills module. |
| template/profile_it/certificates.typ | Adds Italian profile certificates module. |
| template/profile_zh/metadata.toml | Adds Chinese profile metadata (including non-Latin name/font fields). |
| template/profile_zh/education.typ | Adds Chinese profile education module. |
| template/profile_zh/professional.typ | Adds Chinese profile professional module. |
| template/profile_zh/projects.typ | Adds Chinese profile projects module. |
| template/profile_zh/publications.typ | Adds Chinese profile publications module. |
| template/profile_zh/skills.typ | Adds Chinese profile skills module. |
| template/profile_zh/certificates.typ | Adds Chinese profile certificates module. |
| src/lib.typ | Adds fallback logic for non-Latin font resolution in both CV + letter. |
| src/cv.typ | Adds fallback logic for header_quote, cv_footer, non_latin_name. |
| src/letter.typ | Adds fallback logic for letter_footer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix camelCase nonLatinFont -> kebab-case non-latin-font in src/lib.typ - Add backward compat comments to all legacy fallback code in src/ - Add inline documentation comments to template/cv.typ and letter.typ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts in template files, keeping profile-based metadata approach while incorporating main's updates (v3.2.0 version bump, new metadata comments for researchgate/extraInfo/linebreak, fontawesome link in custom icon comment). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… migration guide Profile metadata files (de/fr/it/zh) contained inject_ai_prompt and inject_keywords which trigger panics in src/cv.typ. Removed to match profile_en and allow compilation. Added "Migration from v3" section to docs with motivation, zero-effort upgrade path, and step-by-step migration instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@codex Review this PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc5e4e393b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
template/cv.typ
Outdated
| // | ||
| // Override via CLI: typst compile cv.typ --input profile=fr | ||
| #let profile = sys.inputs.at("profile", default: "en") | ||
| #let metadata = toml("profile_" + profile + "/metadata.toml") |
There was a problem hiding this comment.
Use a package version that supports profile metadata
template/cv.typ now reads per-profile metadata.toml files where values like header_quote and cv_footer are top-level, but the template is still pinned to @preview/brilliant-cv:3.2.0, which expects these fields under metadata.lang.<code>. In this state, users following the new profile layout will hit runtime errors because metadata.lang is absent; template/letter.typ has the same version pin, so both document entrypoints are affected until the import is updated to the release that includes this commit's metadata fallback changes.
Useful? React with 👍 / 👎.
Restore profile_<lang>/ directory structure from PR #155 for content modules. Slim down each profile's metadata.toml to sparse overrides that are deep-merged with root metadata.toml. Remove the separate profiles/ directory — overrides now live inside profile_<lang>/. Update cv.typ and letter.typ to deep-merge root + profile metadata. Update all docs to reflect profile_<lang>/ paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add deep-merge utility for profile-based metadata overrides Replace the full-copy-per-profile approach with a deep-merge function that recursively merges sparse profile TOML files on top of a shared root metadata.toml. This lets users vary any field (personal.info, layout, inject, etc.) per language or target role without duplicating the entire configuration. - Add src/utils/merge.typ with recursive deep-merge function - Export deep-merge from src/lib.typ - Update template/cv.typ and letter.typ with profile-aware loading - Restore root metadata.toml and modules_<lang>/ directories - Remove profile_<lang>/ directories (replaced by profiles/ overrides) - Add example profile files (en, fr, zh) in template/profiles/ - Update docs: recipes, getting-started, migration guide, API reference Closes #142 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use profile_<lang>/ structure with sparse metadata overrides Restore profile_<lang>/ directory structure from PR #155 for content modules. Slim down each profile's metadata.toml to sparse overrides that are deep-merged with root metadata.toml. Remove the separate profiles/ directory — overrides now live inside profile_<lang>/. Update cv.typ and letter.typ to deep-merge root + profile metadata. Update all docs to reflect profile_<lang>/ paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use descriptive custom entry names to prevent deep-merge inheritance bugs profile_fr/metadata.toml defined custom-2 with text="Permis B" but no link, causing deep-merge to inherit root's AWS certification URL. Rename numbered custom entries (custom-1, custom-2) to descriptive names (custom-degree, custom-cert, custom-car) across root and all profiles. Document deep-merge inheritance behavior and naming convention in recipes.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflict in src/lib.typ: keep backward-compat fallback for non_latin_font (profile-based) with calc.min safe insertion (from main). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-Latin fonts Replace fonts.insert(calc.min(2, fonts.len()), ...) with fonts.push(...). The non-Latin font is a fallback appended to the end of the font list, so push expresses the intent directly without a fragile index. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Why this change?
In v3, all CV variants share a single
metadata.toml. The[lang.<code>]sections only allow varyingheader_quote,cv_footer, andletter_footerper language — but fields like[personal.info],[layout], and[inject]are global and cannot differ between languages or target roles (#142).This makes it impossible to, for example, use a different phone number for your French CV, tailor keywords per target industry, or adjust layout for different paper sizes by region.
The new profile-based architecture solves this by making each variant a self-contained folder (
profile_en/,profile_fr/,profile_swe/) with its own completemetadata.tomland module files. Users can now vary everything per profile — not just language-specific text.Summary
profile_<name>/) contains its ownmetadata.tomland module files--input language=xxpattern with--input profile=xxin the templatesrc/) is backward compatible — accepts both old and new metadata formatsBackward compatibility
Package (
src/) — fully backward compatible:metadata.tomlwith[lang.en]sections → works (fallback path for 5 fields:header_quote,cv_footer,letter_footer,non_latin_name,non_latin_font)metadata.toml→ works (top-level path)Template (
template/) — breaking change:modules_<lang>/renamed toprofile_<name>/--input language=xxreplaced by--input profile=xxmetadata.tomlreplaced by per-profilemetadata.tomlUpgrade paths for existing users:
Proposed design
User-facing (template/)
Profile metadata.toml (flat, no
[lang]nesting)What stays unchanged
metadata.language— still used by_is-non-latin(),_default-date-width()metadata.personal.*,metadata.layout.*,metadata.inject.*— same structurecv-section,cv-entry, etc.) — untouched