Skip to content

Translations: pages paired by ref, strings per language, language menu - #47

Merged
jcelerier merged 3 commits into
masterfrom
i18n
Oct 22, 2026
Merged

jcelerier merged 3 commits into
masterfrom
i18n

Conversation

@jcelerier

Copy link
Copy Markdown
Member

Replaces the two-language setup (translation: link per page, if lang == 'fr' in templates, "Lire cette page en français" line) with one that takes any number of languages.

How it works

  • A page and its translations share ref: in their front matter. From it: hreflang for every version + x-default, og:locale:alternate, and a language menu in the header (and in the mobile menu). On a page that is not translated, the menu leads to that language's home page.
  • _data/languages.yml: languages, menu order, Open Graph locale, home page.
  • _data/i18n/<lang>.yml: menu, footer, use-case layout, download buttons, cookie banner. A missing key falls back to English.
  • /js/consent.js is generated (strings of every language + _includes/consent.js), so the banner follows the page language; the docs keep loading the same URL.
  • _data/use_cases.yml keeps only order and group; nav_title and blurb move into each page. Untranslated use cases are listed with their English page.
  • npm run check:i18n (in the lint job): per-language report of untranslated pages and strings in the job summary; fails only on inconsistent data (two pages with the same ref and language, unknown language, use case without English page).
  • README: how to add a language.

Visible changes: language menu (EN ▾ / FR ▾) at the right of the header; French menu labels on French pages; footer links to use cases and privacy policy in the page's language instead of "Use cases · Usages (FR)". The header still stays on one line down to the mobile menu (checked 841–1440 px).

Checked locally: build, html-validate, privacy scan and axe audit (81 pages, 0 problems), Prettier, ESLint, keyboard (Enter opens, Esc closes and returns focus, click outside closes), French banner strings, and the report with a temporary es entry.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LnhJQb1bcRrYTvmX94BTzw

jcelerier and others added 3 commits October 21, 2026 18:46
…nguage menu

Instead of a single `translation:` link per page and `if lang == 'fr'` in the
templates, which only works for two languages:

- Pages and their translations share a `ref` in their front matter; the
  hreflang links, og:locale alternates and a language menu in the header
  (also in the mobile menu) are generated from it, for every language of
  _data/languages.yml. Untranslated pages lead to the language's home page.
- Interface strings (menu, footer, use-case layout and buttons, cookie banner)
  are in _data/i18n/<lang>.yml, with English as fallback for missing keys.
  /js/consent.js is now generated: the strings of every language, then the
  code from _includes/consent.js.
- _data/use_cases.yml only keeps order and group; titles and blurbs of the
  lists are in each page (nav_title, blurb); untranslated use cases are
  listed with their English page.
- The "Read this page in English / Lire cette page en français" lines are
  replaced by the menu. The footer links go to the use cases and privacy
  policy in the page's language.
- npm run check:i18n (in CI) reports untranslated pages and strings per
  language, and fails on inconsistent refs or unknown languages.
- The header keeps one line down to the mobile menu with the language menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnhJQb1bcRrYTvmX94BTzw
…oad page in the page's language

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnhJQb1bcRrYTvmX94BTzw
Home (/fr/), score, libossia, libossia download, docs overview, gallery,
about and project history, next to the use cases, download page and
privacy policy already translated. Blog, documentation and the libossia
binding pages stay in English.

- Shared bodies in includes (home-content, score-features-grid,
  libossia-features, gallery-works), with interface strings from
  _data/i18n; French fields next to the English ones in _data/gallery.yml
  (ossia_fr, award_fr, place_fr, artists_fr, title_fr), _score_features and
  _libossia_features (title_fr, description_fr, tag_fr).
- Header menu, logo link, footer and the about pages' side menu lead to
  the page in the current language; the language menu's French home is /fr/.
- Links inside French pages go to the French versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnhJQb1bcRrYTvmX94BTzw
@jcelerier

Copy link
Copy Markdown
Member Author

Added French versions of the main pages: home (/fr/), score, libossia, libossia download, docs overview, gallery, about, project history and the download page. Blog, score-docs and the libossia binding pages stay in English. Header, footer and side menus lead to the page in the current language; links inside French pages go to French versions. Checked: build, html-validate, privacy scan and axe (90 pages), translation report (31/31 pages, 136/136 strings), and a scan for links to the wrong language (0).

@jcelerier
jcelerier merged commit ca3ca2a into master Oct 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant