Localizing PHP application with FBT instead of standard i18n
Tags: php, i18n, tutorial, opensource
Published: 2022-07-15 18:03:14

Since about 2010, I have been looking for a translation framework for PHP that can generate very complex phrases and at the same time combine options such as singular/plural and work with genders (male, female, unknown) and ideally also format numbers according to the standards of the given country or region — unsuccessfully. In 2018, Facebook released FBT — an open source localization framework that provides a more efficient way of defining content for flexible and high-quality localization. I didn’t hesitate at all. I gradually started to rewrite this JavaScript version into PHP, and even if a few small things were not entirely according to the original code, I succeeded. It was my challenge that I finished in about 40 days (better said, evenings 😊).

- [FBT Preview at F8](https://www.facebook.com/watch/?ref=external&v=2270332766518020)
- [FBT repository for PHP 7.0+](https://www.facebook.com/watch/?ref=external&v=2270332766518020)
- [FBT repository for Laravel 5.5+](https://github.com/richardDobron/laravel-fbt)

There are many reasons why the common i18n libraries are very inadequate. The main ones are:

- misunderstanding of the native text by the translator (does not know the context),
- insufficient/nonsensical code combinations for translation,
- do not support features like enums or pronouns,
- and many more…

Fortunately, FBT can solve all of this. However, it is not easy to use it for the first time when you are not familiar with it. But I will be happy to advise you on how to use it.

### 1. Install the FBT package
```
composer require richarddobron/fbt
```

### 2. Set your FBT configuration

```
<?php
require ("vendor/autoload.php");

\fbt\FbtConfig::set('author', 'your name/team');
\fbt\FbtConfig::set('project', 'project name');
\fbt\FbtConfig::set('path', '/path/to/storage/fbt');
```

### 3. Language and gender settings
If you just want to change the interface language, just use:
```
\fbt\FbtHooks::locale('sk_SK'); // app locale
```

If you have an application in which users log in, you can use the interface **IntlViewerContextInterface**:

{% embed https://gist.github.com/richardDobron/6402efaed0c5aa5feb14307fd22427ed %}

After implementation, set **viewerContext**:
```
$loggedUserDto = ...;
\fbt\FbtConfig::set('viewerContext', $loggedUserDto);
```

### 4. Prepare translations files
Facebook has devised their own system of labeling languages, you can find a list of them at this [link](https://github.com/richardDobron/fbt/blob/main/docs/locales.md).
From this list, choose the languages into which you want to translate your website or application.
I usually add them to the directory **/storage/fbt/**
File name will look like this: **sk_SK.json**

### 5. Add FBT scripts to _composer.json_
{% embed https://gist.github.com/richardDobron/f4a9213609de5c059ee38567c51cd5e1 %}
- Native phrases can also be easily translated via the app editor **[Swiftyper Translations](https://translations.swiftyper.sk)**.

### 6. Add your texts
Native phrases are always expected in **English**, it might look something like this:
{% embed https://gist.github.com/richardDobron/faa29c058615a1a8f50a8acbe7e3ecf3 %}

### 7. Translate collected texts
This is what the collected source strings look like in the _.source_strings.json_ file after script execution:
{% embed https://gist.github.com/richardDobron/1f28a99ea188e915954b3b4acb6657f6 %}

Now we are ready to generate a file in which we will write the translations for the collected source strings:
```
composer run generate-translations
```
The _/storage/fbt/sk_SK.json_ file now contains the hash keys of the source phrases that we can now translate. I make translations into Slovak, so I can use the gender of the **{name}** token and adapt the variations of the given text precisely. This step is a bit difficult for some translations with variants, as you have to work with the variations key.
You can also find several types of translations at this [link](https://github.com/richardDobron/fbt/blob/main/tests/translations/data/sk_SK.json).

{% embed https://gist.github.com/richardDobron/b115199cfc30e77dc5153eee5c6535c7 %}

After completing the translations, we run the command that creates the translations for the application:
```
composer run translate-fbts
```
Finally, this command will generate a production file with translations using Jenkins hash.

{% embed https://gist.github.com/richardDobron/7755dcaecc34a3522af5f04178cf78d4 %}

Your app is now translated! Hurray!


{% embed https://giphy.com/embed/EXFAJtutz5Ig8 %}

Thanks for reading 🙏.