# Translation

# Content

# Setup

Require package

composer require contributte/translation
1

Register extension

extensions:
    translation: Contributte\Translation\DI\TranslationExtension
1
2

# Configuration

Basic configuration.

translation:
    locales:
        whitelist: [en, cs, sk]
        default: en
    dirs:
        - %appDir%/lang
1
2
3
4
5
6

# Presenter or model

Example in the presenter.

<?php declare(strict_types = 1);

namespace App;

use Nette;
use Contributte;

class BasePresenter extends Nette\Application\UI\Presenter
{
    
    /** @var Nette\Localization\ITranslator @inject */
    public $translator;

    /** @var Contributte\Translation\LocalesResolvers\Session @inject */
    public $translatorSessionResolver;

    public function handleChangeLocale(string $locale): void
    {
        $this->translatorSessionResolver->setLocale($locale);
        $this->redirect('this');
    }

    public function renderDefault(): void
    {
        $this->translator->translate('domain.message');

        $prefixedTranslator = $this->translator->createPrefixedTranslator('domain');

        $prefixedTranslator->translate('message');
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Example in the model.

<?php declare(strict_types = 1);

namespace App\Model;

use Nette;

class Model
{
    
    /** @var Nette\Localization\ITranslator */
    private $translator;

    public function __construct(Nette\Localization\ITranslator $translator)
    {
        $this->translator = $translator;
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Latte

How to use on frontend.

{_domain.message}

{_domain.message, $count}

{_domain.message, [name => "Ales"]}

{translator domain}
    {_message}

    {_message, $count}

    {_message, [name => "Ales"]}
{/translator}

{var $myMessage = 'domain.message'}
{$myMessage|translate}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Neon

File name format.

        locale
          |
         /--\
messages.en_US.neon
\______/       \__/
   |            |
 domain     extension
1
2
3
4
5
6
7

File content format.

prefix:
    for: "message" # messages.prefix.for
1
2

# Database loaders

Package included database loaders for Doctrine 2 and Nette Database 3.

# Alternative loaders

array: Symfony\Component\Translation\Loader\ArrayLoader
csv: Symfony\Component\Translation\Loader\CsvFileLoader
dat: Symfony\Component\Translation\Loader\IcuDatFileLoader
res: Symfony\Component\Translation\Loader\IcuResFileLoader
ini: Symfony\Component\Translation\Loader\IniFileLoader
json: Symfony\Component\Translation\Loader\JsonFileLoader
mo: Symfony\Component\Translation\Loader\MoFileLoader
php: Symfony\Component\Translation\Loader\PhpFileLoader
po: Symfony\Component\Translation\Loader\PoFileLoader
ts: Symfony\Component\Translation\Loader\QtFileLoader
xlf: Symfony\Component\Translation\Loader\XliffFileLoader
yml: Symfony\Component\Translation\Loader\YamlFileLoader
1
2
3
4
5
6
7
8
9
10
11
12

# Doctrine

You must create a file with specific format in scanned dirs like as messages.en_US.doctrine. All parameters are optional, but file must be created.

table: "My\Entity" # if you specify entity key, "messages" from file name will be ignored
id: "id" # id column name, default is "id"
locale: "locale" # locale column name, default is "locale"
message: "message" # message column name, default is "message"
1
2
3
4

Added loader to translation configuration.

translation:
    loaders:
        doctrine: Contributte\Translation\Loaders\Doctrine
1
2
3

Entity example.

<?php declare(strict_types = 1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="messages")
 */
class Messages
{
    
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", nullable=false)
     * @ORM\GeneratedValue
     */
    public $messageId;

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    public $id;

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    public $locale;

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    public $message;
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# Nette Database

You must create a file with specific format in scanned dirs like as messages.en_US.nettedatabase. All parameters are optional, but file must be created.

table: "my_table" # if you specify table key, "messages" from file name will be ignored
id: "id" # id column name, default is "id"
locale: "locale" # locale column name, default is "locale"
message: "message" # message column name, default is "message"
1
2
3
4

Added loader to translation configuration.

translation:
    loaders:
        nettedatabase: Contributte\Translation\Loaders\NetteDatabase
1
2
3

DB table example.

CREATE TABLE `messages` (
    `id` varchar(191) NOT NULL,
    `locale` char(5) NOT NULL,
    `message` varchar(191) NOT NULL,
    UNIQUE KEY `id` (`id`),
    KEY `locale` (`locale`),
    KEY `message` (`message`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1
2
3
4
5
6
7
8

# Features

# Wrappers

Possibility passing pluralization to components without pre-translation and avoiding double translation.

$form = new Nette\Application\UI\Form;

$form->addText('mail', 'form.mail.label')
    ->setOption('description', new Contributte\Translation\Wrappers\Message('form.mail.description', [...]);
1
2
3
4

Or pass the not translatable texts.

$form->addSelect('country', 'form.country.label')
    ->setItems([
        new Contributte\Translation\Wrappers\NotTranslate('Czech republic'),
        new Contributte\Translation\Wrappers\NotTranslate('Slovak republic'),
    ]);
1
2
3
4
5