Complete guide to managing publications on your Jekyll academic website.
- Quick Start
- Workflow Overview
- Managing Your BibTeX File
- Adding Publication Links
- Link Validation
- Common Tasks
- Scripts Reference
- Troubleshooting
# 1. Edit BibTeX file
vim files/publications.bib
# 2. Regenerate data file with validation
uv run python .github/scripts/publications/bibtex_to_data.py
# 3. Preview locally
docker compose -f .github/dev/docker-compose.yaml up
# 4. Visit http://localhost:4000/publications/📄 Edit this file: files/publications.bib
🚫 Don't edit: _publications/*.md files (auto-generated, may be deprecated)
Your publications flow through this pipeline:
┌─────────────────────────┐
│ files/publications.bib │ ← Edit this (source of truth)
└──────────┬──────────────┘
│
│ uv run python .github/scripts/publications/bibtex_to_data.py
▼
┌─────────────────────────┐
│ _data/publications.yml │ ← Auto-generated YAML data file
└──────────┬──────────────┘
│
│ Jekyll reads data file directly
▼
┌─────────────────────────┐
│ /publications/ page │ ← Rendered on website
└─────────────────────────┘
Key advantage: Publications page reads directly from the data file. No intermediate markdown files needed!
Location: files/publications.bib
@inproceedings{}- Conference papers@article{}- Journal articles@misc{}- Preprints, technical reports@phdthesis{}- PhD thesis@book{}- Books
@inproceedings{citationkey2024,
title = {Paper Title}, % Required
author = {Author One and Author Two}, % Required (use " and " separator)
year = {2024}, % Required
booktitle = {Conference Name}, % Required for @inproceedings
}@inproceedings{citationkey2024,
title = {Paper Title},
author = {Carlo Ciliberto and Others},
year = {2024},
booktitle = {NeurIPS},
% Links (all optional) - NEW naming scheme
url_paper = {https://arxiv.org/abs/...}, % External paper link
local_paper = {papers/my-paper-2024.pdf}, % Local PDF (relative to files/)
url_code = {https://github.com/user/repo}, % External code repository
local_code = {code/my-project-2024.zip}, % Local code archive
url_slides = {https://slides.com/...}, % External slides
local_slides = {slides/presentation-2024.pdf}, % Local slides PDF
url_video = {https://youtube.com/watch?v=...}, % External video
local_video = {videos/presentation-2024.mp4}, % Local video file
}Backward compatibility: The old field names (url, pdf, code, slides, video) still work!
Priority: url_* is checked first, then local_*, then old field names.
Recommendation: Use the new url_* / local_* naming for clarity when tracking materials.
Use format: firstauthorYEARkeyword
Examples:
ciliberto2024operatornovelli2023metasmith2025learning
Your name will be automatically bolded if it appears as:
- "Carlo Ciliberto"
- "C. Ciliberto"
Important: Separate authors with " and " (with spaces):
# ✓ Correct
author = {Alice Smith and Bob Jones and Carlo Ciliberto}
# ✗ Wrong
author = {Alice Smith, Bob Jones, Carlo Ciliberto}Add external links to papers (ArXiv, conference proceedings, etc.):
@inproceedings{paper2024,
title = {My Paper Title},
author = {Carlo Ciliberto and Others},
year = {2024},
url = {https://proceedings.neurips.cc/paper/...}, % ← Add this
}Best sources for URLs:
- Conference proceedings (NeurIPS, ICML, CVPR, etc.)
- ArXiv:
https://arxiv.org/abs/... - Journal websites
- Your institutional repository
If you have a local copy of the paper:
1. Copy PDF to the correct directory:
cp ~/Downloads/my-paper.pdf files/papers/my-paper-2024.pdf2. Update BibTeX entry:
@inproceedings{paper2024,
title = {My Paper},
author = {Carlo Ciliberto},
year = {2024},
pdf = {papers/my-paper-2024.pdf}, % Relative to files/ directory
}3. Naming convention (recommended):
- Use lowercase with hyphens
- Include year in filename
- Example:
learning-kernel-methods-2024.pdf
You can have both! Local PDF will take priority.
@inproceedings{paper2024,
title = {My Paper Title},
author = {Carlo Ciliberto and Others},
year = {2024},
url = {https://arxiv.org/abs/...}, % External link
pdf = {papers/my-paper-2024.pdf}, % Local PDF
code = {https://github.com/username/repo}, % Optional: code
slides = {https://slides.com/...}, % Optional: slides
video = {https://youtube.com/...}, % Optional: video
}For unpublished work or papers you don't want to link, simply omit url and pdf fields.
The bibtex_to_data.py script automatically validates all links:
uv run python .github/scripts/publications/bibtex_to_data.pyAfter running, you'll see a color-coded report:
================================================================================
PUBLICATION LINK VALIDATION REPORT
================================================================================
Summary:
Total publications: 74
✓ With valid links: 60
⚠ Without any links: 10
✗ With link issues: 4
Publications without links:
⚠ [2023] My Unpublished Work
BibTeX key: unpublished2023
Publications with link issues:
✗ [2022] Paper with Broken Link
BibTeX key: paper2022
- url: HTTP 404
- ✓ With valid links (green) - All good!
- ⚠ Without any links (yellow) - Need to add
urlorpdf - ✗ With link issues (red) - URL returns error (403/404/timeout)
HTTP 403/418 errors: Some websites block automated requests. The links likely work fine in browsers. You can:
- Keep the URL anyway (it will work for users)
- Add a local PDF instead
- Disable validation (see below)
PDF not found: Make sure the path is correct:
# ✅ Correct
pdf = {papers/my-file.pdf} % Relative to files/
# ❌ Wrong (includes 'files/' prefix)
pdf = {files/papers/my-file.pdf}
# ❌ Wrong (absolute path)
pdf = {/Users/carlo/files/papers/my-file.pdf}- Open
files/publications.bib - Add new entry at the top or bottom:
@inproceedings{mycitation2025,
title = {My New Paper Title},
author = {Author One and Author Two and Carlo Ciliberto},
booktitle = {NeurIPS},
year = {2025},
url = {https://arxiv.org/abs/2025.xxxxx},
}- Run:
uv run python .github/scripts/publications/bibtex_to_data.py - Restart Jekyll:
docker compose down && docker compose -f .github/dev/docker-compose.yaml up
- Open
files/publications.bib - Find and delete the entire entry (from
@type{key,to closing}) - Run:
uv run python .github/scripts/publications/bibtex_to_data.py - Restart Jekyll
- Open
files/publications.bib - Find the entry by searching for the title or author
- Edit any field
- Run:
uv run python .github/scripts/publications/bibtex_to_data.py - Restart Jekyll
If you have PDFs in old_site_backup/papers/:
# Find PDFs in old site
find old_site_backup/papers -name "*.pdf" -type f
# Copy relevant ones
cp old_site_backup/papers/weakly-supervised-13/weakly_supervised.pdf \
files/papers/weakly-supervised-2013.pdfThen update BibTeX entry with: pdf = {papers/weakly-supervised-2013.pdf}
grep -i "paper title" files/publications.bibgrep -c "^@" files/publications.bibLocation: .github/scripts/publications/bibtex_to_data.py
Purpose: Converts BibTeX → YAML data file with link validation
Usage:
uv run python .github/scripts/publications/bibtex_to_data.pyWhat it does:
- Reads
files/publications.bib - Generates
_data/publications.yml - Validates all external URLs (5-second timeout)
- Checks for local PDF files
- Generates validation report
Location: .github/scripts/publications/bibtex_to_publications.py
Purpose: Converts BibTeX → Individual markdown files
Usage:
uv run python .github/scripts/publications/bibtex_to_publications.pyNote: This script may be deprecated if you're using the data file workflow.
Edit the script to adjust validation behavior:
# Disable URL validation (faster but less thorough)
VALIDATE_URLS = False # Line 26
# Adjust timeout for slow connections
TIMEOUT = 10 # Line 25 (default is 5 seconds)Check:
- Did you run
bibtex_to_data.pyafter editing BibTeX? - Did you restart Jekyll? (
docker compose down && docker compose -f .github/dev/docker-compose.yaml up) - Check
_data/publications.ymlwas generated - Visit
http://localhost:4000/publications/
Check:
- PDF file exists in
files/papers/directory - Path in BibTeX is relative to
files/(not absolute) - No
files/prefix in thepdffield - Jekyll includes
filesin_config.yml:include: - files
Some websites block automated requests. Options:
- Keep the URL anyway (it will work for users)
- Disable URL validation:
VALIDATE_URLS = False - Use a local PDF instead
Try:
# Full restart
docker compose down
docker compose -f .github/dev/docker-compose.yaml up --build
# Clear browser cache
# Hard reload: Cmd+Shift+R (Mac) or Ctrl+Shift+R (Windows/Linux)Make sure your name appears exactly as:
- "Carlo Ciliberto" or
- "C. Ciliberto"
Check the _pages/publications.html template if you need different formatting.
your-site/
├── files/
│ ├── publications.bib ← Source of truth (edit this!)
│ └── papers/ ← Local PDFs go here
│ ├── paper-name-2024.pdf
│ ├── another-paper-2023.pdf
│ └── ...
├── _data/
│ └── publications.yml ← Auto-generated (don't edit)
├── _publications/ ← May be deprecated (check if used)
│ ├── 2024-01-paper-name.md
│ └── ...
├── scripts/
│ └── publications/
│ ├── bibtex_to_data.py ← Main script
│ ├── bibtex_to_publications.py
│ └── extract_to_bibtex.py
└── _pages/
└── publications.html ← Template (reads from data file)
Complete workflow from start to finish:
# 1. Edit BibTeX file
vim files/publications.bib
# 2. Add a local PDF (if needed)
cp ~/Downloads/awesome-paper.pdf files/papers/awesome-paper-2024.pdf
# 3. Update BibTeX entry
# (add: pdf = {papers/awesome-paper-2024.pdf})
# 4. Regenerate and validate
uv run python .github/scripts/publications/bibtex_to_data.py
# 5. Review validation report
# (fix any issues identified)
# 6. Preview locally
docker compose -f .github/dev/docker-compose.yaml up
# 7. Check in browser
open http://localhost:4000/publications/
# 8. Commit changes
git add files/publications.bib files/papers/ _data/publications.yml
git commit -m "Update publications"
git push- Prefer official sources for URLs (conference proceedings, journals, ArXiv)
- Use local PDFs for papers not available online
- Run validation regularly before committing changes
- Organize PDFs consistently (e.g.,
paper-name-year.pdf) - Check validation report to catch broken links early
- Keep BibTeX file clean - use consistent formatting
- Test locally before pushing to GitHub
- Total publications: 74
- Format: BibTeX (
files/publications.bib) - Main script:
.github/scripts/publications/bibtex_to_data.py
If you encounter issues:
- Check this guide first
- Review the validation report output
- Check MIGRATION_HISTORY.md for technical migration details
- Search existing BibTeX entries for examples
Key Points:
- ✅
files/publications.bibis your single source of truth - ✅ Use
urlfor external links,pdffor local files - ✅ Place local PDFs in
files/papers/ - ✅ Run
uv run python .github/scripts/publications/bibtex_to_data.pyafter changes - ✅ Review validation report and fix issues
- ✅ Preview with
docker compose -f .github/dev/docker-compose.yaml upbefore pushing - ✅ Publications page reads directly from
_data/publications.yml
End of Guide