CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Website of the football club AS Wëntger (www.asw.lu): a plain GitHub Pages + Jekyll site using the github-pages gem.
GitHub builds and publishes it on every push to main; there is no separate deploy step. Content, YAML comments and
commit-facing texts are in Luxembourgish — keep new UI text and data comments in Luxembourgish too.
README.md is the editor-facing documentation (includes, menu, sponsors, Facebook/Instagram token setup).
Commands
docker compose up --build # first time (needs internet); afterwards: docker compose up → http://localhost:4001
bundle exec jekyll serve --port 4001 # same, with local Ruby
bundle exec jekyll build # what the "Check links" workflow runs, followed by:
htmlproofer ./_site --disable-external --checks Links --allow-hash-href --ignore-files "/redirect/"
- The dev container uses
--incremental --force_polling; changes to_config.ymlneed a restart. - There are no tests or linters; the only CI check is the internal link check above (a broken internal link makes the commit ✗).
- Data fetchers (Python 3.12, run by scheduled GitHub Actions which commit their output):
python tools/fetch_matches.py,fetch_rankings.py,fetch_facebook.py(needsFB_PAGE_TOKEN),fetch_instagram.py,fetch_shop.py.
Architecture
- Pages:
pages/**getlayout: pageandpermalink: /:basename/via_config.ymldefaults, so the URL is the file name only — sub-folders just mirror the menu, and basenames must be unique acrosspages/. Renames needredirect_from:in the front matter plus an update of_data/menu.yml(the menu is data-driven, up to 3 levels, rendered by_includes/nav.html). - Root-relative URLs everywhere: write
/kalenner/,/images/...._layouts/default.htmlpost-processes the rendered HTML and prefixessite.baseurlonto every="/…"andurl("/…so the site also works under a GitHub project path. - Data-driven content (
_data/*.yml) rendered by includes; most pages are thin shells calling an include:ekippen.yml(teams: FLF/FuPa ids, calendar category) →ekipp.html,ekippen-carousel.html,ranking.html,spielplan.html.persons.ymlis the single source for all people; each person hasroleswithgroup=comite,supporterclub,asw-reporter, a commission id (kommissiounen.yml) or a team id (ekippen.yml).person-list.htmlcollects and sorts them (sortOrder → roleName → name);person-card.htmlderives the photo path from the name:"SCHOLZEN Guy"→/images/persons/scholzen_guy.{jpg,jpeg,png,webp}(slugified, no accents; UPPERCASE words = surname), initials if missing. Photos are 4:5.sponsors.yml,deals.yml,terrainen.yml,sportzeitung.yml,aswreporter.yml— schema documented in each file’s header comment.
- Generated data — do not edit by hand (overwritten by workflows):
_data/calendar_matches/(hourly, from api.asw.lu; the fetcher deliberately strips volunteer/referee personal data),_data/rankings/(hourly, FLF or FuPa),_data/facebook_posts.json+assets/fb/,_data/instagram_stories.json+assets/ig/,_data/shop.json+images/shop/. Because bots push often,git pull --rebasebefore pushing. - Styling: Sass partials in
_sass/(_nav,_layout,_components,_cms,_base,_fonts) compiled viaassets/css/main.scss; club colours come fromcolors:in_config.yml. Fonts are self-hosted inassets/fonts/. Client JS:assets/js/site.js(menu etc.) andassets/js/match-calendar.js. - Images are stored as WebP.
_site/is build output (git-ignored); never edit it. - Never commit raw WordPress exports (
*.WordPress.*.xml) — they contain personal data.










