PHPackages                             mindplay/lang - 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. mindplay/lang

ActiveLibrary

mindplay/lang
=============

ultra-simple, super-lightweight localization facility

1.1.2(7y ago)414.1k11LGPL-3.0+PHPPHP &gt;=5.4.0

Since Apr 16Pushed 7y ago1 watchersCompare

[ Source](https://github.com/mindplay-dk/lang)[ Packagist](https://packagist.org/packages/mindplay/lang)[ RSS](/packages/mindplay-lang/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (1)Dependencies (3)Versions (5)Used By (1)

mindplay/lang
=============

[](#mindplaylang)

This library implements an ultra-simple, super-lightweight localization facility. (~100 SLOC)

[![PHP Version](https://camo.githubusercontent.com/581d3b86ad2a67effa63792b85b18395acbbc26aae6ab4a453ed555677b8761c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d352e342532422d626c75652e737667)](https://packagist.org/packages/mindplay/lang)[![Build Status](https://camo.githubusercontent.com/b2fd8e8966e36ce963b763ba20337ec31bf207e447bf189043e4cae2d8dfcb44/68747470733a2f2f7472617669732d63692e6f72672f6d696e64706c61792d646b2f6c616e672e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/mindplay-dk/lang)[![Code Coverage](https://camo.githubusercontent.com/544fdb7acce7047477ecd38c73b797437d68bf806248a584cf5956d385a13c08/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696e64706c61792d646b2f6c616e672f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mindplay-dk/lang/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/866bca33837a052a2488e4f60789a273b6ca585221fc1cd1e41fcf36ac42c242/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696e64706c61792d646b2f6c616e672f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mindplay-dk/lang/?branch=master)

It consists of a single pseudo-namespace with just a few functions, but affords a surprising amount of flexibility, including the ability to handle plurality, such as "1 result" vs "5 results", without the (mental or computational) overhead of inventing any proprietary syntax.

##### Concept

[](#concept)

Strings are translated from english source text, optionally with name/value tokens being replaced.

Alternatively, you can use keys instead of english source text, e.g. `NUM_RESULTS` rather than `{num} results` - this is solely a matter of convention, and has no bearing on how the translation mechanism works, you just need to understand the pros and cons of each strategy:

- With english source text, you get more readable code, and you may not need any english language files at all - the downside is that even a small change (capitalization, punctuation) to the english source text will require the source text to be updated in all translation files. (on the other hand, you could view it as an advantage, that any change to the source text will require updates to the translations, forcing you to keep translations up to date.)
- With keys, your source code is arguably less readable, but more sturdy - minor changes to english source text doesn't affect anything. Using this approach however, you must ship a set of english language files with your project or package. (again, you could view it as an advantage, that the english source files provide a source of reference for translators.)

Translations are grouped into "translation domains", which map to subfolders and plain PHP files, e.g. one file per every domain/language pair.

By convention, your base translation domain should be your Composer package name, e.g. `{vendor}/{package}`, optionally with translation sub-domains nested below those - following this convention obviates the need to bootstrap with `lang::register()` at all, if you follow the convention of placing a folder named `lang`in the root of your Composer package.

The whole thing is `static`, and if that makes you quibble - relax. Translations *are* after all global, in the sense that there's only one translation of each string for any given language.

Usage
-----

[](#usage)

To translate a string, simpy do this:

```
use mindplay\lang;

echo lang::text("foo/bar", "Hello {who}", ["who" => "World"]); // => "Hello World"
```

By default (without any configuration; see below) this library will load the file `vendor/foo/bar/en.php` - the language file format will be discussed below.

To change the active language, do this:

```
lang::set("en");
```

To obtain a string in a specific language (ignoring the active language) use the `translate()` function:

```
$text = lang::translate("en", "foo/bar", "...");
```

Alternatively, you can obtain a translation function for a specific language domain, and reuse it:

```
$t = lang::domain("foo/bar");

echo $t("Hello {who}", ["who" => "World"]); // => "Hello World"
echo $t("Hi {who}", ["who" => "World"]); // => "Hi World"
```

This can be useful for dependency injection, or just to avoid repeating the language domain name for every call. Note that an optional second argument for the language code will give you a translation function for a specific language. Also note that language files will not actually load until the translation function is used - so there are no unpredictable performance implications.

Assuming you follow the convention of using your Composer package name as your root language domain, and placing your language files in a folder named `lang` in the root of your package, you do not need to call `lang::register()` to configure the root path - the package will use [composer-locator](https://github.com/mindplay-dk/composer-locator)to automatically find the root path.

In other cases - or in cases where you wish to override the translation files of an external package in your project - you need to register the base path of the translation files for the language domain - for example:

```
lang::register("foo/bar", __DIR__ . "/lang");
```

Now, if you call `lang::text("foo/bar", "...")`, the translation file `{__DIR__}/lang/en.php` will be loaded - the file name is the two-letter language code. If you call `lang::text("foo/bar/baz", "...")`, the translation file `{__DIR__}/lang/baz/en.php` will load, and so on.

A language file such as `lang/baz/en.php` might look like this:

```
