Translation Management
Also Known As
gettext
Weblate
i18n workflow
translation strings
po files
TL;DR
Organising, extracting, and synchronising translatable strings — gettext .po/.mo files, ICU MessageFormat, and tools like Weblate or Crowdin for translator workflows.
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
✗ Translation is just string replacement — languages have different word orders, plural forms (Arabic has 6), grammatical gender, and formal/informal registers; correct translation requires context and ICU MessageFormat for dynamic content.
Why It Matters
Concatenating translated fragments ('You have' . $count . 'messages') produces grammatically wrong sentences in many languages where adjectives, verbs, and nouns change based on count and gender.
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
✗ Vulnerable
// 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
✓ Fixed
// 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')
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
34
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 8
Perplexity 7
Google 5
Unknown AI 4
Ahrefs 2
ChatGPT 2
Also referenced
How they use it
crawler 27
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Medium
⚡ Quick Fix
Store translations in PHP arrays or YAML, use the ICU message format for pluralisation and variables, and integrate Crowdin or POEditor for non-developer translators
📦 Applies To
PHP 5.0+
web
cli
🔗 Prerequisites
🔍 Detection Hints
Translations hardcoded in PHP files; no plural forms support; string concatenation with translated parts (breaks right-to-left languages)
Auto-detectable:
✗ No
php-translation
symfony-translation
crowdin
poeditor
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File
Tests: Update