Public website for the Health AI Research (HealthAI) group at the Institute of Data Science, Maastricht University.
Static site — no build step, no framework. Pages are plain HTML files that load structured content from content/*.yaml at runtime via cms.js. All content edits go in YAML; the HTML is not hand-edited for content.
| File | Purpose |
|---|---|
index.html |
Homepage — hero, recent news, recent publications |
people.html |
Group members, filterable by theme |
publications.html |
Publication list with search, year slider, cite/BibTeX |
research.html |
Research themes and projects |
news.html |
News, blog posts, talks, podcasts — unified search/filter |
students.html |
Student projects (not linked from nav) |
cms.js |
YAML loader and shared rendering utilities |
nav.js |
Navigation bar and footer |
styles.css |
Global styles |
| File | What it drives |
|---|---|
content/people.yaml |
Group members — Faculty and Researchers sections |
content/publications.generated.yaml |
Publications (auto-generated — do not hand-edit) |
content/research.yaml |
Research themes and projects |
content/news.yaml |
News items, blog posts, talks, podcasts |
content/site.yaml |
Site-wide metadata |
content/students.yaml |
Student project listings |
Each entry has: name, role, group, image_url, themes, bio, keywords, orcid, github, google_scholar, linkedin, personal_page, cris_url, work_url, email.
groupis eitherFacultyorResearchers- On
people.html, the Researchers group is split byrole: entries withrole: PhD Researcherappear under "PhD Researchers"; all others appear under "Postdocs, Researchers, and Research Software Engineers" github,google_scholar,linkedinstore bare handles/IDs (not full URLs)cris_url,work_url,personal_pagestore full URLsimage_urlshould be a local path (assets/people/<slug>.jpg) — never a hotlinked LinkedIn URL
The file has four top-level sections:
news—day,month,year,title,body; optionalurlblog— managed byfetch_blog_posts.py; fields:title,url,date,author,excerpt,sourcetalks—event,date,title,speaker,type; optionalurl(e.g. Zenodo DOI link), optionaldescriptionpodcasts—show,episode,title,guest,duration,date,icon
All scripts are in scripts/ and require Python 3.
python3 scripts/add_people.py "Full Name" "https://www.maastrichtuniversity.nl/<profile-slug>"Scrapes the UM staff page for bio, portrait photo, ORCID, and CRIS URL, then appends an entry to content/people.yaml. Review the entry afterward — the script defaults role to PhD Researcher; correct it if needed.
Run in order:
# 1. Fetch each person's ORCID works summary
python3 scripts/fetch_orcid_works.py [--refresh] [--name <substring>]
# 2. Fetch Crossref metadata for all unique DOIs
python3 scripts/fetch_crossref.py
# 3. Build publications.generated.yaml
python3 scripts/build_publications.pyCaches live in cache/orcid/, cache/crossref/, cache/abstracts/, and cache/summaries/. The pipeline is incremental — re-running only fetches new DOIs.
Optional: fetch full abstracts and generate plain-language summaries (requires Ollama running locally):
python3 scripts/fetch_abstracts.py
python3 scripts/generate_summaries.pypython3 scripts/fetch_blog_posts.py [--dry-run]Reads blog_feed URLs from content/people.yaml and syncs posts into the blog section of content/news.yaml. Manual entries (no source: feed field) are always preserved.
python3 scripts/enrich_people.pyRe-scrapes UM profile pages to refresh image_url and bio for existing entries. Caches HTML under cache/people_pages/.
The site is a static file tree — deploy by pushing to the main branch. No build step required.
See LICENSE.