Printable HTML/CSS CV template based on the original Almeida CV by Inês Almeida (MIT License), extended with multi-CV routing, per-CV language/style control, and new data sections.
Live Demo: https://jinli-cv-demo.netlify.app/ — powered by the cv-demo repository.
Demo site:
- Default page: https://jinli-cv-demo.netlify.app/
- German CV: https://jinli-cv-demo.netlify.app/cv-de/
- Chinese CV: https://jinli-cv-demo.netlify.app/cv-zh/
This project is a derivative of Almeida CV by Inês Almeida (MIT License). Fork maintained at jin-li/jinli-cv.
- Multi-CV support from
data/<cv-folder>/with per-CV route byslug - Per-CV
languageCodefor section labels and page language - Flexible section ordering via
section_orderandside_section_orderparams - Per-CV theme/layout overrides (colors, column sizes, spacing, section order)
- New
Publicationssection- Linked/italic title support
- Single timeline-style gradient line in front of list
- Bullet list styling and print-friendly behavior
- New
Projectssection- Experience-like visual style
- Gradient guide line in front of each project's details list
- Topic, details, and optional badges support
- New
Thesissection- Experience-like visual style (timeline, place icon, bullets, badges)
- Better child spacing controls
child_margin/child_paddingnow apply to list items as well
- Fixed print behavior for long sections and publication lists
- Download button for saving CV as PDF via browser print dialog
- Proper print margins to prevent content from touching page edges
- Hugo Extended (v0.110.0 or later recommended)
- See install docs: https://gohugo.io/getting-started/installing/
The example site expects the theme at ./themes/jinli-cv. Create a symlink to point to the theme in the parent directory:
# Clone this repo
git clone https://github.com/jin-li/jinli-cv.git
cd jinli-cv/exampleSite
# Create symlink: themes/jinli-cv -> ../.. (the theme root)
mkdir -p themes
ln -s ../.. themes/jinli-cv
# Start the example site
hugo server -DSite runs at http://localhost:1313/.
# 1. Create a new Hugo site
hugo new site my-cv
cd my-cv
# 2. Initialize git
git init
# 3. Add this theme as a git submodule
git submodule add https://github.com/jin-li/jinli-cv.git themes/jinli-cv
# 4. Copy the example site content to your site root
cp -r themes/jinli-cv/exampleSite/* .
# 5. (Optional) Remove the example git tracking
rm -rf .git
# 6. Start the dev server
hugo server -DYour site structure will look like:
my-cv/
├── config.toml # Your site config
├── content/
│ └── _content.gotmpl # Dynamic CV page generator
├── data/
│ ├── content.yaml # Default CV (homepage)
│ ├── cv-de/
│ │ ├── config.toml
│ │ └── content.yaml
│ └── cv-zh/
│ ├── config.toml
│ └── content.yaml
├── static/
│ └── img/
│ └── avatar.png
└── themes/
└── jinli-cv/ # Theme submodule
Edit data/content.yaml with your information. See the example in themes/jinli-cv/exampleSite/data/content.yaml for all available fields.
Key sections:
Name:
first: Your
last: Name
order: first_last # or last_first
align: center # left, center, right
Avatar:
Photo: https://your-avatar-url.com/photo.jpg
Contacts:
- Icon: fas fa-envelope
Info: your@email.com
- Icon: fas fa-globe
Info: <a class="contact__link" href="https://your-site.com" target="_blank">your-site.com</a>
Profile: "Your professional summary..."
Experience:
- Employer: Company Name
Place: City, Country
Positions:
- Title: Senior Developer
Date: 2022 - Present
Details:
- Achievement 1
- Achievement 2
Badges: ["Go", "Docker", "Kubernetes"]
Education:
- Course: MSc Computer Science
Institution: University Name
Date: 2020 - 2022
Details:
- Thesis: "Your Thesis Title"Create a folder under data/ for each CV:
mkdir -p data/cv-de data/cv-frEach folder needs two files:
data/cv-de/config.toml:
slug = "cv-de"
title = "Lebenslauf"
languageCode = "de"
[params]
# Override any global params for this CV
section_order = ["profile", "experience", "projects", "education", "skills"]
side_section_order = ["avatar", "name", "contacts", "languages", "interests"]
showDownload = true
download_button = "top_right"data/cv-de/content.yaml:
Name:
first: Dein
last: Name
order: first_last
align: center
Avatar:
Photo: https://your-avatar-url.com/photo.jpg
Contacts:
- Icon: fas fa-envelope
Info: dein@email.de
Profile: "Dein professionelles Profil auf Deutsch..."
Experience:
- Employer: Firmenname
Place: Berlin, Deutschland
Positions:
- Title: Senior Entwickler
Date: 2022 - Heute
Details:
- Erfolg 1
- Erfolg 2
Badges: ["Go", "Docker", "Kubernetes"]Replace static/img/avatar.png with your own photo (recommended: square, ~400x400px).
Edit config.toml under [params] to override theme defaults:
[params]
colorPrimary = "#your-brand-color"
colorLight = "#fff"
colorDark = "#333"
colorPageBackground = "#f5f5f5"
# ... see exampleSite/config.toml for all optionsCreate assets/scss/_custom.scss in your site root:
// Override theme variables
$color-primary: #your-color;
$font-family-base: 'Your Font', sans-serif;
// Custom styles
.your-custom-class {
// ...
}# Clean build
hugo --cleanDestinationDir --minify
# Output will be in ./public/
# Deploy the contents of public/ to your hosting providerOption A: Connect your Git repo (easiest)
- Push your site to a Git repo (GitHub, GitLab, Bitbucket)
- Go to Netlify → Add new site → Import an existing project
- Select your repo
- Configure build settings:
- Base directory: Leave empty (or
themes/jinli-cv/exampleSiteif you cloned the theme repo directly) - Build command:
hugo --minify(orhugo --gc --minify) - Publish directory:
public
- Base directory: Leave empty (or
- Add environment variable:
HUGO_VERSION = 0.146.5(or your preferred version) - Click Deploy site
Option B: Use netlify.toml (recommended for reproducibility)
Create netlify.toml in your site root:
[build]
command = "hugo --minify"
publish = "public"
[build.environment]
HUGO_VERSION = "0.146.5"
# Optional: redirect www to non-www
[[redirects]]
from = "https://www.yourdomain.com/*"
to = "https://yourdomain.com/:splat"
status = 301
force = trueIf using the theme as a submodule, add this to netlify.toml:
[build]
command = "git submodule update --init --recursive && hugo --minify"
publish = "public"Netlify will automatically:
- Clone your repo
- Initialize submodules (fetches the theme)
- Run Hugo build
- Deploy to
https://your-site.netlify.app - Set up continuous deployment on every git push
Custom domain: Netlify DNS → Add custom domain → Follow verification steps.
Option A: GitHub Actions (recommended)
Create .github/workflows/hugo.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [main, master]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive # Important for theme submodule
fetch-depth: 0
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.146.5'
extended: true
- name: Build
run: hugo --minify --gc
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4Then in your repo settings:
- Go to Settings → Pages
- Source: "GitHub Actions"
- Your site will be at
https://yourusername.github.io/your-repo-name/
Option B: Manual deploy with gh-pages branch
# Build
hugo --minify --gc
# Deploy to gh-pages branch
cd public
git init
git add .
git commit -m "Deploy"
git push -f https://github.com/yourusername/your-repo.git master:gh-pages- Go to Cloudflare Pages → Create a project
- Connect your Git repo
- Build settings:
- Build command:
hugo --minify - Build output directory:
public - Root directory: Leave empty (or set if using subfolder)
- Build command:
- Environment variables:
HUGO_VERSION = 0.146.5 - Deploy!
- Go to Vercel → Add New Project
- Import your Git repo
- Framework preset: Hugo
- Build settings:
- Build Command:
hugo --minify - Output Directory:
public
- Build Command:
- Deploy!
Dockerfile:
FROM klakegg/hugo:0.146.5-ext AS builder
WORKDIR /src
COPY . .
RUN hugo --minify
FROM nginx:alpine
COPY --from=builder /src/public /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]nginx.conf:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Enable gzip
gzip on;
gzip_types text/css application/javascript;
# Cache static assets
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}Build and run:
docker build -t my-cv .
docker run -p 8080:80 my-cvThe theme automatically generates pages for each folder in data/ that contains both config.toml and content.yaml.
| Folder | slug in config.toml |
URL |
|---|---|---|
data/ (root) |
N/A | / (homepage) |
data/cv-de/ |
cv-de |
/cv-de/ |
data/cv-zh/ |
cv-zh |
/cv-zh/ |
data/cv-fr/ |
cv-fr |
/cv-fr/ |
Each data/<cv>/config.toml can override:
slug = "cv-fr" # Required: URL path
title = "CV Français" # Page title
languageCode = "fr" # i18n language code
[params]
# Any global param can be overridden per-CV
section_order = [...]
side_section_order = [...]
showDownload = true
colorPrimary = "#different-color"
# ... etcThe theme is designed for A4 printing:
- Open your CV in browser
- Press
Ctrl+P(orCmd+Pon Mac) - Settings:
- Paper size: A4
- Margins: None / Default (0.5cm top/bottom are built-in)
- Background graphics: Enabled (required for badges, gradients)
- Scale: 100%
Click Save as PDF to generate a print-ready PDF.
Section labels are translated via i18n/*.toml. Current languages:
| Code | Language | File |
|---|---|---|
en |
English | i18n/en.toml |
de |
German | i18n/de.toml |
es |
Spanish | i18n/es.toml |
eo |
Esperanto | i18n/eo.toml |
fr |
French | i18n/fr.toml |
pl |
Polish | i18n/pl.toml |
zh-cn |
Simplified Chinese | i18n/zh-cn.toml |
To add a language:
- Copy
i18n/en.tomltoi18n/your-code.toml - Translate all values
- Use
languageCode = "your-code"in your CV config
jinli-cv/
├── assets/
│ └── scss/ # SCSS source files
├── exampleSite/ # Complete example site
│ ├── config.toml
│ ├── content/
│ ├── data/
│ └── static/
├── i18n/ # Translation files
├── images/ # Screenshots for README
├── layouts/
│ ├── cv/ # CV page templates
│ ├── partials/ # Reusable partials
│ └── _default/ # Base templates
├── static/ # Static assets (fonts, etc.)
├── theme.toml # Theme metadata
└── LICENSE # MIT License
# Check version
hugo version
# Install specific version (macOS)
brew install hugo@0.146.5
# Or download from https://github.com/gohugoio/hugo/releasesEnsure your build command includes submodule init:
# netlify.toml
[build]
command = "git submodule update --init --recursive && hugo --minify"If you see module "jinli-cv" not found, add to your config.toml:
themesDir = "themes"
theme = "jinli-cv"- Enable Background graphics in print dialog
- Check browser print preview matches screen
- Ensure
hugo --minifydoesn't strip critical CSS (it shouldn't)
- Fork the repo
- Create a feature branch:
git checkout -b feature/my-feature - Commit changes:
git commit -am 'Add my feature' - Push:
git push origin feature/my-feature - Open a Pull Request
Issues and pull requests are welcome!
- Original theme: Almeida CV by Inês Almeida (MIT License)
- Fork & extensions: jin-li/jinli-cv (a.k.a. 锦鲤简历) by Jin Li
- Fonts: Oswald, Roboto, Material Icons, Font Awesome
MIT License - see LICENSE for details.
Copyright (c) 2020 Inês Almeida Copyright (c) 2024-2026 Jin Li
