Symfony2 мультиязычность

Автор: Aport Пятница, Январь 30th, 2015 Нет комментариев

Рубрика: Разное

Symfony2 предлагает нам несколько вариантов работы с переводами, но самый простой на мой взгляд, это перевод на основе доменых сообщений — это такие файлы, в которых хранится перевод.

Соглашения

Существуют соглашения именования файлов переводов:

  • messages - переводы по умолчанию, все что Вы используете в twig-шаблоне
  • validators - переводы сообщений об ошибках, которые возникают в результате валидации данных, ключи эти сообщений указаны в сущности, данные которой подвергаются проверки

Пример переводов на основе messages

Например в папке src/Acme/DemoBundle/Resources/translations/ создаем файлы messages.en.yml и messages.ru.yml

В свою очередь переводы в этих файлах записываются так:

ключ: значение
ключ2: значение2
и т.д.

Приведу пример файла на английском:

hi: Hello World
symfony2.is.great: Symfony is great

А теперь пример файла русского перевода:

hi: Привет Мир
symfony2.is.great: Симфони велик
Symfony2 the best: Симфони лучший

Заметили, ключи одинаковые, а значения разные, вот таким обрзом и организуется перевод.

А еще, в русском переводе я добавил третий ключ, которого нет в первом, это не ошибка, просто Симфони выводит ключи у которых нет перевода. Т.е. если мы напишем:

{{ ‘Symfony2 the best’|trans }}

то в английской версии интерфейса пользователя будет выведен ключ

Symfony2 the best

а в русской

Симфони лучший

благодаря такой возможности, для основного языка можно вообще не создавать файл перевода.

Пример переводов на основе validators

Создаем файл сущности src/Acme/DemoBundle/Entity/Orgunit.php

<?php
/**
 * Справочник единиц орг. структуры
 */
namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\OrgunitRepository")
 */
class Orgunit
{
    ...

    /**
     * @ORM\Column(type="integer", options={"default":0, "unsigned": true, "comment" : "ID объекта орг. единицы"})
     * @Assert\NotBlank(message = "objectId.NotBlank")
     * @Assert\Type(type="integer", message="objectId.integer")
     * @Assert\Range(
     *      min = 1,
     *      max = 4294967295,
     *      minMessage = "objectId.minMessage",
     *      maxMessage = "objectId.maxMessage"
     * )
     */
    private $objectId = 0;

    ...

Создаем файл перевода src/Acme/DemoBundle/Resources/translations/validators.en.yml

objectId.NotBlank : Укажите значение
objectId.integer : Неправильный тип данных, должен быть {{ type }}
objectId.minMessage : Минимальное значение 1
objectId.maxMessage : Максимальное значение 4294967295

Обратите внимание на вторую строчку, а именно на {{ type }}, таким образом мы можем использовать значения переменных, указанные в классе сущности.

и пример кода, в результате которого присходит проверка валидации:

    public function formAction()
    {
        $entity = new Orgunit();

        $form = $this->createFormBuilder($entity);

        $request = $this->get('request');

        if ( $request->getMethod() === 'POST' ) {// Обрабатываем форму

            $form->handleRequest($request);// обновляем сущность и данные в форме

            if ($form->isValid()) {// Валидируем (правила валидации в нотации к классу )

                // валидация прошла успешно

            }else{

                // получаем ошибки валидации, согласно файла перевода
                $form_errors = $this->get('helper_form_errors')->getArray($form);

            }
        }

        return array( 'form' => $form->createView() );
    }

Вот так просто, Symfony2 позволяет нам создавать мультиязычные интерфейсы.

Теперь о плохом

Самое ужасное, это то, что Symfony2 ищет все эти файлы во всех бандлах (даже вендорных) в папка вида Resources/translations/ И все бы ничего, и с этим можно смириться, но все найденные файлы подгружаются в память, и даже с учетом кэша — память меньше не становится. К примеру, если у Вас 123 файла переводов, и в сумме это 25 мб, то независимо от того, используете на текущей странице перевод для французского языка или нет - Symfony2 все равно подгрузит его в память. В общем на скорость форматирования страницы это может повлиять только при нехватке памяти.

Вывод

Используйте Symfony2 доменные файлы только для маленьких сайтов и только для интерфейсов, которые доступны везьде, например шапка или подвал сайта, небольшое глобальное меню и т.п. В противном случае перевод лучше реализовывать самостоятельно, я это сделал создав отдельный бандл с методом, который вызываю в нужных местах шаблонов.

Источники: 1 - 2 - 3 - 4

 

Источник: yapro.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты