Multilenguaje

El soporte multilenguaje utiliza el componente symfony/translation.

Instalación

composer require symfony/translation

Crear paquetes de idioma

Por defecto, webman coloca los paquetes de idioma en el directorio resource/translations (si no existe, créalo tú mismo). Si deseas cambiar el directorio, configúralo en config/translation.php.
Cada idioma corresponde a una de las subcarpetas, y la definición del lenguaje se coloca por defecto en messages.php. Un ejemplo es el siguiente:

resource/
└── translations
    ├── en
    │   └── messages.php
    └── zh_CN
        └── messages.php

Todos los archivos de idioma devuelven un arreglo como por ejemplo:

// resource/translations/en/messages.php

return [
    'hello' => 'Hello webman',
];

Configuración

config/translation.php

return [
    // Idioma por defecto
    'locale' => 'zh_CN',
    // Idioma de respaldo, cuando no se encuentra la traducción en el idioma actual, se intenta usar la traducción del idioma de respaldo
    'fallback_locale' => ['zh_CN', 'en'],
    // Carpeta donde se almacenan los archivos de idioma
    'path' => base_path() . '/resource/translations',
];

Traducción

La traducción se realiza utilizando el método trans().

Crea el archivo de idioma resource/translations/zh_CN/messages.php como sigue:

return [
    'hello' => '你好 世界!',
];

Crea el archivo app/controller/UserController.php

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        $hello = trans('hello'); // 你好 世界!
        return response($hello);
    }
}

Acceder a http://127.0.0.1:8787/user/get devolverá "你好 世界!"

Cambiar el idioma por defecto

Para cambiar el idioma, utiliza el método locale().

Añade el archivo de idioma resource/translations/en/messages.php como sigue:

return [
    'hello' => 'hello world!',
];
<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // Cambiar idioma
        locale('en');
        $hello = trans('hello'); // hello world!
        return response($hello);
    }
}

Acceder a http://127.0.0.1:8787/user/get devolverá "hello world!"

También puedes usar el cuarto parámetro de la función trans() para cambiar temporalmente el idioma, por ejemplo, el ejemplo anterior y este son equivalentes:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function get(Request $request)
    {
        // Cambiar idioma con el cuarto parámetro
        $hello = trans('hello', [], null, 'en'); // hello world!
        return response($hello);
    }
}

Establecer el idioma claramente para cada solicitud

La traducción es un singleton, lo que significa que todas las solicitudes comparten esta instancia. Si alguna solicitud usa locale() para establecer el idioma por defecto, afectará a todas las solicitudes posteriores en este proceso. Por lo tanto, debemos establecer claramente el idioma para cada solicitud. Por ejemplo, utilizando el siguiente middleware.

Crea el archivo app/middleware/Lang.php (si el directorio no existe, créalo tú mismo) como sigue:

<?php
namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;

class Lang implements MiddlewareInterface
{
    public function process(Request $request, callable $handler) : Response
    {
        locale(session('lang', 'zh_CN'));
        return $handler($request);
    }
}

Agrega el middleware global en config/middleware.php como sigue:

return [
    // Middleware global
    '' => [
        // ... Otros middlewares omitidos aquí
        app\middleware\Lang::class,
    ]
];

Uso de marcadores de posición

A veces, un mensaje contiene variables que necesitan ser traducidas, por ejemplo:

trans('hello ' . $name);

En tales casos, utilizamos marcadores de posición para manejarlos.

Cambia resource/translations/zh_CN/messages.php a lo siguiente:

return [
    'hello' => '你好 %name%!',
];

Al traducir, pasa los valores correspondientes a los marcadores de posición como segundo parámetro:

trans('hello', ['%name%' => 'webman']); // 你好 webman!

Manejo de plurales

Algunos idiomas presentan diferentes formas dependiendo de la cantidad de cosas, por ejemplo, There is %count% apple. Cuando %count% es 1, la oración es correcta; cuando es mayor que 1, es incorrecta.

En tales casos, utilizamos el pipe (|) para listar las formas plurales.

En el archivo de idioma resource/translations/en/messages.php, añade apple_count así:

return [
    // ...
    'apple_count' => 'There is one apple|There are %count% apples',
];
trans('apple_count', ['%count%' => 10]); // There are 10 apples

Incluso podemos especificar rangos numéricos, creando reglas plurales más complejas:

return [
    // ...
    'apple_count' => '{0} There are no apples|{1} There is one apple|]1,19] There are %count% apples|[20,Inf[ There are many apples'
];
trans('apple_count', ['%count%' => 20]); // There are many apples

Especificar archivos de idioma

El nombre del archivo de idioma por defecto es messages.php, sin embargo, realmente puedes crear archivos de idioma con otros nombres.

Crea el archivo de idioma resource/translations/zh_CN/admin.php como sigue:

return [
    'hello_admin' => '你好 管理员!',
];

Puedes especificar el archivo de idioma usando el tercer parámetro de trans() (omitiendo la extensión .php).

trans('hello', [], 'admin', 'zh_CN'); // 你好 管理员!

Más información

Consulta el manual de symfony/translation