Pelican migration - #6
Conversation
Replaces the Jekyll/Ruby build with a Pelican-based workflow managed
entirely within the Python ecosystem using uv.
- Add pyproject.toml and uv.lock (Pelican, pelican-sitemap, typogrify)
- Add pelicanconf.py and publishconf.py replacing _config.yml
- Migrate all content pages to content/pages/ with Pelican metadata
- Move assets/ into content/assets/ to match Pelican's content layout
- Add custom theme (themes/) with Jinja2 templates and CSS
- Implement dual color scheme (MSU brand / CERL) via separate theme
CSS files, selectable at build time via COLOR_SCHEME in pelicanconf.py
- Convert Jekyll Liquid figure shortcodes to inline HTML img tags
- Update bin/create_pubs.sh to output Pelican metadata format and
write to content/pages/pubs.md
- Update templates/pubs-template.md bibliography path for new layout
- Update CLAUDE.md with revised build and publishing workflow
The original Jekyll files (_config.yml, Gemfile, root .md pages) are
retained on the main branch and are not part of this migration.
Add bin/create_pubs.py using pypandoc (bundled binary) to generate content/pages/pubs.md from the BibTeX file, eliminating the system dependencies on pandoc and gawk required by bin/create_pubs.sh. The old shell script is kept as a reference.
uv-managed environment)
…version of the apa.csl file rather than requiring internet access.
- base.html: homepage canonical now resolves to / instead of /home/
- pelicanconf.py: narrow STATIC_PATHS to assets/img so the .bib file
is not copied into the site output
- publishconf.py: anchor sys.path to the file's own directory instead
of the process working directory; update SITEURL to msucerl.org
- deploy.yml: enable uv dependency caching in CI
- create_pubs.py: add trailing newline and explicit UTF-8 encoding to write_text
- pelicanconf.py: remove dead FEATURE_IMAGE key (feature hero is disabled in template)
- CLAUDE.md: correct theme path (themes/ not themes/cerl/), update hosted URL
to msucerl.org, remove stale feature hero and FEATURE_IMAGE references
- about.md: add Status: hidden so the stub isn't published or sitemapped - pelicanconf.py: strip dead articles/indexes keys from SITEMAP config - style.css: remove unused .feature-hero/.feature-overlay rules and --font-serif variable - CLAUDE.md: fix index.html template description and color theme mechanism description
Both theme-cerl.css and theme-msu.css now include a dark variant that activates automatically based on the user's OS preference. Header and nav are unchanged (already dark); the overrides cover body background, text, headings, accents, borders, aside, and footer. Accent colors are lightened relative to their light-mode values to maintain contrast on dark backgrounds.
Uses the native <picture> element to serve the white-text variant (CERL_squirrel_nobackground_whitetext_v2.png) in dark mode and the existing black-text logo in light mode. No JS or CSS changes needed.
Enables Pelican's article system to power a lab news and blog feed:
- content/posts/ — new directory for post files; includes a welcome post
- news.html / article.html — templates for the index and individual posts
- pelicanconf.py — enable ARTICLE_PATHS, add URL/save-as config for
news/{year}/{slug}/, add DIRECT_TEMPLATES/NEWS_SAVE_AS for the index,
suppress individual category/tag/author pages, restore sitemap config
for articles and indexes, add "News & Perspectives" as second nav item
- base.html — active nav state now handles article pages and news index
- style.css — news list and article meta/back-link styles
Documents the post metadata format and workflow for creating new entries in content/posts/, covering Title, Date, Author, Slug, and Summary fields.
Rewrites the homepage blurb to more fully describe CERL's research focus, methods, and interdisciplinary scope across three colleges. Moves Publications to the end of the nav bar, fixes section header float-clearing on the People page so "External Collaborators" is properly separated from the bio above it, and adds News & Perspectives post documentation to README and CLAUDE.md.
Fixes a CLAUDE.md inaccuracy (COLOR_SCHEME only needs to be set in pelicanconf.py; publishconf.py inherits it), removes the unused yaml-metadata.template left over from the old pandoc workflow, and expands the commented-out feature hero block in index.html with re-enablement instructions in case it's wanted again.
There was a problem hiding this comment.
Pull request overview
Completes the CERL website migration from Jekyll to Pelican by introducing a custom Pelican theme (templates + CSS), converting site content to Pelican’s metadata/header format, and updating CI/CD to build/deploy via uv + GitHub Actions (including a Python publications generator).
Changes:
- Added a Pelican theme (
themes/) with page/article/news templates and CSS variable–driven color schemes (plus dark mode tokens). - Replaced the old publications build script with
bin/create_pubs.pyand added a vendored APA CSL file + BibTeX source. - Replaced Jekyll tooling/config with Pelican configs (
pelicanconf.py,publishconf.py), apyproject.toml, and a new Actions deploy workflow.
Reviewed changes
Copilot reviewed 32 out of 80 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| themes/templates/page.html | New Pelican page template. |
| themes/templates/news.html | New /news/ index template. |
| themes/templates/index.html | New homepage template with aside + logo handling. |
| themes/templates/base.html | New base layout with header/nav/footer + canonical link logic. |
| themes/templates/article.html | New article (news post) template. |
| themes/static/css/theme-msu.css | MSU color tokens (light/dark). |
| themes/static/css/theme-cerl.css | CERL color tokens (light/dark). |
| themes/static/css/style.css | New global layout/typography + news/article styles. |
| templates/yaml-metadata.template | Removed legacy pandoc template (Jekyll-era). |
| templates/pubs-template.md | Updated pandoc input template for pubs generation. |
| templates/apa.csl | Vendored APA CSL style for offline citeproc. |
| README.md | Updated local dev + editing workflow docs for Pelican/uv. |
| pyproject.toml | Added Python project deps (Pelican, plugins, pypandoc binary). |
| publishconf.py | Added Pelican production config (SITEURL, output deletion). |
| pelicanconf.py | Added Pelican site config (paths, URLs, theme, menu, sitemap). |
| index.md | Removed old Jekyll homepage content file. |
| Gemfile.lock | Removed Ruby/Jekyll dependency lockfile. |
| Gemfile | Removed Ruby/Jekyll dependency manifest. |
| content/posts/welcome.md | Added initial News & Perspectives post. |
| content/pages/pubs.md | Converted pubs page to Pelican metadata format + updated content. |
| content/pages/projects.md | Converted projects page and replaced Jekyll include with <img>. |
| content/pages/people.md | Converted people page and replaced Jekyll includes with <img>. |
| content/pages/outreach.md | Converted outreach page to Pelican metadata format. |
| content/pages/home.md | Added Pelican homepage content + template/save_as metadata. |
| content/pages/curriculumdev.md | Converted curriculum dev page to Pelican metadata format. |
| content/pages/about.md | Added placeholder About page (hidden). |
| content/assets/styles.scss | Added SCSS file (appears Jekyll/Alembic-era). |
| content/assets/bib/group_publications.bib | Added bibliography source for pubs generation. |
| CLAUDE.md | Added repo workflow/architecture guidance for Claude Code. |
| bin/create_pubs.sh | Updated legacy shell script paths/front matter (still present). |
| bin/create_pubs.py | Added Python pubs generation script using pypandoc + CSL. |
| about.md | Removed old Jekyll about page. |
| 404.md | Removed old Jekyll 404 page. |
| .gitignore | Updated ignores for Python/Pelican artifacts. |
| .github/workflows/deploy.yml | New Actions workflow: build all branches; deploy main only. |
| _includes/site-aside.html | Removed Jekyll include file. |
| _includes/figure.html | Removed Jekyll include file. |
| _config.yml | Removed Jekyll site configuration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/msu-cerl/msu-cerl.github.io/sessions/218d8094-a1e0-4392-88bd-eda68bcd2071 Co-authored-by: devinsilvia <6162515+devinsilvia@users.noreply.github.com>
Implemented the requested review-thread updates in commit
Screenshot of updated UI: Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/msu-cerl/msu-cerl.github.io/sessions/a64ce8e0-175a-4310-9f3f-b519f95a1051 Co-authored-by: devinsilvia <6162515+devinsilvia@users.noreply.github.com>
Applied the requested thread updates in commit
Screenshot: Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Adds a skip-to-main-content link for keyboard users, marks the active nav item with aria-current="page", and corrects the heading hierarchy across all content pages and templates — page titles are now h1, section headers h2, entries h3, and sub-headings h4. Also updates the README uv install instructions and float-clearing CSS to cover h2.
Adds aria-label="Main" to the nav, aria-label="About CERL" to the homepage aside, and wraps individual post content in <article>. Hides the redundant "Read the full post" link from assistive technology via aria-hidden/tabindex (the title link is already descriptive). Extends the prefers-reduced-motion block to disable CSS transitions.
Adds a --color-nav-active token to each theme with a darkened version of the accent color, giving ~5.7:1 contrast against the header text — above the 4.5:1 AA threshold. Uses the new token for the active nav background in place of --color-accent.
Adds underlines to body links so color is not the sole indicator, resolving the WCAG color-only link requirement. Adds --color-aside-link tokens to both themes with darkened colors that pass 4.5:1 contrast on the aside background in light mode, and overrides them in the dark mode blocks to use the bright accent colors appropriate for dark backgrounds.
Adds --frozen to uv sync in CI for reproducible builds. Expands STATIC_PATHS from "assets/img" to "assets" so any file placed under content/assets/ is served without further config changes. Deletes the stale about.md placeholder. Adds underlines to news item title links for consistency with body link treatment. Documents STATIC_PATHS behavior and the Typogrify HTML attribute gotcha in CLAUDE.md.
| {% if article.summary %}<p class="news-item-summary">{{ article.summary }}</p>{% endif %} | ||
| <a class="news-item-more" href="{{ SITEURL }}/{{ article.url }}" aria-hidden="true" tabindex="-1">Read the full post →</a> |
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/msu-cerl/msu-cerl.github.io/sessions/030f70af-7e68-43a7-b730-1535787422a3 Co-authored-by: devinsilvia <6162515+devinsilvia@users.noreply.github.com>
Applied in commit Screenshot: Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
index.html was the only template without a page title heading, leaving the homepage as the only page on the site without an h1.
|
OK, this probably isn't perfect, but best I can tell, this migration to Pelican is sufficiently complete to warrant making the switch. I'm going to go ahead and merge this in! |
Summary
This PR completes the migration of the CERL website from Jekyll to Pelican, a Python-based static site generator. Here's what's included:
uvworkflow; all content pages converted to Pelican-compatible Markdown with plain key-valuemetadata headers
themes/directory with Jinja2 templates, a layout/typography stylesheet, and two color schemes (cerl,msu) driven entirely by CSScustom properties
@media (prefers-color-scheme: dark); includes a separate squirrel logo with white text for dark backgrounds/news/backed bycontent/posts/; posts are listed in reverse chronological order with summaries and "Readthe full post" links
bin/create_pubs.pyreplaces the old shell/gawk script; usespypandocwith a vendored APA CSL file (no network or systempandoc required at build time)
main; updated to opt into Node.js 24README.mdupdated to reflect the new workflow, content structure, and common editing tasks andCLAUDE.mdadded for future development with Claude Code assistance.Test plan
uv run pelican content -s publishconf.py) completes without errors/news/lists posts with summaries; individual post pages render correctlymsucerl.orgafter mergeThis migration was developed with assistance by Claude Code