1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Symfony ComponentAdvent Calendar 2023

Day 2

いろいろ翻訳、"Translation"

Last updated at Posted at 2023-12-01

Symfony Component Advent Calendar 2023の2日目の記事です。

いろいろ翻訳、"Translation"

Translationは、翻訳を司るコンポーネントです。

インストール

composer require symfony/translation

翻訳

翻訳を行うには、元の文と翻訳文をセットにした翻訳用のリソースを読み込ませます。

use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\ArrayLoader;

$translator = new Translator('ja');
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', [
    'Hello World!' => 'こんにちは、世界!',
    "This is an apple." => 'これはりんごです。',
], 'ja');

echo $translator->trans('Hello World!'); // こんにちは、世界!

Symfonyの場合

Symfonyの場合は、翻訳用のリソースをtranslationsディレクトリに用意し設定を行うことで、自動的にリソースを読み込めます。
また、TranslatorInterfaceをDIすることで、Translatorオブジェクトを自動注入できます。

config/packages/translation.yaml
framework:
    default_locale: ja # デフォルトで翻訳する言語
    translator:
        default_path: '%kernel.project_dir%/translations' # 翻訳ファイルの置き場所
translations/messages.ja.yaml
"Hello world!": "こんにちは、世界"
"This is an apple.": "これはりんごです。"
src/Command/SomeCommand.php
namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Contracts\Translation\TranslatorInterface;

class TranslateCommand extends Command
{
    public function __construct(private readonly TranslatorInterface $translator)
    {
        parent::__construct();
    }


    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $message = 'Hello world!';
        
        $translated = $this->translator->trans($message);
        $io->info($translated); // こんにちは、世界!

        return Command::SUCCESS;
    }
}

メッセージIDの指定

元の文章ではなく、メッセージIDを指定することで翻訳文を入手することも可能です。

translations/messages.ja.yaml
"Hello world!": "こんにちは、世界"
apple: "これはりんごです。" # ID指定
$translator->trans('apple'); // これはりんごです。

Twig上での利用

Twigではフィルター機能とタグで翻訳することが可能です。

index.html.twig
{% set message = 'Helllo world!' %}
{{ message|trans }}

{% trans %}Hello world!{% endtrans %}
{* どちらも、「こんにちは、世界!」 *}

ICUメッセージフォーマット

たとえば英語だと、りんごは単数形だとapple、複数形だとapplesです。また、男性に対してはhe、女性に対してはsheといったように、翻訳したい箇所で、別の単語に切り替えたい時があります。そのような場合、 ICU MessageFormatというものを利用して翻訳することができます。

translations:messages+intl-icu.ja.yaml
num_of_apples: >-
    {apples, plural,
        =0  {りんごはないです。}
        =1 {りんごはひとつです。}
        =2 {りんごはふたつです。}
        =3 {りんごはみっつです。}
        =4 {りんごはよっつです。}
        =5 {りんごはいつつです。}
        =6 {りんごはむっつです。}
        =7 {りんごはななつです。}
        =8 {りんごはやっつです。}
        =9 {りんごはここのつです。}
        other   {りんごは#個です。}   
    }
intivation: >-
        {gender, select,
        female  {{name}さんに招待状をお送りしました。彼女の招待コードは{code}です}
        male    {{name}さんに招待状をお送りしました。彼の招待コードは{code}です}
        other   {{name}さんに招待状をお送りしました。{name}さんの招待コードは{code}です}
    }
for ($i = 0; $i <= 10; $i ++) {
    echo $translator->trans('num_of_apples', ['apples' => $i]);
}

/*
りんごはないです。
りんごはひとつです。
りんごはふたつです。
りんごはみっつです。
りんごはよっつです。
りんごはいつつです。
りんごはむっつです。
りんごはななつです。
りんごはやっつです。
りんごはここのつです。
りんごは10個です。
*/

echo $translator->trans(
    'invitation',
    ['gender' => 'male', 'name' => 'すみだ', 'code' => '12345']
);

// すみださんに招待状をお送りしました。彼の招待コードは12345です。

外部プロバイダーの利用

現在はCrowdinなど、外部の翻訳サービスも充実しています。そんな外部サービスを利用して翻訳ファイルを生成することも可能です。現在利用できるのは、Crowdin Loco Lokaliseで、それぞれのプロバイダーを追加インストールします。

インストール&設定

composer require symfony/crowdin-translation-provider
config/packages/translation.yaml
framework:
    translator:
        providers:
            crowdin:
                dsn: '%env(CROWDIN_DSN)%'
                locales: ['en', 'ja']

外部サービスから翻訳ファイル生成

bin/console translation:pull

外部サービスに翻訳ファイルをアップロード

bin/console translation:push

Crowdinにアップロードした結果

スクリーンショット 2023-11-26 17.36.04.png

たとえば本番デプロイ後に外部サービスから翻訳ファイルを生成するようにしておけば、コードと翻訳ファイルを分けて扱うことが可能になります。

まとめ

今回はTranslationを紹介しました。日本向けのサービスであればあまり活躍の機会はありませんが、グローバルなサイトを作る時には必須な機能になると思うので、要チェックなコンポーネントになります。使い方も楽ちんです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?