Localization
Understanding internationalization, translation mechanisms, language packs, and database translations.
Part A: Translation Mechanisms
Translation System Overview
Two Translation Mechanisms
Magento Translation Systems
1. Inline Translation
Characteristics:
- Limited fancy tool
- Translate phrases directly on website
- Frontend editing
- Quick for small changes
Use Case: Quick fixes, testing translations, store owner edits
2. Dictionary Translation
Characteristics:
- Comprehensive framework
- Translate everything
- CSV file based
- Systematic approach
Use Case: Full translation, professional work, multi-language sites
What Can Be Translated?
Dictionary Translation Supports
-  PHTML Templates - Using __()function
-  Email Templates - Using {{trans}}directive
-  PHP Files - Hardcoded phrases using __()
- JavaScript Files - Using translation functions
-  XML Files - Layout, configuration using translateattribute
- UI Components - Admin grids, forms, etc.
How Dictionary Translation Works
The Translation Process
Step-by-Step Workflow:
- Crawl - Special script scans code for translatable strings
- Generate CSV - Script creates CSV file with all phrases
- Translate - Human translator fills in translations in CSV
- Upload - Translated CSV uploaded back to system
- Substitution - Magento automatically replaces original with translated phrases
Translation Hints
How the Crawler Finds Strings
The crawler needs hints to find translatable strings. Two principal hints:
1. The __() Function
                Wrap strings in PHP/PHTML files:
<?= __('Hello World') ?>
<?= __('Welcome, %1', $name) ?>2. The translate Attribute
                Mark strings in XML files:
<label translate="true">
    Product Name
</label>PHTML File Translation
 Using __() in Templates
    
    Basic Usage:
<h1><?= __('Shopping Cart') ?></h1>
<p><?= __('You have items in your cart') ?></p>With Placeholders:
<?= __('Welcome, %1\!', $customerName) ?>
<?= __('You have %1 items in your cart', $itemCount) ?>
<?= __('Total: %1 %2', $currency, $total) ?>- Translates holistic phrases instead of fragments
- Provides context to translators
- Allows different word orders in different languages
- %1, %2, %3, etc. are replaced with actual values
Example with Multiple Placeholders:
<?= __(
    'Order #%1 was placed on %2 and is currently %3',
    $orderId,
    $orderDate,
    $orderStatus
) ?>Email Template Translation
 Using {{trans}} in Emails
    
    Email templates use a different syntax than PHTML files:
Basic Usage:
{{trans "Shopping Cart"}}
{{trans "Thank you for your order"}}With Variables:
{{trans "%items are shipping today." items=shipment.getItemCount()}}
{{trans "Hello %name" name=customer.name}}
{{trans "Order Total: %amount" amount=order.total}}- Use {{trans "..."}}instead of__()
- Pass variables using key=valuesyntax
- Use %variable_nameas placeholder in string
XML File Translation
 Using translate Attribute
    
    Layout XML (layout.xml)
    <block class="Magento\Framework\View\Element\Text">
    <arguments>
        <argument name="text" xsi:type="string" translate="true">
            Product Info Column
        </argument>
    </arguments>
</block>System Configuration (etc/adminhtml/system.xml)
    <section id="catalog" translate="label">
    <label>Catalog</label>
    <tab>catalog</tab>
    <resource>Magento_Catalog::config_catalog</resource>
    <group id="fields" translate="label">
        <label>Storefront</label>
    </group>
</section>DI Configuration (etc/di.xml)
    <type name="Magento\Catalog\Block\Product\View">
    <arguments>
        <argument name="data" xsi:type="array">
            <item name="label" xsi:type="string" translate="true">
                Block after Info Column
            </item>
        </argument>
    </arguments>
</type>translate="true" or translate="label" attribute to mark content as translatable. The crawler will find and extract these strings.
    JavaScript Translation
Translating JavaScript Strings
JavaScript files also support translation using jQuery's $.mage.__() function:
define([
    'jquery',
    'mage/translate'
], function ($) {
    'use strict';
    
    return function() {
        var message = $.mage.__('Hello World');
        var welcome = $.mage.__('Welcome, %1', customerName);
        
        alert(message);
    };
});- Import mage/translatemodule
- Use $.mage.__()function
- Supports placeholders like PHP version
Best Practices
Do's
- Always use placeholders for dynamic content
- Translate complete sentences, not fragments
- Provide context in comments for translators
- Use __()even if not translating yet
- Mark all user-visible strings as translatable
Don'ts
- Don't concatenate translated strings
- Don't translate system identifiers or codes
- Don't hardcode strings without translation functions
- Don't forget to add translateattribute in XML
Part B: Language Packs & i18n Tools
Internationalization (i18n)
What is i18n?
Internationalization (i18n) is the process of designing software to support multiple languages and regions. Magento has had strong i18n support since its early days.
- Automatic phrase collection from code
- CSV-based translation dictionaries
- Theme-specific translations
- Language packs for full localization
- Multiple fallback levels
i18n CLI Commands
Collecting Translatable Phrases
1. Collect Phrases for a Module
bin/magento i18n:collect-phrases app/code/Bonlineco/TestFinds all translatable strings within the specified path (module, theme, or entire installation).
2. Collect Phrases with Module Information
bin/magento i18n:collect-phrases -m-m Flag:
        Adds two additional columns to the output:
- type - Either "module" or "theme"
- module - The module name that uses this translation
This is essential for building language packages as it shows which module each phrase belongs to.
3. Collect Phrases for Entire Installation
bin/magento i18n:collect-phrases -m > translations.csvSearches entire Magento application (all modules and themes) for translatable strings and outputs to CSV.
Three Translation Sources
Translation Data Hierarchy
1. Theme Translation Dictionary
Location:
app/code/Vendor/Module/i18n/de_DE.csv
                Scope: Module or theme specific
Priority: First or second (after module)
2. Language Packs
Location:
app/i18n/Vendor/Language/
                Scope: Entire application
Priority: Third
3. Database Translations
Location:
translation table
                Scope: Store-specific
Priority: Highest (last)
Theme Translation Dictionary
Module/Theme-Specific Translations
Theme translation dictionaries allow specifying translations for a specific module or theme.
Structure:
app/code/Bonlineco/Test/
├── i18n/
│   ├── de_DE.csv
│   ├── fr_FR.csv
│   └── es_ES.csv
└── ...CSV Format:
"Shopping Cart","Warenkorb"
"Add to Cart","In den Warenkorb"
"Checkout","Zur Kasse"
"Welcome, %1","Willkommen, %1"- First column: Original string (English)
- Second column: Translated string
- Placeholders (%1, %2) remain unchanged
- File named as locale code (de_DE, fr_FR, etc.)
Creating Translation Dictionary:
Step 1: Collect phrases for your module
bin/magento i18n:collect-phrases app/code/Bonlineco/Test > phrases.csvStep 2: Translate the phrases (manually or service)
Step 3: Save as locale-specific CSV in i18n directory
app/code/Bonlineco/Test/i18n/de_DE.csv- Core module translations
- Third-party module translations
- Parent theme translations
Can be overridden by language packs and database translations.
Language Packs
Application-Wide Translation
Language packs provide translations for the entire Magento application, including all modules and themes.
Creating a Language Pack:
Step 1: Collect All Phrases
bin/magento i18n:collect-phrases -m > all_phrases.csvThe -m flag adds module information needed for language packs.
Step 2: Translate the CSV File
Have a professional translator complete the translations in the CSV file.
Step 3: Pack the Translations
bin/magento i18n:pack /absolute/path/to/translated.csv de_DEThis generates the necessary language pack files.
Step 4: Create Language Module
app/i18n/Bonlineco/de_DE/
├── de_DE.csv
├── registration.php
└── language.xmlregistration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::LANGUAGE,
    'bonlineco_de_de',
    __DIR__
);ComponentRegistrar::LANGUAGE type for language packs, not MODULE.
    language.xml
<?xml version="1.0"?>
<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:noNamespaceSchemaLocation="urn:magento:framework:App/Language/package.xsd">
    <code>de_DE</code>
    <vendor>Bonlineco</vendor>
    <package>de_de</package>
    <sort_order>100</sort_order>
    <use vendor="magento" package="de_de"/>
</language><use> Tag:
        You can include multiple <use> nodes. If Magento doesn't find a translation in your package, it searches through each <use> package (and their <use> nodes) until it finds a match.
Final Structure:
app/i18n/Bonlineco/de_DE/
├── de_DE.csv           <- Translations (from i18n:pack)
├── language.xml        <- Package configuration
└── registration.php    <- Component registrationLanguage Pack Example
Real-World Example
Popular language packs on GitHub:
- German: Magento2_German_LocalePack_de_DE
- French: Community-maintained i18n/Magento/fr_FR
- Spanish: Various community packages
- Install via Composer: composer require vendor/language-package
- Enable in Admin: Stores → Configuration → General → Locale Options
- Clear cache: bin/magento cache:flush
Fallback Chain
Translation Resolution
When Magento looks for a translation, it follows this chain:
Resolution Order:
- Check module's i18n dictionary
- Check theme's i18n dictionary
- Check language pack
- Check language pack's <use> packages
- Check their <use> packages (recursive)
- If none found, use original untranslated text
Best Practices
Do's
- Use language packs for complete translations
- Use theme dictionaries for theme-specific overrides
- Leverage community language packs
- Use i18n:collect-phrasesto find all strings
- Include module info with -mflag for packs
Don'ts
- Don't modify core translation files
- Don't skip -mflag for language packs
- Don't hardcode translations in custom code
- Don't forget to register language component
- Don't mix module and language registration types
Part C: Database Translations & Priority Order
Database Translations
 The translation Table
    
    Database translations are stored in the translation table and provide the highest priority translation source.
Advantages
- Easiest to implement - No files to edit
- Quick changes - Instant updates via admin
- Inline translation - Edit directly on frontend
- Highest priority - Overrides all other sources
- Store-specific - Different per store view
Disadvantages
- Difficult to replicate - Not in version control
- Not portable - Tied to specific installation
- Migration complexity - Must export/import
- Backup needed - Can be lost in DB issues
- No code review - Changes not tracked
Inline Translation
Enabling Inline Translation
Inline Translation allows translating phrases directly on the website frontend.
Enable in Admin Panel:
Path: Stores → Configuration → Advanced → Developer → Translate Inline
- Set Enabled for Storefront to "Yes"
- Set Enabled for Admin to "Yes" (optional)
- Save configuration
- Clear cache
How It Works:
- Translatable phrases appear with red borders (or hover highlight)
- Click on a phrase to open translation dialog
- Enter translation
- Submit to save to translationtable
- Translation immediately active (after cache clear)
While using Inline Translation, disable these caches:
- translate- Translation cache
- block_html- Block HTML output
- full_page- Full page cache
bin/magento cache:disable translate block_html full_pageCreating Database Translations
Two Methods
Method 1: Using Inline Translation (Recommended)
- Enable Inline Translation in Admin
- Navigate to page with string to translate
- Click on translatable text
- Enter translation in dialog
- Submit and clear cache
Method 2: Direct Database Insert (Manual)
Insert directly into translation table:
INSERT INTO translation (string, translate, store_id, crc_string)
VALUES (
    'Add to Cart',
    'In den Warenkorb',
    1,
    CRC32('Add to Cart')
);Limitation: Need to determine the correct module to associate the translation with.
Translation Priority Order
Complete Priority Hierarchy
Magento searches for translations in this specific order (lowest to highest priority):
app/code/Vendor/Module/i18n/locale.csv
app/design/frontend/Vendor/theme/i18n/locale.csv
app/i18n/Vendor/Language/locale.csv
translation table
Magento starts at #1 (module) and works up. If a translation is found at any level, it's used. Higher levels override lower levels.
Result: Database translations can override everything, making them perfect for quick fixes or store-specific customizations.
Pros & Cons Comparison
CSV Files vs Database
| Aspect | CSV Files (translate.csv) | Database (translation table) | 
|---|---|---|
| Portability | ✅ Easily replicated across instances | ❌ Tied to specific installation | 
| Version Control | ✅ Can be committed to Git | ❌ Not in version control | 
| Ease of Update | ⚠️ Must edit files manually | ✅ Quick via inline translation | 
| Store-Specific | ⚠️ Requires separate files | ✅ Easy per-store customization | 
| Migration | ✅ Copy files between environments | ⚠️ Must export/import database | 
| Professional Use | ✅ Preferred for complete translations | ⚠️ Better for quick overrides | 
| Priority | ⚠️ Lower priority | ✅ Highest priority (overrides all) | 
When to Use Which?
Use CSV Files When:
- Creating complete language translations
- Need version control
- Deploying to multiple environments
- Working with professional translators
- Building reusable language packs
- Need systematic approach
Use Database When:
- Quick one-off translations needed
- Store-specific customizations
- Testing translations before committing
- Client wants to make changes
- Overriding specific problematic translations
- Emergency fixes
Best Practices
Recommendations
- Primary translations: Use CSV files in language packs
- Overrides: Use database for quick fixes
- Document DB translations: Keep a list of manual DB translations
- Export before migration: Export DB translations if needed
- Disable inline in production: Only enable for authorized users
- Clear cache after changes: Always clear translation cache
- Use placeholders: Never concatenate translated strings
Common Pitfalls
- Forgetting to disable caches while using inline translation
- Not documenting database translations
- Losing DB translations during migration
- Mixing translation sources inconsistently
- Leaving inline translation enabled in production
Exam Tips
Key Points to Remember
- Two mechanisms: Inline translation (limited) and dictionaries (comprehensive)
- Translation hints: __()function andtranslateattribute
- PHTML: Use __('text')
- Email: Use {{trans "text"}}
- XML: Use translate="true"attribute
- JavaScript: Use $.mage.__('text')
- i18n CLI: bin/magento i18n:collect-phraseswith-mflag
- Three sources: Module/theme dictionaries, language packs, database
- Priority order: Module → Theme → Language Pack → Database (highest)
- CSV files: Portable, version controlled, better for complete translations
- Database: Quick edits, highest priority, not portable
- Inline translation: Easy to use but disable caches first
- Language pack registration: Use ComponentRegistrar::LANGUAGE
- Placeholders: %1, %2, etc. for dynamic content
