Translation Management
debt(d7/e7/b7/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints note automated=no, and while tools like php-translation, symfony-translation, crowdin, and poeditor exist, they catch workflow gaps (missing translations, out-of-sync strings) rather than the structural mistakes like string concatenation or missing plural forms — those require code review or QA with native speakers. The problems are often invisible in development (English works fine) and only surface when actual translated content is displayed.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix describes adopting ICU message format, migrating to PHP arrays/YAML, and integrating external translation platforms. Fixing string concatenation patterns (__('You have') . $count . __('messages')) requires touching every such instance throughout the codebase, updating translation files, adding proper plural forms, and establishing a new workflow — this spans multiple files and components, trending toward cross-cutting.
Closest to 'strong gravitational pull' (b7). Translation management applies to web and CLI contexts across the entire application. Once strings are hardcoded or concatenated incorrectly, every new feature must follow the same broken pattern or risk inconsistency. The choice of i18n strategy shapes how all user-facing strings are written, how translators are engaged, and how plural/gender/register logic is handled — every future maintainer is affected by the established pattern.
Closest to 'serious trap' (t7). The misconception field directly states the trap: developers treat translation as mere string replacement, missing that languages have different word orders, up to 6 plural forms (Arabic), grammatical gender, and formal/informal registers. The common mistakes confirm this — the 'obvious' approach of concatenating translated fragments feels correct to an English-speaking developer but produces grammatically wrong output in many languages. This contradicts the intuitive mental model of 'just replace words.'
Also Known As
TL;DR
Explanation
Translation management involves: string extraction (identifying all translatable strings in code), storage format (gettext .po files, JSON, XLIFF, ICU), translator workflow (tools like Weblate, Crowdin, Lokalise), and deployment (compiling .po to .mo, importing JSON). PHP implementations: gettext() + ngettext() with .po/.mo files (compiled binary), symfony/translation component (multiple formats), Laravel's __() helper with JSON or PHP array files. Key principles: use ICU MessageFormat for pluralisation and complex messages, never concatenate translated strings (word order differs between languages), and extract strings with context to help translators.
Common Misconception
Why It Matters
Common Mistakes
- String concatenation: __('You have') . $count . __('messages') — word order breaks in many languages.
- No context for translators — 'Open' can mean open door, open file, or business status.
- Not using plural forms — ngettext() or ICU plural rules; hardcoded English plurals break other languages.
- Translating without a process — strings get out of sync between code and translation files.
Code Examples
// Concatenation breaks word order:
echo __('Hello') . ' ' . $userName . ', ' . __('you have') . ' ' . $count . ' ' . __('messages');
// German: 'Hallo Alice, Sie haben 5 Nachrichten' — word order different
// Cannot be correctly translated by substituting individual words
// ICU MessageFormat — full sentence with placeholders:
$message = $formatter->format(
'{greeting}, {name}! {count, plural, one {You have # message} other {You have # messages}}.',
['greeting' => __('Hello'), 'name' => $userName, 'count' => $count]
);
// Translator gets the full sentence with context
// Each language provides its own plural rules
// gettext with context:
$msg = pgettext('button label', 'Open'); // Different from pgettext('status', 'Open')