Skip to content

Language manager for internationalization of websites

Notifications You must be signed in to change notification settings

bnjmnhssnn/Babelfisch

Repository files navigation

Babelfisch

Language manager for internationalization of websites

  • Organize your language files in a tree structure, e.g. folders on a filesystem or parent-child hierarchy in a database
  • Supports nested language files with mustache-like syntax
  • Dynamic injection of additional data

PHP Composer

Example structure of your languages folder

Language files must be suffixed with the language identifiers used in the next step

languages/
├── button/
│   ├── buy_EN.txt
│   ├── buy_DE.txt
│   └── buy_NL.txt
├── greeting/
│    ├── welcome_EN.txt
│    ├── welcome_DE.txt
│    └── welcome_NL.txt
└── home/
     ├── main_paragraph_EN.txt
     ├── main_paragraph_DE.txt
     └── main_paragraph_NL.txt

No matter if you use filesystem storage or a database, you are free to organize your language files however you like. If you choose a hierarchical, tree-like structure, you can access each entry by a colon-separated identifier (See Basic Usage)

Get a Babelfisch instance

use \bnjmnhssnn\Babelfisch;
use \bnjmnhssnn\Babelfisch\StorageAdapter\FilesystemAdapter;

$bf = new Babelfisch(
    new FilesystemAdapter(__DIR__ . '/languages'),
    'EN', 'DE', 'NL' // Pass the active language first, then optional fallback languages
);

When no language file for the active language can be found, Babelfisch will try to load the fallback languages in the specified order.

Basic Usage

$buy_button = '<button>' . $bf->output('button:buy') . '</button>';

Inject dynamic data

Content of languages/greetings/welcome_EN

Hello {{name}}, welcome to my awesome website!
echo $bf->output('greeting:welcome', ['name' => 'Ted']); // Hello Ted, welcome to my awesome website!

Nested language files & dynamic data

Content of languages/home/main_paragraph_EN

{{greeting:welcome}}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.

First, Babelfisch will resolve {{greeting:welcome}} with the content of the language file languages/greeting/welcome_EN.txt, and then resolve {{name}} in languages/greeting/welcome_EN.txt with the dynamic data in the second argument.

echo $bf->output('home:main_paragraph', ['name' => 'Ted']);

When a dynamic data entry has the same identifier like a language file, the dynamic data will take precedence:

echo $bf->output(
    'home:main_paragraph', 
    [
        'name' => 'Ted',
        'greeting:welcome' => 'Hi {{name}},' // Will overwrite the content of languages/greeting/welcome
    ]
);

Use cacheing

In the case of large and deeply nested language files, it could be more performant to use a cache module.

use \bnjmnhssnn\Babelfisch;
use \bnjmnhssnn\Babelfisch\StorageAdapter\FilesystemAdapter;
use \bnjmnhssnn\Babelfisch\Cache\FilesystemCache;

$bf = new Babelfisch(new FilesystemAdapter(__DIR__ . '/languages'), 'EN', 'DE', 'NL');
$bf->setCache(new FilesystemCache(__DIR__ . '/cache'));

When you pass dynamic data to the output method, the cache module will generate one cache file for each dynamic data set, which is not desired in many cases. Though, you have to activate the cache explicitely with a third boolean argument, or use the convenience method outputWithCache instead.

echo $bf->output('very_large_paragraph', [], true);
// ... or with the convenient method "outputWithCache"
echo $bf->outputWithCache('very_large_paragraph');

Strategies for missing language files

When a language file and all of it's fallback files are missing, Babelfisch will throw an exception, by default. You can set 4 different strategies to customize this behaviour.

// Throw an exception (default)
$bf->setNotFoundAction(Babelfisch::NOT_FOUND_ACTION_EXCEPTION);

// Output the requested ID for the missing content
$bf->setNotFoundAction(Babelfisch::NOT_FOUND_ACTION_SHOW_ID);

// Output an empty string for the missing content
$bf->setNotFoundAction(Babelfisch::NOT_FOUND_ACTION_EMPTY_STRING);

// Provide any callable that takes the ID as input (must return a string)
$bf->setNotFoundAction(
     function($id) {
          return "<strong style="background-color: red">{$id}</strong>";
     }
);

About

Language manager for internationalization of websites

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published