PHPackages                             ipl/i18n - 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. ipl/i18n

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

ipl/i18n
========

Icinga PHP Library - Internationalization

v1.0.0(1mo ago)094.0k↓47.8%2MITPHPPHP &gt;=8.2CI passing

Since Jun 9Pushed 1mo ago8 watchersCompare

[ Source](https://github.com/Icinga/ipl-i18n)[ Packagist](https://packagist.org/packages/ipl/i18n)[ Docs](https://github.com/Icinga/ipl-i18n)[ RSS](/packages/ipl-i18n/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (4)Versions (11)Used By (2)

Icinga PHP Library - Internationalization (i18n)
================================================

[](#icinga-php-library---internationalization-i18n)

`ipl/i18n` provides a translation suite built on PHP's native [gettext](https://www.php.net/gettext) extension. It handles locale negotiation from HTTP `Accept-Language` headers, wires a static translator instance for use anywhere in an application, and exposes convenient global helper functions and a trait for use in classes.

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

[](#installation)

The recommended way to install this library is via [Composer](https://getcomposer.org):

```
composer require ipl/i18n
```

`ipl/i18n` requires PHP 7.2 or later with the `intl` and `gettext`extensions.

Translation catalogs are expected in gettext's standard directory layout:

```
/path/to/locales//LC_MESSAGES/.mo

```

`.mo` files are compiled binary catalogs produced from human-editable `.po`files via `msgfmt`. If you do not specify a domain, `ipl/i18n` uses the `default` domain.

Usage
-----

[](#usage)

### Setting Up the Translator

[](#setting-up-the-translator)

Bootstrap the translator once at application startup and assign it to `StaticTranslator` so that the global helper functions and the `Translation`trait resolve it automatically from anywhere in your application. `addTranslationDirectory()` accepts an optional second argument to register a named domain — see [Working With Multiple Domains](#working-with-multiple-domains-and-message-context)for details:

```
use ipl\I18n\GettextTranslator;
use ipl\I18n\StaticTranslator;

$translator = (new GettextTranslator())
    ->addTranslationDirectory('/path/to/locales')
    ->setLocale('de_DE');

StaticTranslator::$instance = $translator;
```

### Global Helper Functions

[](#global-helper-functions)

Once `StaticTranslator::$instance` is set, import `t()` and `tp()` via `use function` and call them anywhere in your application:

```
use function ipl\I18n\t;
use function ipl\I18n\tp;

echo t('Save changes');

// $count selects the plural form, printf substitutes %d.
printf(tp('%d item', '%d items', $count), $count);
```

Both functions forward to the static translator instance, so they always reflect the currently active locale.

### Translation Trait

[](#translation-trait)

Add the `Translation` trait to any class that needs to translate messages. Set `$translationDomain` to scope translations to a specific gettext domain, or leave it `null` (the default) to use the default domain:

```
use ipl\I18n\Translation;

class MyModule
{
    use Translation;

    protected ?string $translationDomain = 'mydomain';

    public function getLabel(): string
    {
        return $this->translate('Dashboard');
    }

    public function getItemLabel(int $count): string
    {
        // $count selects the plural form, sprintf substitutes %d.
        return sprintf(
            $this->translatePlural('%d item', '%d items', $count),
            $count
        );
    }
}
```

### Working With Multiple Domains and Message Context

[](#working-with-multiple-domains-and-message-context)

Register additional translation directories under named domains and use the domain- and context-aware methods to resolve messages precisely. Context disambiguates source strings that share the same English word but require different translations — for example, `"request"` as an HTTP request versus a change request:

```
use ipl\I18n\GettextTranslator;

$translator = (new GettextTranslator())
    ->addTranslationDirectory('/path/to/default/locales')
    ->addTranslationDirectory('/path/to/configuration/locales', 'configuration')
    ->setLocale('de_DE');

// Same source string, different translations depending on context:
// 'http'   → an HTTP request
// 'change' → a change request
echo $translator->translate('request', 'http');
echo $translator->translate('request', 'change');

// Resolve messages from the `configuration` domain.
echo $translator->translateInDomain('configuration', 'configuration item');
printf(
    $translator->translatePluralInDomain(
        'configuration', '%d job', '%d jobs', 2, 'deployment queue'
    ),
    2
);
```

### Detecting the User's Language

[](#detecting-the-users-language)

Browsers send an `Accept-Language` header with each request listing the user's preferred languages in priority order (e.g., `de-DE,de;q=0.9,en-US;q=0.8`). Use `Locale::getPreferred()` to match that list against the locales your application actually has available and activate the best fit:

```
use ipl\I18n\Locale;

$availableLocales = $translator->listLocales();
$preferredLocale = (new Locale())->getPreferred(
    $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
    $availableLocales
);

$translator->setLocale($preferredLocale);
```

If no exact or language-level match is available, locale selection falls back to `en_US` by default. Use `setDefaultLocale()` on the `Locale`instance to change the fallback.

### Testing With NoopTranslator

[](#testing-with-nooptranslator)

In tests you typically do not want to depend on compiled `.mo` catalog files being present on disk. `NoopTranslator` satisfies the translator interface by returning every message unchanged, so your test suite runs without any gettext setup while still exercising all code paths that call `t()`, `tp()`, or the `Translation` trait:

```
use ipl\I18n\NoopTranslator;
use ipl\I18n\StaticTranslator;

StaticTranslator::$instance = new NoopTranslator();
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for a list of notable changes.

License
-------

[](#license)

`ipl/i18n` is licensed under the terms of the [MIT License](LICENSE.md).

###  Health Score

56

—

FairBetter than 98% of packages

Maintenance89

Actively maintained with recent releases

Popularity30

Limited adoption so far

Community24

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 62.9% 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 ~291 days

Recently: every ~344 days

Total

7

Last Release

55d ago

Major Versions

v0.2.2 → v1.0.0.x-dev2026-03-24

PHP version history (3 changes)v0.1.0PHP &gt;=5.6.0

v0.2.0PHP &gt;=7.2

v1.0.0.x-devPHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/39625a91c802211110651e31881abdd47b715dad6a8879493d55933eb24a46c0?d=identicon)[ipl](/maintainers/ipl)

---

Top Contributors

[![lippserd](https://avatars.githubusercontent.com/u/1894563?v=4)](https://github.com/lippserd "lippserd (88 commits)")[![nilmerg](https://avatars.githubusercontent.com/u/16668527?v=4)](https://github.com/nilmerg "nilmerg (27 commits)")[![sukhwinder33445](https://avatars.githubusercontent.com/u/54990055?v=4)](https://github.com/sukhwinder33445 "sukhwinder33445 (6 commits)")[![Al2Klimov](https://avatars.githubusercontent.com/u/6053266?v=4)](https://github.com/Al2Klimov "Al2Klimov (5 commits)")[![Thomas-Gelf](https://avatars.githubusercontent.com/u/553008?v=4)](https://github.com/Thomas-Gelf "Thomas-Gelf (5 commits)")[![yhabteab](https://avatars.githubusercontent.com/u/57616252?v=4)](https://github.com/yhabteab "yhabteab (4 commits)")[![grangeway](https://avatars.githubusercontent.com/u/434241?v=4)](https://github.com/grangeway "grangeway (2 commits)")[![BastianLedererIcinga](https://avatars.githubusercontent.com/u/235492483?v=4)](https://github.com/BastianLedererIcinga "BastianLedererIcinga (2 commits)")[![jrauh01](https://avatars.githubusercontent.com/u/81301701?v=4)](https://github.com/jrauh01 "jrauh01 (1 commits)")

---

Tags

localizationinternationalizationi18ntranslationgettext

### Embed Badge

![Health badge](/badges/ipl-i18n/health.svg)

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

###  Alternatives

[tractorcow/silverstripe-fluent

Simple localisation for Silverstripe

92421.6k26](/packages/tractorcow-silverstripe-fluent)[delight-im/i18n

Internationalization and localization for PHP

625.2k3](/packages/delight-im-i18n)[inpsyde/multilingual-press

Simply THE multisite-based free open source plugin for your multilingual websites.

2414.0k1](/packages/inpsyde-multilingual-press)[skillshare/formatphp

Internationalize PHP apps. This library provides an API to format dates, numbers, and strings, including pluralization and handling translations.

8029.6k](/packages/skillshare-formatphp)[fisharebest/localization

A lightweight localization database and translation tools, with data from the CLDR, IANA, ISO, etc.

3191.1k2](/packages/fisharebest-localization)[smousss/laravel-globalize

Make Laravel projects translatable in a matter of seconds!

2266.3k](/packages/smousss-laravel-globalize)

PHPackages © 2026

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