Skip to content

Latest commit

 

History

622 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

arc42.org Website

Live at arc42.org

Built with Jekyll and served by Netlify.

Stack: Jekyll 4 (Ruby) · Minimal Mistakes theme (fully vendored) · Docker Compose for local development · Netlify for build & deploy.


Local development

All development runs in Docker — no local Ruby, Bundler, or Jekyll needed, just Docker and make.

make build     # build the dev image once (installs the pinned gems — needs network)
make dev       # start Jekyll with live reload at http://localhost:4200

make dev serves on 4200, the first slot in the arc42 42xx block. Every site in the family has its own fixed port so their dev servers can run side by side — see raw/port-assignment.md in meta.arc42.org for the full assignment. The number is stated explicitly in three places rather than inherited from Jekyll's default, so it stays honest if this site ever moves: SITE_PORT in the Makefile, the mapping plus --port in docker-compose.yml, and EXPOSE/CMD in the Dockerfile.

Everything after the first make build works fully offline (e.g. on a train): the gems are baked into the Docker image and the theme is vendored into the repo, so no build step reaches out to the network.

Make targets

Command What it does
make help List all targets.
make dev Start the dev server with live reload at http://localhost:4200.
make build Build the arc42-site:latest Docker image from the pinned gems.
make site Generate the static site into _site/.
make check-links Build, then validate internal links/images/HTML with html-proofer.
make shell Open a shell inside the container for debugging.
make install Refresh gems in the image after editing the Gemfile.
make update Update gems to their latest allowed versions (rewrites Gemfile.lock).
make stop Stop and remove the running container.
make logs Tail the dev server logs.
make clean Remove _site/ and local caches.

After make update (or any change to Gemfile.lock), the container refuses to serve until you re-run make build — the entrypoint compares the lockfile against the gems baked into the image and fails loudly on drift, so you never run against stale gems.


Theme

The Minimal Mistakes theme (v4.24.0) is vendored into this repository — its _layouts/, _includes/, _sass/, and assets/js/ live here directly rather than being pulled from a remote theme or gem at build time. This keeps builds fully offline and puts every template under version control. arc42-specific customizations (masthead, footer, head, SCSS) sit alongside the stock theme files and override them via Jekyll's normal precedence.

Deployment

Netlify builds and deploys on push. The build configuration lives in netlify.toml (build command, publish directory, JEKYLL_ENV=production) and the Ruby version is pinned in .ruby-version — these override the Netlify dashboard's build settings.


Resources library

The /resources/ page (books, articles, talks, videos) is data-driven. Every entry is a single Markdown file in the _resources/ collection — no HTML to touch, no counts to maintain.

Add a resource

Drop one file in _resources/, e.g. _resources/my-new-talk.md:

---
type: talk                 # book | article | talk | video   (required)
title: "My new talk"       # required
language: en               # en | de                         (required)
year: 2026                 # optional — undated items sort to the end
summary: "One-line description shown on the card."   # required
search: "extra author keywords for the filter"       # optional
cover: /images/resources/my-new-talk.webp            # optional (see Thumbnails)
link: https://speakerdeck.com/...                    # optional — omit for no link
link_label: "Open slides"                            # optional CTA text
id: my-anchor              # optional — for deep links like /resources/#my-anchor
---

That's it. The listing template (_includes/resource-item.html) renders the card; _pages/resources.md loops the collection, sorts by year descending (undated last), and computes the type-badge counts in Liquid — so the numbers can never drift out of sync with the files.

The link arrow is derived from the URL, so it stays consistent: internal , external (plus rel="noopener"), and .pdf .

Thumbnails

Set cover: to any image path and the card shows that thumbnail. Omit it and the card falls back to a color-coded letter marker (Book / Article / Talk / Video). This works for every type, not just books.

  • New thumbnails (articles, talks, videos): put them in /images/resources/.
  • Existing book covers live in /images/books/ — leave them there.

The thumbnail box is portrait-ish (4rem × 5.5rem) with object-fit: contain, so both portrait covers and landscape stills fit without distortion.

Detail pages (opt-in)

Each resource also gets its own page at /resources/<slug>/ (the collection is output: true). Most are minimal landing pages generated from the front matter; add detail: true to promote one and the listing card links to it ("More details →") instead of straight out.

Write Markdown below the front matter and it becomes the body of that detail page — headings, lists, a longer description, a cover, a buy/watch button (from link:). _resources/effektive-softwarearchitekturen.md is the worked example; the layout is _layouts/resource.html.

Remember: sitemap.xml is maintained by hand. When you publish a detail: true page, add its URL there — the other auto-generated item pages are orphaned landing pages and are intentionally left out of the sitemap.

Translators (About page)

The translator credits in the /about/ page's community section are data-driven from _data/translators.yml. Add or edit people there — no HTML to touch.

Add a translator

One block per person (not per language):

- name: "Mario Giustiniani"   # required
  language: "Italiano"        # required — in its own script
  bio: "One to three sentences."                        # optional
  portrait: "/images/translators/mario-giustiniani.webp" # optional
  links:                                                # optional — list of labelled links
    - label: "GitHub"
      url: "https://github.com/mgiustiniani"

The About page (_pages/about.md) renders this in two tiers:

  1. Full credit roll — every entry, grouped by language (co-translators of one language auto-join with commas and "and"). A name links to its first links: entry when present.
  2. "Meet some of our translators" — entries that have a bio or a portrait, shown as cards. The whole tier stays hidden until at least one entry qualifies, so it never looks half-finished.

Portraits and the monogram fallback

  • With portrait: → the card shows that image (square, round-cropped via CSS). Put portraits in /images/translators/ as ~320px square webp.
  • Without portrait: → the card falls back to an initials monogram on a tinted disc (e.g. "Damien Lucas" → DL), so cards with and without a photo sit together cleanly.

Styles live under .translator-grid / .translator-card in assets/css/arc42-org.css. No sitemap entry is needed — this is a section of an existing page, not a new URL.

How does the search page work?

Three pieces, no dependencies:

  • search.json builds the index at compile time — one entry per page that has a real front-matter title, which is also what keeps the redirect stubs in _pages/ and the asset templates out of it. Roughly 14 entries.
  • assets/js/arc42-search.js fetches that index and does the matching and ranking in the browser.
  • _pages/search.html is the page itself: a search box, a results list, and a <script> tag.

Two rules in the matcher are worth knowing before you change it:

Terms match only at the start of a word. A plain substring test makes c4 match every page mentioning arc42 — "arc42" — which is what the previous implementation did, returning 13 of 14 pages. Prefix typing still works, so archi finds "architecture". The boundary is expressed as (?:^|[^a-z0-9]) rather than a (?<!…) lookbehind, because Safari only gained lookbehind in 16.4.

Results are scored, not just filtered. Title hits count 10, URL hits 4, body hits 1 each up to 5 per term, with ties broken by title so ordering is stable between builds. Without this the results arrive in Jekyll's page-emission order, which put the 20-years blog post above /canvas/ for the query "canvas".

This replaced Simple-Jekyll-Search, which could do neither: its matcher was a raw field.indexOf(term) and its sort comparator returned a constant 0.

Training dates

The training block (_includes/subtle-ads/subtle-ads.html, embedded on five pages: home, learn, documentation, examples, download) is rendered at build time from _data/trainings.json — an expiry-filtered copy of https://trainings.arc42.org/api/trainings.json that .github/workflows/refresh-trainings.yml refreshes and commits only when the dates actually changed. The workflow runs on three triggers: a weekly cron (Mondays 05:47 UTC), manual workflow dispatch, and a repository_dispatch event (trainings-updated) that the trainings repo pushes right after the feed republishes — so date changes propagate within minutes instead of waiting up to a week. The push is an accelerator, never a dependency (ADR-0006 in meta.arc42.org): if it never arrives, the cron still bounds staleness at one week, and a failed fetch simply leaves the last committed snapshot in place. Edit dates in the trainings repo's _data/trainings.yml, never here; _includes/subtle-ads/subtle-ads.html owns the rendering, assets/css/subtle-ad.css the styling. This replaced the former runtime htmx fetch from the Vercel fragment backend (see the integration spec in the arc42 workspace's docs/superpowers/specs/2026-08-04-docs-faq-training-dates-design.md).

Credits

Michael Rose, creator of the Minimal-Mistakes Jekyll Theme

Icons + Images:

  • Free images can be found at Unsplash
  • I bought several icons from IconFinder, a great source for professional-grade icons. Recommended!
  • I generated the various favicon files with RealFavIconGenerator.

Licenses

arc42 Template

The arc42 template is licensed under a CreativeCommons Sharealike International 4.0 License.

You are free to:

  • Share — copy and redistribute the template in any medium or format
  • Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The MIT License (MIT)

Copyright (c) 2016ff Michael Rose

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

(jekyll-based) website for arc42.org - the template for communicating software architectures.

Topics

Resources

Stars

6 stars

Watchers

3 watching

Forks

Used by

Contributors

Languages