PHPackages                             elcheco/translator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. elcheco/translator

ActiveLibrary[Localization &amp; i18n](/categories/localization)

elcheco/translator
==================

Translation system using neon files, supports plurals and string replacements, fallback language. Extension to Nette Framework ^3.0

v2.0.6(8mo ago)21.9kBSD-3-ClausePHPPHP &gt;=8.3

Since Oct 4Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/elcheco/translator)[ Packagist](https://packagist.org/packages/elcheco/translator)[ RSS](/packages/elcheco-translator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (11)Versions (18)Used By (0)

ElCheco Translator
==================

[](#elcheco-translator)

[![Downloads this Month](https://camo.githubusercontent.com/9d24f5daed51233a7151c405b0c4c104b8b3e62293a8b3ef027f9e4ac6f0f748/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f656c636865636f2f7472616e736c61746f722e737667)](https://packagist.org/packages/elcheco/translator) [![License](https://camo.githubusercontent.com/fa7d5fcf2c84b580327af52da95dd751703af65f079dc3c5a0081beac0789718/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4e65772532304253442d626c75652e737667)](https://github.com/elcheco/translator/blob/master/LICENSE)

A powerful and flexible translation library for PHP applications with support for both NEON files and database storage, featuring full Unicode CLDR plural rules support.

Features
--------

[](#features)

- **CLDR Plural Rules Support** - Full Unicode CLDR compliance for accurate pluralization
- **Legacy Format Compatibility** - Seamless support for existing numeric plural formats
- **Multiple Storage Backends** - NEON files or database storage
- **Advanced Pluralization** - Support for all CLDR categories (zero, one, two, few, many, other)
- **Decimal Number Support** - Correct handling of decimal plurals (e.g., Czech uses 'many' for decimals)
- **Locale-Specific Number Formatting** - Automatic number formatting based on locale
- **Translation Usage Tracking** - Monitor which translations are actually used
- **Console Commands** - Import, export, and convert translations
- **Migration Tools** - Convert legacy formats to CLDR standard
- **Fallback Locale Support** - Automatic fallback when translations are missing
- **Compatible with Nette Framework** - Full integration with Nette DI

What's New in Version 2.0
-------------------------

[](#whats-new-in-version-20)

- 🎉 **CLDR Plural Rules** - Industry-standard pluralization for 100+ languages
- 🔢 **Decimal Number Support** - Proper handling of fractional numbers in plurals
- 🔄 **Automatic Format Detection** - Use legacy and CLDR formats in the same project
- 🛠️ **Migration Tools** - Convert existing translations to CLDR format
- 📊 **Enhanced Database Support** - Store CLDR patterns and ICU MessageFormat
- ⚡ **Zero Breaking Changes** - Full backward compatibility maintained

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- Nette Framework 3.0 or higher (if using with Nette)
- Dibi database library (if using database storage)
- PHP Intl extension (recommended for CLDR support)

Installation
------------

[](#installation)

```
composer require elcheco/translator
```

Configuration
-------------

[](#configuration)

### Basic Configuration (Nette DI)

[](#basic-configuration-nette-di)

```
extensions:
    translator: ElCheco\Translator\Extension
```

### NEON File-Based Translations

[](#neon-file-based-translations)

```
translator:
    default: en_US     # Default locale
    fallback: en_US    # Fallback locale
    debugMode: %debugMode%
    dictionary:
        factory: ElCheco\Translator\NeonDictionary\NeonDictionaryFactory
        args:
            directory: %appDir%/translations    # Directory with NEON files
            cache: %tempDir%/cache/translations # Cache directory
            autoRefresh: %debugMode%            # Auto refresh translations
```

### Database-Based Translations

[](#database-based-translations)

```
translator:
    default: en_US     # Default locale
    fallback: en_US    # Fallback locale
    dictionary:
        factory: ElCheco\Translator\DbDictionary\DbDictionaryFactory
        args:
            - @Dibi\Connection  # Database connection
            - MyModule           # Module name
            - true               # Track usage
    commands:
        - ElCheco\Translator\Console\ImportNeonTranslationsCommand(@Dibi\Connection)
        - ElCheco\Translator\Console\ExportNeonTranslationsCommand(@Dibi\Connection)
        - ElCheco\Translator\Console\ConvertToCldrCommand(@Dibi\Connection) # NEW!
```

CLDR Plural Rules Support
-------------------------

[](#cldr-plural-rules-support)

The translator now supports the Unicode CLDR (Common Locale Data Repository) standard for plural rules, providing linguistically correct pluralization for all languages.

### What are CLDR Plural Rules?

[](#what-are-cldr-plural-rules)

CLDR defines standardized categories for plural forms:

- **zero**: For zero items (some languages have special forms)
- **one**: For singular (but not always just 1!)
- **two**: For dual forms (e.g., Slovenian)
- **few**: For small quantities (e.g., 2-4 in Czech)
- **many**: For larger quantities or special cases (e.g., decimals in Czech)
- **other**: The default/general plural form

### CLDR vs Legacy Format

[](#cldr-vs-legacy-format)

The translator supports both formats simultaneously:

#### Legacy Format (still supported):

[](#legacy-format-still-supported)

```
messages_count:
    0: You have no messages
    1: You have %s message
    2: You have %s messages

# Czech with ranges
days_count:
    1: %s den
    "2-4": %s dny
    5: %s dní
```

#### CLDR Format (recommended):

[](#cldr-format-recommended)

```
messages_count:
    zero: You have no messages
    one: You have one message
    other: You have {count} messages

# Czech with proper decimal support
days_count:
    one: {count} den
    few: {count} dny
    many: {count} dne      # for decimals like 1.5, 2.5
    other: {count} dní
```

### Special Case: Czech Decimals

[](#special-case-czech-decimals)

Czech (and Slovak) use the `many` category specifically for decimal numbers:

```
# Czech translations
distance:
    one: "{count} kilometr"      # 1 kilometr
    few: "{count} kilometry"     # 2, 3, 4 kilometry
    many: "{count} kilometru"    # 1.5 kilometru, 2.5 kilometru
    other: "{count} kilometrů"   # 0, 5, 6... kilometrů
```

This ensures grammatically correct output:

- ✅ 1,5 kilometru (not "kilometrů" or "kilometr")
- ✅ 2,5 kilometru (not "kilometry")

Usage
-----

[](#usage)

### In Presenters or Services

[](#in-presenters-or-services)

```
use ElCheco\Translator\Translator;

class BasePresenter extends \Nette\Application\UI\Presenter
{
    private Translator $translator;

    public function injectTranslator(Translator $translator)
    {
        $this->translator = $translator;
    }

    public function beforeRender()
    {
        // Set translator for templates
        $this->template->setTranslator($this->translator);
    }

    public function handleSwitchLocale(string $locale)
    {
        $this->translator->setLocale($locale);
        $this->redirect('this');
    }
}
```

### In Templates (Latte)

[](#in-templates-latte)

```
{* Simple translation *}
{_'Welcome to our website'}

{* Translation with parameters *}
{_'Hello %s', $userName}

{* Legacy plural format *}
{_'You have %s new messages', $count}

{* CLDR format with automatic number formatting *}
{_'items_count', $itemCount}

{* Decimal numbers are formatted correctly *}
{_'distance_km', 1.5} {* Czech: "1,5 kilometru" *}
```

### Direct Usage in PHP

[](#direct-usage-in-php)

```
use ElCheco\Translator\Translator;

$translator = new Translator($dictionaryFactory);
$translator->setLocale('cs_CZ');

// Simple translation
echo $translator->translate('Welcome'); // "Vítejte"

// Legacy plural format
echo $translator->translate('You have %s messages', 5); // "Máte 5 zpráv"

// CLDR format
echo $translator->translate('days_count', 1);    // "1 den"
echo $translator->translate('days_count', 2);    // "2 dny"
echo $translator->translate('days_count', 1.5);  // "1,5 dne" (decimal → many)
echo $translator->translate('days_count', 5);    // "5 dní"
```

NEON Translation Files
----------------------

[](#neon-translation-files)

Translation files support both legacy and CLDR formats:

### Simple Translations

[](#simple-translations)

```
# en_US.neon
Welcome: Welcome to our website
"Hello %s": Hello %s
```

### Legacy Plural Format

[](#legacy-plural-format)

```
# cs_CZ.neon
"You have %s messages":
    0: Nemáte žádné zprávy
    1: Máte %s zprávu
    "2-4": Máte %s zprávy
    5: Máte %s zpráv
```

### CLDR Format (Recommended)

[](#cldr-format-recommended-1)

```
# en_US.neon
items_count:
    zero: You have no items
    one: You have one item
    other: You have {count} items

# cs_CZ.neon
items_count:
    one: Máte {count} položku
    few: Máte {count} položky
    many: Máte {count} položky    # for decimals
    other: Máte {count} položek
```

Command Line Tools
------------------

[](#command-line-tools)

### Import Translations from NEON to Database

[](#import-translations-from-neon-to-database)

```
php bin/console translations:import-neon /path/to/neon/files ModuleName \
    --locale=en_US \
    --mark-as-approved \
    --overwrite
```

### Export Translations from Database to NEON

[](#export-translations-from-database-to-neon)

```
php bin/console translations:export-neon ModuleName en_US \
    --output-dir=./translations \
    --include-keys=key1,key2 \
    --include-untranslated
```

### Convert Legacy Translations to CLDR Format (NEW!)

[](#convert-legacy-translations-to-cldr-format-new)

```
# Convert NEON files
php bin/console translations:convert-to-cldr neon /path/to/translations \
    --locale=cs_CZ \
    --output-dir=./translations/cldr \
    --backup

# Convert database translations
php bin/console translations:convert-to-cldr database ModuleName \
    --locale=cs_CZ \
    --dry-run
```

Database Structure
------------------

[](#database-structure)

The database schema has been enhanced to support CLDR:

```
-- New column for format type
ALTER TABLE `translation_keys`
ADD COLUMN `format_type` ENUM('sprintf', 'icu') DEFAULT 'sprintf';

-- Stores ICU MessageFormat patterns
ALTER TABLE `translation_keys`
ADD COLUMN `cldr_message_pattern` TEXT NULL;
```

Number Formatting
-----------------

[](#number-formatting)

The translator automatically formats numbers according to locale:

```
$translator->setLocale('en_US');
echo $translator->translate('distance_km', 1234.5); // "1,234.5 kilometers"

$translator->setLocale('cs_CZ');
echo $translator->translate('distance_km', 1234.5); // "1 234,5 kilometru"

$translator->setLocale('de_DE');
echo $translator->translate('distance_km', 1234.5); // "1.234,5 Kilometer"
```

Migration Guide
---------------

[](#migration-guide)

### Migrating to CLDR Format

[](#migrating-to-cldr-format)

1. **Automatic Detection**: The translator automatically detects and handles both formats
2. **Gradual Migration**: You can migrate translations one by one
3. **Migration Tool**: Use the console command to convert existing translations

```
# Backup and convert
php bin/console translations:convert-to-cldr neon ./translations \
    --backup \
    --output-dir=./translations
```

### Example Migration

[](#example-migration)

Before (Legacy):

```
days:
    0: žádný den
    1: %s den
    "2-4": %s dny
    5: %s dní
```

After (CLDR):

```
days:
    zero: žádný den
    one: {count} den
    few: {count} dny
    many: {count} dne     # for decimals
    other: {count} dní
```

Advanced Features
-----------------

[](#advanced-features)

### Custom Plural Rules

[](#custom-plural-rules)

```
use ElCheco\Translator\Cldr\CldrPluralRules;

// Get plural category for a number
$category = CldrPluralRules::getPluralCategory('cs_CZ', 1.5); // 'many'

// Get available categories for a locale
$categories = CldrPluralRules::getAvailableCategories('cs_CZ');
// ['one', 'few', 'many', 'other']
```

### Usage Tracking (Database Only)

[](#usage-tracking-database-only)

```
// Enable usage tracking
$factory = new DbDictionaryFactory($connection, 'Module', true);

// Later, save statistics
$dictionary->saveUsageStats();

// Query usage data
SELECT key, usage_count FROM translation_keys ORDER BY usage_count DESC;
```

Testing
-------

[](#testing)

```
# Run all tests
composer test

# Run specific test suites
vendor/bin/phpunit --testsuite "CLDR Tests"
vendor/bin/phpunit --filter testCzechDecimalSupport
```

Language Support
----------------

[](#language-support)

The translator includes built-in CLDR plural rules for 100+ languages, including:

- **Simple plurals** (one/other): English, German, Dutch, Spanish, Italian
- **Slavic languages**: Czech, Slovak, Polish, Russian, Ukrainian, Croatian
- **Complex plurals**: Arabic (6 forms), Irish, Maltese, Lithuanian
- **No plurals**: Japanese, Chinese, Thai, Vietnamese
- **Special decimals**: Czech/Slovak (many), Lithuanian (many), Romanian (few)

Examples
--------

[](#examples)

### E-commerce Site

[](#e-commerce-site)

```
# products.cs_CZ.neon
product_count:
    zero: Žádné produkty
    one: "{count} produkt"
    few: "{count} produkty"
    many: "{count} produktu"    # 1,5 produktu
    other: "{count} produktů"

in_stock:
    zero: Vyprodáno
    one: "Poslední kus"
    few: "Posledních {count} kusy"
    other: "Skladem {count} kusů"
```

### Weather App

[](#weather-app)

```
# weather.cs_CZ.neon
temperature:
    one: "{count} stupeň"
    few: "{count} stupně"
    many: "{count} stupně"      # 20,5 stupně
    other: "{count} stupňů"

days_forecast:
    one: "Předpověď na {count} den"
    few: "Předpověď na {count} dny"
    many: "Předpověď na {count} dne"   # 1,5 dne
    other: "Předpověď na {count} dní"
```

Changelog
---------

[](#changelog)

### Version 2.0.0

[](#version-200)

- Added full Unicode CLDR plural rules support
- Added decimal number handling for all languages
- Added ICU MessageFormat support
- Added migration tools for legacy → CLDR conversion
- Enhanced database schema for CLDR storage
- Maintained 100% backward compatibility

### Version 1.x

[](#version-1x)

- Basic translation support
- Legacy plural forms
- Database and NEON storage
- Import/export commands

Contributing
------------

[](#contributing)

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

License
-------

[](#license)

MIT License

Credits
-------

[](#credits)

Inspired by [rostenkowski/translate](https://github.com/rostenkowski/translate), enhanced with:

- Full CLDR plural rules support
- Decimal number handling
- Modern PHP 8.3+ features
- Enhanced database functionality
- Comprehensive migration tools

Support
-------

[](#support)

For questions and support:

- Create an issue on GitHub
- Check the [documentation](https://github.com/elcheco/translator/wiki)
- See [examples](https://github.com/elcheco/translator/tree/master/examples)

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance59

Moderate activity, may be stable

Popularity22

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity85

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~157 days

Recently: every ~12 days

Total

17

Last Release

258d ago

Major Versions

v0.3.2 → v1.0.02025-04-08

v1.0.1 → v2.02025-07-13

PHP version history (4 changes)v0.1PHP &gt;=7.2

v0.2PHP &gt;=7.3

v0.3PHP &gt;=8.0

v1.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/a9887fa227e7985a2e5b6098c1a8305f7dab78b384dcdb094df4fe28cdede84a?d=identicon)[elcheco](/maintainers/elcheco)

---

Top Contributors

[![elcheco](https://avatars.githubusercontent.com/u/1447985?v=4)](https://github.com/elcheco "elcheco (11 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/elcheco-translator/health.svg)

```
[![Health](https://phpackages.com/badges/elcheco-translator/health.svg)](https://phpackages.com/packages/elcheco-translator)
```

###  Alternatives

[kdyby/translation

Integration of Symfony/Translation into Nette Framework

921.2M24](/packages/kdyby-translation)[contributte/translation

Symfony/Translation integration for Nette Framework.

771.8M37](/packages/contributte-translation)[brandembassy/slim-nette-extension

19190.2k](/packages/brandembassy-slim-nette-extension)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
