PythonのFlaskでテンプレートを多言語化!翻訳の基本構文を完全ガイド
生徒
「Flaskで作ったWebサイトの画面に表示される『こんにちは』などの文字を、英語の時は『Hello』に自動で変えたいです。HTMLファイルにはどう書けばいいですか?」
先生
「Flaskでは、テンプレートエンジンと呼ばれるJinja2の中で、特定の記号を使って文字を囲むことで翻訳を実現できますよ。」
生徒
「特定の記号……難しそうですね。プログラミングが初めての私でも覚えられますか?」
先生
「大丈夫です。基本的には、アンダーバーと括弧を使うだけです!まずは一番簡単な書き方からマスターしていきましょう。」
1. テンプレート翻訳の基本!アンダーバー関数の使い方
FlaskでWebサイトの画面(テンプレート)を作るとき、通常はHTMLというファイルに文字を書いていきます。しかし、そのまま日本語を書いてしまうと、世界中の誰が見ても日本語しか表示されません。
そこで、翻訳したい文字を「{{ _('文字') }}」という特殊な書き方で囲みます。このアンダーバー「_」は、プログラムの世界では「これから翻訳する言葉ですよ」という目印になります。
例えば、サイトの見出しを翻訳したい場合は、HTMLファイルの中に以下のように記述します。
<h1>こんにちは</h1>
<h1>{{ _('Hello') }}</h1>
このように「{{ }}」という二重の波括弧で囲むことで、Flaskのシステムが中身を読み取り、設定された言語に合わせて適切な訳語を表示してくれます。
2. 翻訳テキストの中に変数を組み込む方法
「ようこそ、〇〇さん!」のように、名前などの一部だけが状況によって変わる文章を翻訳したいこともありますよね。この「〇〇」の部分をプログラミングでは「変数(へんすう)」と呼びます。
文章全体をバラバラに翻訳してしまうと、言語によって語順が違うときに不自然になってしまいます。そのため、文章の枠組みはそのままで、変数を差し込む方法を使います。
<p>{{ _('Welcome, %(name)s!', name=user.username) }}</p>
「%(name)s」という部分が、後から名前が入るための「予約席」になります。この書き方をすることで、日本語なら「ようこそ、田中さん!」、英語なら「Welcome, Tanaka!」と、正しい位置に名前が入った状態で翻訳されます。
3. 複数形に対応する翻訳の書き方
英語などの言語には、単数形(1つのとき)と複数形(2つ以上のとき)で言葉が変わるというルールがあります。例えば、リンゴが1個なら「1 apple」ですが、2個なら「2 apples」になります。
これを自動で判別してくれるのが「ngettext」という機能です。少し複雑に見えますが、初心者のうちから知っておくと非常に役立ちます。
<p>
{{ ngettext('%(num)d apple', '%(num)d apples', count, num=count) }}
</p>
この一行で、「count」という数字が1なら1番目の文章を、それ以外なら2番目の文章を自動的に選んで表示してくれます。自分で「もし1だったら……」という命令を書かなくて済むので、とてもスマートです。
4. HTMLタグを含む文章を翻訳する時の注意点
翻訳したい文章の中に、文字を太くする「<b>」タグや、リンクを作る「<a>」タグを含めたい場合があります。しかし、普通に囲むとセキュリティ上の理由でタグがそのまま文字として表示されてしまうことがあります。
安全にHTMLタグを反映させるには、「safe(セーフ)」というフィルターを組み合わせます。
{{ _('Click <b>here</b> to start.') | safe }}
ただし、何でもかんでも「safe」を付けるのは危険です。信頼できる翻訳メッセージだけに使うようにしましょう。これは「この文字の中のHTMLタグは私が書いたものだから、そのまま実行しても大丈夫だよ」とプログラムに伝える役割を持っています。
5. 長い文章を翻訳する transブロックの使い方
一行だけの短い言葉ではなく、数行にわたる長い説明文などを翻訳したいときは、波括弧ではなく「{% trans %}」というブロックを使うと便利です。
これを使うと、HTMLの構造を保ったまま、中の文章だけを翻訳の対象として指定することができます。
{% trans %}
This is a very long paragraph.
You can write multiple lines here
and all of them will be extracted for translation.
{% endtrans %}
これを使うメリットは、翻訳ファイルを作るときに、改行なども含めて一つのまとまりとして扱いやすくなることです。サイトの利用規約や長い説明文に向いている書き方です。
6. 翻訳ファイルへの書き出しと注意点
HTMLにこれらの構文を書き込んだら、次に「メッセージ抽出(ちゅうしゅつ)」という作業を行います。これは、HTMLファイルの中から「_('...')」で囲まれた部分を自動的に探し出して、翻訳用のリストを作ってくれる作業です。
このとき、一文字でもスペルが違ったり、括弧を閉じ忘れたりすると、正しく抽出されません。初心者のうちは、コピー&ペーストを基本にして、正確に書く癖をつけましょう。
また、翻訳したい文字は必ずシングルクォート(')かダブルクォート(")で囲む必要があります。これを忘れると、プログラムは「文字」ではなく「変数」だと勘違いしてエラーを出してしまいます。
7. gettextとngettextの違いを整理しよう
ここで、よく使う二つの言葉を整理しておきましょう。
- gettext(ゲットテキスト):一番よく使います。単純な翻訳に使われ、テンプレート内では「_()」と短く書かれます。
- ngettext(エヌゲットテキスト):「n」はNumber(数字)のnです。数によって言い回しが変わる場合に使います。
基本的には「_()」だけ覚えておけば、サイトの8割以上は多言語化できます。複雑なことは後回しにして、まずは全ての表示文字を「_()」で囲むところから始めてみましょう。
8. 翻訳の文脈を指定する「context」の活用
同じ「Open」という言葉でも、ドアを「開ける」という意味と、設定を「公開する」という意味など、場面によって日本語訳が変わることがあります。
そんなときに、翻訳者へ「これは〇〇の場面で使う言葉ですよ」とヒントを与えるのが「context(コンテキスト)」です。
# Python側の例ですが、テンプレートでも似た概念があります
pgettext('menu', 'Open')
pgettext('file', 'Open')
これにより、同じ「Open」に対して、メニュー画面なら「開く」、ファイル操作なら「読み込み」といった異なる訳を割り当てることができるようになります。
9. テンプレート内で現在選択されている言語を知る
翻訳だけでなく、言語によって画像のデザインを変えたり、特定のリンク先を変えたりしたいこともあります。その場合は、現在どの言語が選ばれているかを確認するコードを書きます。
{% if get_locale() == 'ja' %}
<p>日本限定のキャンペーン実施中!</p>
{% else %}
<p>Check out our global offers!</p>
{% endif %}
「get_locale()」という命令を使うことで、今のサイトが何語モードで動いているかを判定できます。これを使えば、翻訳ファイルだけでは対応できない「表示内容そのものの切り替え」も自由自在です。
10. 初心者が多言語化でつまずかないためのコツ
最後に、作業をスムーズに進めるためのアドバイスです。それは「一気に全部やろうとしないこと」です。
まずはトップページの「こんにちは」だけを翻訳してみる。それができたら次はメニュー、その次は説明文……というように、少しずつ「{{ _('...') }}」の範囲を広げていきましょう。
多言語化は、地道な作業ですが、自分の作ったサイトがボタン一つで英語や他の言語に切り替わる瞬間は、エンジニアとして最高の喜びを感じるはずです。この基本構文をマスターして、世界中の人に届くWebサイトを完成させてくださいね!