Skip to content

docs: German translation of the core guides, plus multilingual plumbing - #15627

Open
devGregA wants to merge 1 commit into
DefectDojo:bugfixfrom
devGregA:devgrega/docs-i18n
Open

docs: German translation of the core guides, plus multilingual plumbing#15627
devGregA wants to merge 1 commit into
DefectDojo:bugfixfrom
devGregA:devgrega/docs-i18n

Conversation

@devGregA

@devGregA devGregA commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Translates the 246 core guide pages (~257,000 words) into German, and adds the multilingual plumbing that every further language reuses. German is one language on purpose: it proves the whole pipeline end to end so the rest is repetition, not risk.

Layout choice

Translations sit beside their English source as <page>.de.md, not under a per-language contentDir. The contentDir approach would require moving every English page into content/en/, which breaks existing tooling and every open docs PR. English URLs are untouched: defaultContentLanguageInSubdir stays false, so English pages keep serving from the site root and German lands under /de/. Each translated page keeps the English slug, weight, aliases, and audience, so URLs, ordering, and the Open Source / Pro toggle behave identically in German.

Site chrome was the hidden half of this

The templates hardcoded their English text, so translating page bodies alone would have produced a German page with an English homepage, navigation, and footer. About sixty strings are now i18n lookups: nav labels, the homepage cards, the whole footer, the hero subtitle, and eleven screen-reader labels. Their terminology comes from the product UI catalogs (dojo/locale/<lang>/), so a severity or status word reads the same in the docs as it does in DefectDojo.

Two theme bugs fixed on the way

  • baseof.html now emits per-language lang and dir. The theme hardcoded the site-level language code and never emitted dir at all, so Arabic, Hebrew, Persian, and Urdu would have rendered left-to-right no matter how good the translation was.
  • Active-nav detection now strips the language prefix before comparing section segments. Without that, every item in a translated nav matched and rendered as the current page.

Scope

Translated: get_started (42), asset_modelling (41), admin (40), triage_findings (30), metrics_reports (21), automation (16), connectors (16), import_data (15), sensei (7), federal_compliance (7), navigation (6), help (3), issue_tracking (1), home.

Left English on purpose: releases/ changelogs (they churn with every release, and a stale translated changelog is worse than an English one) and supported_tools/ (219 pages of tables, scanner names, and CVE identifiers that are the same in any language). Nav entries for those sections point at the English URL, so nothing in a translated nav 404s.

Verification

  • Production build clean. English pages unchanged: 660 pages still build at the site root, and no English content file is modified by this branch (the diff is 246 new .de.md files, four new i18n/menu/docs files, and seven template or config edits).
  • All 246 pages passed the apply gates: fenced code blocks, shortcodes, link URLs, and heading structure identical to source, with the frontmatter whitelist enforced. Nothing partial is written for a page that fails.
  • 291 German pages build with zero {{< or {{% leakage in the rendered HTML (a broken shortcode renders literally, so this is the real test).
  • 0 of 246 pages identical to their English source; 88% carry German function words (the rest are short index pages that are mostly frontmatter).
  • Rendered locally: German nav, sidebar, TOC, title, and body all in German; active states correct in both languages.

A gate bug worth mentioning

Two long pages kept failing the fence gate on content that turned out to be correct. The gate paired code-fence markers with a regex anchored at column 0, so an indented or blockquoted opening fence ( ```yaml, > ```yaml) was skipped and that block's closing fence was mistaken for an opening one, which swallowed the following prose as "code" and hid its headings from the heading check. The gate now walks lines the way a markdown parser does. It is stricter than before, not looser: on one page it went from seeing 89 fenced blocks to all 98, and it now catches corruption inside blockquoted code that previously passed silently. Re-verified against eight deliberate mutations (translated code line, dropped fence, lost indentation, truncated body, demoted heading, rewritten URL) - all flagged, clean translations still pass.

Process

TRANSLATIONS.md documents the layout, what is and is not translated, how to add a language, and a quarterly refresh cadence. The refresh is incremental: --changed-since <ref> exports only pages whose English source moved, and any page whose English text is byte-identical carries its existing translation forward for free. That path is already proven here: this branch was resynced onto current bugfix mid-flight, and 64 of the 246 pages reused their earlier translation because their English had not changed.

Honest caveats

  • These are machine translations: integrity-checked, not meaning-checked. A native-speaker pass is the right next step before promoting a language heavily.
  • The remaining 26 languages' chrome strings are already translated and held outside the repo, so each additional language is its content run plus four files. A language is added to languages.toml only when its content lands, so the switcher never offers an empty language.
  • Trust Center and Status footer links from docs: link the Trust Center and Status page from the footer #15613 are not in this branch; whichever PR lands second should make those two labels i18n lookups as well.
  • One upstream page is named PRO__tagging_objects copy.md. It is draft: false and therefore live, so it is translated like any other page, but the filename looks accidental and is worth a separate cleanup.

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Adds a German locale to the documentation site and the theme plumbing a
second language needs.

Content: 246 German pages covering the core guides (get started, import
data, triage, asset modelling, metrics, issue tracking, admin,
automation, connectors, federal compliance, sensei, help, navigation).
Changelogs and the supported_tools parser reference are out of scope for
this pass. Pages use the filename-suffix layout (page.de.md) so the
English tree stays where it is and open pull requests keep applying.

Theme: about 60 hardcoded English strings in the layouts move to i18n
lookups (navigation, homepage cards, hero, footer, aria labels), with
i18n/en.toml and i18n/de.toml holding them and a per-language menu file
for the sidebar. Two bugs surfaced while wiring this up and are fixed
here: baseof.html emitted a fixed lang attribute and no dir attribute,
and the header active-state check matched every navigation item once
URLs carried a language prefix.

Navigation entries for untranslated sections point at the English pages
so nothing 404s. TRANSLATIONS.md documents the layout, the scope, how to
add a language, and the quarterly refresh.

These are machine translations checked for structural integrity, not
reviewed for meaning. A native-speaker pass is recommended before
treating the German pages as authoritative.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Conflicts have been resolved. A maintainer will review the pull request shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant