Skip to content

i18n: Phase 4 — translate all remaining content (15 files)#12

Merged
abonforti merged 5 commits into
azzurra:masterfrom
vjt:i18n/content-translations
May 10, 2026
Merged

i18n: Phase 4 — translate all remaining content (15 files)#12
abonforti merged 5 commits into
azzurra:masterfrom
vjt:i18n/content-translations

Conversation

@vjt
Copy link
Copy Markdown
Contributor

@vjt vjt commented May 10, 2026

Scope

This is PR-2 of N, stacked on top of #11 (i18n scaffold).

Because GitHub doesn't support cross-fork base branches, the base here is master — so until #11 merges, this PR's diff will appear to contain the scaffold changes too. Review #11 first, merge it, and this PR's diff will automatically shrink to only the 15 new files.

The branch graph: masteri18n/scaffold (#11) ← i18n/content-translations (this PR).

What's translated

8 root pages — translated slugs matching [languages.en] menu URLs

IT EN slug URL
storia.en.md history /en/history
come-connettersi.en.md connect /en/connect
contatti.en.md contact /en/contact
faq.en.md faq /en/faq
kline.en.md kline /en/kline
network.en.md network /en/network
regolamento.en.md rules /en/rules
servizi.en.md services /en/services

7 news posts — kept the IT filename, English-y slugs

IT EN slug
azzurra-rinasce-come-azzurra-chat.en.md azzurra-reborn-as-azzurra-chat
nickserv-resetpass.en.md nickserv-resetpass
nuovi-server-2026.en.md new-servers-2026
nuovo-sito-2008.en.md new-website-2008
nuovo-sito.en.md new-website
riorganizzazione-2020.en.md reorganisation-2020
webchat-operativa.en.md webchat-back-online

_index.md is intentionally left IT-only (the parity gate excludes section indexes — Hugo handles the EN section listing automatically from the .en.md posts).

Internal-link policy

All internal links inside the EN files were rewritten to point at /en/<slug> targets:

  • /storia/en/history
  • /contatti/en/contact
  • /regolamento/en/rules
  • /come-connettersi/en/connect
  • /kline/en/kline

This way an EN reader never gets bounced back to Italian via internal navigation.

Smoke build

hugomods/hugo:exts-0.145.0:

                   | IT | EN
-------------------+----+-----
  Pages            | 42 | 41
  Static files     |  5 |  5
  Aliases          | 12 | 11

Total in 115 ms — zero i18n warnings

Translation method

LLM-pre-translated, then sanity-passed for tone (kept the staff voice, the "See you in chat 👋" sign-off, emoji where they were in the IT version). Straight prose translation.

Deferred to PR-3 (Phase 5)

aliases: on EN pages so old IT-slug-under-/en/ paths (e.g. /en/storia) don't 404 from any external link minted before this scaffold went live. Out of scope here.

vjt added 2 commits May 10, 2026 21:07
Phase 1 (config split):
- hugo.toml restructured into [languages.it] (default, served at /) and
  [languages.en] (served at /en/)
- defaultContentLanguageMissing left at "fallback" implicitly so missing
  EN pages render the IT version instead of 404
- Stats labels and menu names translated per-language

Phase 2 (theme i18n extraction):
- themes/azzurra/i18n/{it,en}.toml with ~22 keys
- All hardcoded UI strings in baseof / index / list / single / info
  shortcode replaced with {{ i18n "key" }}
- Internal links use relLangURL so /en/ pages keep their language prefix

Phase 3 (date format):
- dateFormat key per language, rendered via time.Format which honors the
  page's languageCode → "10 maggio 2026" on /it, "May 10, 2026" on /en

Sample translation:
- content/news/gamebot.en.md as proof-of-concept; same slug across langs

Parity gate:
- .githooks/pre-commit blocks any commit that adds/modifies content/*.md
  without a sibling .en.md (excludes _index.md and *.en.md itself)
- .github/workflows/i18n-parity.yml mirrors the check server-side as the
  non-bypassable gate; --no-verify only skips the local fast-iteration hook

Smoke build (hugomods/hugo:exts-0.145.0): clean, IT+EN sites render,
58 pages total, zero i18n warnings.
Hypnotize requested:
1. Parity gate must work both ways: an EN content file without an IT
   counterpart should also block. Refactored .githooks/pre-commit and
   .github/workflows/i18n-parity.yml to enforce sibling existence in
   either direction.
2. Add vjt (vjt@azzurra.chat) to the staff mailto block in baseof.

Bonus: workflow trigger branch fixed master (was main).

Smoke build still green: IT 42 + EN 16 pages, zero warnings.
vjt added 3 commits May 10, 2026 21:40
The original full-tree scan blocked PR#11 because the scaffold ships only
one sample .en.md while the rest of content/ is still IT-only — exactly
the state PR#12 is meant to fix. Bidirectional enforcement still applies,
just only to files touched in the current PR (mirrors the delta-based
.githooks/pre-commit hook). The incremental scaffold → content → aliases
landing pattern now works without each PR having to ship a complete set.
Replaces the filename-suffix layout (content/foo.md + content/foo.en.md
with slug overrides) with explicit directory split. Translated pages now
live under their own language tree with English filenames matching the
public URL, so reviewers see content/en/news/gamebot.md rather than
content/news/gamebot.en.md with slug=gamebot — the github file URL no
longer contradicts the language of the content.

Pairing across languages is declared via the translationKey frontmatter
field rather than inferred from a shared filename stem. The scaffold
sample (news/gamebot) ships paired with translationKey: news-gamebot on
both sides; PR#12 adds the matching keys on the other pages as their EN
counterparts land.

hugo.toml: per-language contentDir lets Hugo route each tree
independently. defaultContentLanguage=it keeps IT URLs at the root
(no /it/ prefix), EN remains at /en/.

Parity gate: the pre-commit hook and the GitHub Action workflow both
switch from filename-stem matching to translationKey matching, using
identical extraction logic. Pages without a translationKey are treated
as not-yet-paired (free pass) — the gate enforces well-formed pairs, it
does not force every page to be translated. Only declared keys must
resolve in the other language tree.

Smoke build: hugo 0.145.0+extended → IT 42 + EN 16 pages, zero warnings,
gamebot sample renders at /en/news/gamebot/ (filename = slug).
Adds the English siblings under content/en/ (matching the dir-split
layout from the previous commit), with translationKey wiring to the
Italian originals under content/it/. Eight root pages (connect, contact,
faq, history, kline, network, rules, services) plus seven news posts
(azzurra-reborn-as-azzurra-chat, new-servers-2026, new-website-2008,
new-website, nickserv-resetpass, reorganisation-2020, webchat-back-online).

URLs follow the language tree natively now: IT at /<it-slug>/ and EN at
/en/<en-slug>/, no slug overrides needed in frontmatter.

Italian sources gain a translationKey field but are otherwise unchanged.
@vjt vjt force-pushed the i18n/content-translations branch from 151a86d to f37a258 Compare May 10, 2026 21:55
@abonforti abonforti marked this pull request as ready for review May 10, 2026 22:00
@Essency Essency self-requested a review May 10, 2026 22:06
@abonforti abonforti merged commit 9168ae8 into azzurra:master May 10, 2026
1 check 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.

3 participants