Jekyll site with Sass styling using npm. Development happens on master, and deployment is done by pushing the built site to gh-pages.
sudo apt update
sudo apt install -y ruby-full build-essential zlib1g-dev
sudo apt install -y nodejs npmsudo pacman -Syu --needed ruby base-devel
sudo pacman -Syu --needed nodejs npmBy default, gem install tries to write to system directories and requires sudo. To keep everything in your home directory, add the following to your shell config (~/.bashrc, ~/.zshrc, etc.):
export GEM_HOME="$HOME/.gem"
export PATH="$GEM_HOME/bin:$PATH"Then reload your shell (exec bash, exec zsh, etc. or open a new terminal) and install Bundler:
gem install bundlerFrom the repository root:
bundle config set --local path 'vendor/bundle'
bundle install
npm installThis installs Ruby gems into vendor/bundle/ (project-local) and Node packages into node_modules/. Both are gitignored.
Run all
bundleandnpmcommands from the project directory.
Create a worktree for the gh-pages branch in the _deploy directory (only needs to be done once):
git worktree add --orphan -b gh-pages _deploy
touch _deploy/.nojekyll- Compile Sass to CSS:
npm run scssThe scss script in package.json watches assets/scss/main.scss and compiles the single production bundle to assets/css/main.css. It runs in the foreground, so open a second terminal for Jekyll.
- Run Jekyll:
bundle exec jekyll serve --unpublishedSite will be available at http://localhost:4000. This command also runs in the foreground. You can stop it with Ctrl+C when done.
If
Gemfileorpackage.jsonchange (e.g., aftergit pull), re-runbundle installand/ornpm installbefore building.
- Config: _config.yml
- Pages: _pages/
- Projects collection: _projects/
- Layouts: _layouts/
- Includes: _includes/
- Site copy and publications: _data/
- Sass/SCSS sources: assets/scss/
- Compiled CSS bundle:
assets/css/main.css - Local fonts and licences: assets/fonts/
To add a new project, create a new Markdown file in the _projects/ directory with the following front matter:
---
layout: project
title: "Plain-text project title"
short_title: "Optional short name"
description: "Metadata description for search and link previews."
summary: "Plain-text summary for project listings."
published: true
featured: false
status: active
updated: 2026-07-24
tags:
- cosmology
thumbnail:
src: /assets/images/projects/example.svg
alt: "Scientifically meaningful image description"
links:
code: https://example.com
data: https://example.com
math: true
zoom: true
---Projects are automatically listed on the Projects page. featured: true also places them on the homepage, while published: false excludes unfinished projects from production builds. Keep title and summary free of HTML and MathJax. Use math and zoom only when the project content needs those enhancements.
Publications are curated in _data/publications.yml, newest first:
- id: stable-citation-key
title: "Paper title"
authors:
- "Author One"
- "Author Two"
year: 2026
venue: "Journal or preprint"
doi: "10.xxxx/example"
arxiv: "2601.00001"
project: project-file-slug
featured: trueproject matches the filename slug in _projects/. When that project is published, the publication list and project page link to each other.
Data downloads are rendered by _includes/mirror.html as full-width rows that name the destination host, describe the payload, and surface access notes in a highlighted strip. Facts that repeat across articles live once in _data/mirrors.yml:
kooplex:
name: "ELTE Kooplex"
domain: "datashare.vo.elte.hu"
url: "https://datashare.vo.elte.hu/metalnx/"
note_label: "Sign in"
note: "Log in with the username <code>anonymous</code> and leave the password field empty."Per-dataset details stay next to the prose that describes them. Wrap one or more rows in a .mirror-set:
<div class="mirror-set">
<p class="mirror-set__label">Download mirrors</p>
{% include mirror.html host="kooplex" label="All 138 snapshots" format="HDF5" filesize="1.5 GB / snapshot" %}
{% include mirror.html host="helsinki-sharepoint" label="Four selected snapshots" badge="Partial" format="HDF5" href="https://example.com/deep-link" %}
</div>| Parameter | Purpose |
|---|---|
host |
key in _data/mirrors.yml; supplies name, domain, url and note |
href |
per-dataset deep link; falls back to the host's landing url |
name, domain |
override the registry, or replace it entirely |
label |
what this mirror gives you |
format, filesize |
pill-shaped chips, rendered only when present |
badge |
short qualifier such as Partial |
note, note_label |
per-call access note, inline HTML allowed |
hide_note |
true suppresses the host's registry note |
action |
call-to-action text, defaults to Download |
.mirror-set spans the full width of .project-article and .page-surface, so it works in both projects and regular pages. For a download link inside a table cell, reuse the pill on its own: <a class="mirror__action mirror__action--compact" …>.
Verified affiliation, contact, and About-page copy live in _data/site.yml. Empty optional values are intentionally hidden rather than replaced with invented public copy.
Regular pages reside in _pages/ and normally use the pages layout:
---
layout: pages
title: "Page Title"
eyebrow: "Optional section label"
description: "Page summary used in the introduction and metadata."
permalink: /page-url/Edit _includes/navigation.html. Use aria-current="page" for the active route rather than a visual-only class.
<li>
<a href="{{ '/people/' | relative_url }}"{% if page.url contains '/people/' %} aria-current="page"{% endif %}>People</a>
</li>Make sure to place it in the correct position within the <ul> to maintain the desired order of menu items.
Important: The site is built from
gh-pages, notmaster. Keepgh-pagesclean: it should contain only the built site (i.e., the contents of the_site/folder after runningbundle exec jekyll buildon themasterbranch), and nothing else.
Important: Ensure you already have the
gh-pagesworktree set up in_deploy/as described in the Project setup section above. This only needs to be done once.
- On
master, compile the CSS and build the site without the--unpublishedflag to exclude draft posts:
npm run scss:build
bundle exec jekyll build- Navigate to the
gh-pagesbranch using the worktree that resides in the special_deploydirectory:
cd _deploy- Replace contents of the
gh-pagesworktree with the latest build:
git pull origin gh-pages # Ensure you have the latest changes
rsync -av --delete ../_site/ . --exclude .git --exclude .nojekyll- Commit and push:
git add -A
git commit -m "build $(date -Iseconds)" # Using ISO 8601 format for precise timestamps
git push origin gh-pages- Switch back to
masterto continue development:
cd -- Always ensure you are on the correct branch (
masterfor development,gh-pagesfor deployment) before running build or deployment commands. - Built output is in
_site/(ignored via .gitignore). - For a stricter pre-deployment check, run
JEKYLL_ENV=production bundle exec jekyll build --strict_front_matter. - The
gh-pagesbranch should only contain the built site. Do not commit source files or development changes togh-pages.