【ITニュース解説】Localizing a Django app into 7 languages — RTL, a JS game, and the honest parts
2026年10月23日に「Dev.to」が公開したITニュース「Localizing a Django app into 7 languages — RTL, a JS game, and the honest parts」について初心者にもわかりやすく解説しています。
ITニュース概要
Djangoアプリを7言語に多言語化した開発ノウハウを紹介。画面表示と記事内容で翻訳の仕組みを分離し、右から左へ書く言語や未翻訳時の英語フォールバックに対応。構造整合性チェックなど、世界中のユーザーに届けるための工夫を学ぶ。
ITニュース解説
システムエンジニアを目指す皆さん、現代のWebアプリケーション開発において、世界中のユーザーにサービスを届けることは非常に重要です。今回解説するのは、たった一人の開発者がDjango製のアプリケーションを7つの言語に対応させた事例だ。この経験談は、国際化(i18n)や地域対応(L10n: ローカライゼーション)の具体的な課題と解決策を学ぶ上で非常に参考になる。
まず、なぜ多言語化に取り組む価値があったのかという点から解説する。このプロジェクトは無料で提供される学習コンテンツが中心であり、世界中の多様な背景を持つ人々が、母国語で学習できる環境を提供することは、ユーザー体験を大幅に向上させる。例えば、バングラデシュやエジプトのプロジェクトマネージャーが、第三言語である英語ではなく、自分の使い慣れた言語で学習できることは、学習効率や理解度を高める上で不可欠だ。さらに、多言語化は検索エンジン最適化(SEO)の観点からも大きなメリットがある。一つの英語コンテンツが七つの言語に対応することで、検索エンジンがインデックスするページの数が劇的に増加し、サイトの露出機会が格段に増えるため、多くの潜在ユーザーにリーチできるようになる。
このプロジェクトでは、初期段階でAIによる機械翻訳が活用されたが、その品質については「翻訳はベータ版である」という正直なラベルを付与することで、ユーザーからの信頼を損なわないよう配慮されていた。
多言語化の作業を進める上で、まず重要なのは、アプリケーションを構成する要素を大きく二つに分けることだ。一つは、ナビゲーションメニュー、ボタン、フォームのラベルといった、アプリケーションの「見た目の枠組み」にあたる部分だ。これは「Chrome」と呼ばれ、Djangoに標準搭載されているgettextという強力な国際化ツールを使って翻訳された。gettextは、アプリケーションのコードやテンプレート内に埋め込まれた翻訳対象の文字列を抽出し、翻訳者が.poファイルという形式で翻訳文を記述できるようになる。
もう一つは、チュートリアル記事のような「長文のコンテンツ」だ。これをgettextで翻訳しようとすると、パラグラフごとに翻訳IDを管理することになり、非常に手間がかかる。そこで、この部分は言語ごとに独立したMarkdownファイルとして管理し、もし特定の言語のファイルが存在しない場合は、自動的に英語のファイルを表示する仕組みが採用された。このUIの枠組みとコンテンツを異なるシステムで管理するアプローチが、多言語化を効率的に進める上で最も重要な決定事項だった。さらに、アプリケーションの核となる専門用語、例えば「ワーク・ブレイクダウン・ストラクチャー」のようなプロジェクト管理の用語は、特定の試験体系と紐づいているため、翻訳せずに英語のまま維持するという方針が取られた。これにより、利用者が混乱することなく、情報の正確性が保たれる。
次に、実際に直面した技術的な課題と、その解決策を見ていこう。
特に注意が必要だったのは、アラビア語のように「右から左へ記述する(RTL)」言語への対応だ。RTL言語のテキストは、Webブラウザのdir="rtl"属性を設定するだけで自動的に反転表示されるが、UI全体のレイアウトはそう簡単にはいかない。これまでのCSSではmargin-leftやpadding-rightのように、物理的な方向を指定するプロパティが使われていたが、RTL環境ではこれらが逆の挙動をするため、見た目が崩れてしまう。この問題の解決策は、margin-inline-startやtext-align: startといった「論理的なプロパティ」を使うことだ。これらのプロパティは、テキストの記述方向に応じて自動的に左右の配置を調整してくれるため、一つのCSSファイルでLTR(左から右)とRTLの両方に対応でき、余計なスタイルシートを記述する必要がなくなる。
Djangoの言語タグ(例: zh-hans)と、コンテンツを格納するディレクトリ名(例: zh/)で異なる命名規則を使ってしまったことも、一時的にページが正しく表示されない原因となった。このような細かな部分でも、URLのプレフィックスには完全な言語タグを、コンテンツの参照にはベースとなる言語タグを使うなど、一貫したルールを定めておくことが重要だ。
Webアプリケーションでは、JavaScriptを使って動的にUIを生成する場面も多いが、サーバー側で処理されるDjangoの翻訳タグは、JavaScriptで生成された文字列には適用できない。この課題に対しては、Djangoが提供する「djangojsカタログ」という専用の仕組みが活用された。makemessages -d djangojsコマンドでJavaScript用の翻訳ファイルを作成し、JavaScriptコード内でgettext()関数を呼び出すことで、クライアントサイドの動的なコンテンツも多言語化することが可能になる。
すべての言語の翻訳が同時に完了するとは限らない。ある言語の特定のレッスンがまだ翻訳されていない場合、そのページが404エラーになることを避けるため、「翻訳されていないコンテンツは英語で表示する」というフォールバック(代替)の仕組みが導入された。これにより、ユーザーは翻訳が途中でもアプリケーションを利用でき、途中で利用を諦めることなくコンテンツにアクセスし続けられる。また、翻訳は単にテキストを置き換えるだけでなく、元のコンテンツの構造を正確に保つ必要がある。特に、セクションのアンカーリンクや内部IDが変更されると、他のページからのリンクが壊れてしまう可能性がある。このため、翻訳されたファイルが英語のファイルと同一の構造を持っているかを自動的にチェックする「パリティテスト」が導入された。これにより、翻訳者が誤って構造を変更してしまうことを防ぎ、アプリケーション全体の整合性が保たれる。
訪問者の言語を適切に選択するため、匿名ユーザーに対してはIPアドレスから国を推定し、そこから最適な言語を判断した。ログイン済みのユーザーには、登録時に設定した国情報に基づいて言語を決定する。もちろん、明示的にユーザーが言語を切り替えた場合は、その設定が最優先され、記憶される。
実際にDjangoで多言語化を実装する手順は、比較的シンプルだ。まず、settings.pyファイルでUSE_I18N = Trueを設定し、利用する言語のリスト(LANGUAGES)と翻訳ファイルの格納場所(LOCALE_PATHS)を定義する。そして、LocaleMiddlewareをミドルウェアに追加して、言語切り替えの機能を有効にする。次に、urls.pyでi18n_patternsを使ってURLに言語プレフィックスを追加する。これにより、例えば /learn/ は /bn/learn/ や /ar/learn/ のように、言語ごとのパスを持つようになる。テンプレートファイルでは、{% load i18n %}を宣言し、翻訳したい文字列を{% trans "Learning Centre" %}や{% blocktrans %}Learn by doing.{% endblocktrans %}のようにマークアップする。これらのタグで囲まれた文字列が、翻訳の対象となる。マークアップが完了したら、python manage.py makemessages -l bn -l arといったコマンドで翻訳ファイルを抽出し、抽出された.poファイルに翻訳文を記述し、最後にpython manage.py compilemessagesを実行して、機械が読み込むための.moファイルに変換する。RTL対応のCSSについては、HTMLの<html>タグにdir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}"と記述し、CSSでは先述の論理プロパティを使用することで実現できる。これにより、動的に言語の方向が切り替わり、統一されたスタイルで表示される。
このように、一見複雑に見える多言語化の作業も、「UIとコンテンツの分離」、「専門用語の明確な定義」、「論理的なCSSプロパティによるRTL対応」、「部分翻訳時の適切なフォールバック」、そして「構造の整合性を保つテスト」といった明確な原則と、Djangoの強力な国際化機能を組み合わせることで、一人の開発者でも大規模なアプリケーションに対応させることが可能だ。特に、AIによる機械翻訳を初期段階で活用しつつ、その品質状況を正直にユーザーに伝える姿勢は、信頼を得る上で非常に重要だ。システムエンジニアを目指す皆さんにとって、このような実践的な多言語化の経験は、今後のキャリアにおいて大きな強みとなるだろう。