Silex, el manual oficial

A.12. TranslationServiceProvider

El proveedor TranslationServiceProvider proporciona un servicio que facilita la traducción de tu aplicación a diferentes idiomas.

A.12.1. Parámetros de configuración

El proveedor define los siguientes parámetros configurables:

  • translator.domains (opcional): este parámetro contiene los datos de traducción de todos los idiomas y de todos los dominios (que son los diferentes archivos en los que puedes dividir una traducción).
  • locale (opcional): el idioma al que se deben traducir los contenidos. Su valor por defecto es en (es decir, inglés) pero normalmente se modifica durante el procesamiento de la petición para utilizar el idioma preferido del usuario.
  • locale_fallback (opcional): el idioma al que se traducirán los contenidos no disponibles en el idioma del usuario. Su valor por defecto también es en.

A.12.2. Servicios proporcionados

El proveedor proporciona los siguientes servicios:

  • translator: es una instancia de la clase Translator utilizada para la traducción de los contenidos.
  • translator.loader: es una instancia de alguna clase que implemente la interfaz LoaderInterface. Por defecto se utiliza la clase ArrayLoader.
  • translator.message_selector: es una instancia de la clase MessageSelector.

A.12.3. Cómo se registra el proveedor

El siguiente código muestra un ejemplo de cómo registrar este proveedor:

$app->register(new Silex\Provider\TranslationServiceProvider(), array(
    'locale_fallback' => 'en',
));

Nota El componente Translation de Symfony que utiliza este proveedor se incluye cuando descargas Silex en forma de archivo comprimido. Si instalas Silex mediante Composer, debes añadir esta dependencia ejecutando el siguiente comando:

$ composer require symfony/translation

A.12.4. Ejemplos de uso

La traducción de los contenidos normalmente se realiza a través del servicio translator y utiliza el parámetro translator.domains:

$app['translator.domains'] = array(
    'messages' => array(
        'en' => array(
            'hello'     => 'Hello %name%',
            'goodbye'   => 'Goodbye %name%',
        ),
        'de' => array(
            'hello'     => 'Hallo %name%',
            'goodbye'   => 'Tschüss %name%',
        ),
        'fr' => array(
            'hello'     => 'Bonjour %name%',
            'goodbye'   => 'Au revoir %name%',
        ),
    ),
    'validators' => array(
        'fr' => array(
            'This value should be a valid number.' => 'Cette valeur doit être un nombre.',
        ),
    ),
);

$app->get('/{_locale}/{message}/{name}', function ($message, $name) use ($app) {
    return $app['translator']->trans($message, array('%name%' => $name));
});

Si utilizas el código anterior, las siguientes rutas mostrarán los siguientes mensajes:

  • /en/hello/igor devolverá el texto Hello igor.
  • /de/hello/igor devolverá el texto Hallo igor.
  • /fr/hello/igor devolverá el texto Bonjour igor.
  • /it/hello/igor devolverá el texto Hello igor (en este caso se utiliza el idioma por defecto definido como fallback).

A.12.5. Utilizando recursos

Cuando las traducciones están guardadas en archivos, puedes cargarlas de la siguiente manera:

$app = new Application();

$app->register(new TranslationServiceProvider());
$app->extend('translator.resources', function ($resources, $app) {
    $resources = array_merge($resources, array(
        array('array', array('This value should be a valid number.' => 'Cette valeur doit être un nombre.'), 'fr', 'validators'),
    ));

    return $resources;
});

A.12.6. Traits

El trait Silex\Application\TranslationTrait definido por este proveedor añade los siguientes atajos:

  • trans: traduce el mensaje indicado.
  • transChoice: traduce un mensaje que varía en función de algún valor numérico.
$app->trans('Hello World');

$app->transChoice('Hello World');

A.12.7. Archivos de traducción en formato YAML

Si no quieres definir las traducciones en archivos PHP, esta sección explica cómo utilizar archivos YAML, mucho más fáciles de leer y de escribir.

Antes de nada, añade los componentes Config y Yaml de Symfony como dependencias de tu aplicación:

$ composer require symfony/config symfony/yaml

Después, crea los archivos YAML que contendrán la traducción de los contenidos. Una buena recomendación consiste en guardar estos archivos en un directorio llamado locales/ y utilizar como nombre el archivo el propio nombre del idioma (ejemplo: /locale/en.yml, /lovales/es.yml, etc.) El contenido de estos archivos está formado por la asociación entre el texto original y su traducción:

hello: Hello %name%
goodbye: Goodbye %name%

Por último, registra la clase YamlFileLoader en el servicio translator y agrega todos tus archivos de traducción:

use Symfony\Component\Translation\Loader\YamlFileLoader;

$app['translator'] = $app->share($app->extend('translator', function($translator, $app) {
    $translator->addLoader('yaml', new YamlFileLoader());

    $translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en');
    $translator->addResource('yaml', __DIR__.'/locales/de.yml', 'de');
    $translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr');

    return $translator;
}));

A.12.8. Archivos de traducción en formato XLIFF

Al igual que para los archivos YAML, el primer paso consiste en añadir el componente Config de Symfony como dependencia de tu aplicación (mirar explicación en la sección anterior).

Después, crea los archivos XLIFF en el directorio /locales y añádelos al servicio de traducción:

$translator->addResource('xliff', __DIR__.'/locales/en.xlf', 'en');
$translator->addResource('xliff', __DIR__.'/locales/de.xlf', 'de');
$translator->addResource('xliff', __DIR__.'/locales/fr.xlf', 'fr');

Nota El cargador de archivos XLIFF ya está preconfigurado por la extensión.

A.12.9. Traduciendo contenidos en las plantillas Twig

Una vez cargado, el servicio de traducción se puede utilizar directamente desde las plantillas Twig:

{{ app.translator.trans('translation_key') }}

Y si utilizas el bridge de Twig incluído en Symfony, puedes traducir los contenidos todavía más fácilmente:

{{ 'translation_key'|trans }}
{{ 'translation_key'|transchoice }}
{% trans %}translation_key{% endtrans %}