gettext一覧

Django 多言語機能 (i18n) を実装する

Django で多言語機能 i18n を実装します。

多言語機能の実装方法は大きく2つあり、言語コードを URL に含める方法と、言語コードを URL に含めずセッションで管理する方法があります。

ここでは、実装が簡単な言語コードを URL に含める方法で実装したいと思います。

完成イメージ

バージョン

  • Python 3.6.4
  • Django 2.0.3
  • gettext 0.19.8.1

インストール

Python, Django

Python と Django のインストールは、Python Web フレームワーク Django の環境を構築するの記事を参考にしてください。

gettext

Django の多言語機能を使うために、GNU gettext パッケージが必要です。私の環境ではすでにインストールされていましたが、入っていない場合は、インストールしましょう。

実装

settings.py

ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
    ...
    'app.app.AppConfig'
]
MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]
LANGUAGE_CODE = 'ja'
USE_I18N = True
from django.utils.translation import gettext_lazy as _
LANGUAGES = [
    ('ja', _('Japanese')),
    ('en', _('English')),
]
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

settings.py での i18n 設定は、主に4つです。

MIDDLEWARE

SessionMiddleware と CommonMiddleware の間に LocaleMiddleware をセットします。

USE_I18N

デフォルトで True になっていますので、そのままにしましょう。

LANGUAGES

LANGUAGES では、使用予定の言語を定義します。Django で使用できる言語一覧は、こちらで確認しましょう。

LOCALE_PATHS

LOCALE_PATHS は、翻訳テキストファイルと翻訳バイナリファイルを格納する任意の場所を指定します。

views.py

from django.shortcuts import render
from django.utils.translation import gettext as _

def index(request):
    view_trans = _('これはビューの翻訳です。')
    context = {'view_trans': view_trans}
    return render(request, 'app/index.html', context)

翻訳の実装方法は、HTML と Python で異なります。まずは、Python での実装方法ですが、django.utils.translation の gettext 関数を使用し、翻訳対象の文言を引数にセットします。

gettext as _ とするのが、慣例のようで、_(‘ここに文言を入れます。’) とします。

urls.py

from django.conf.urls.i18n import i18n_patterns
from django.urls import path

from app.views import index

urlpatterns = i18n_patterns(
    path('', index),
)

今回は、実装が簡単な URL に言語コードを含めるパターンで実装しますので、i18n_patterns を使います。

index.html

{% load i18n %}
<html>
<head>
</head>
<body>
<p>{% trans 'これはテンプレートの翻訳です。' %}</p>
<p>{{ view_trans }}</p>
</body>
</html>

HTML の翻訳です。i18n をロードして、trans タグでくくるだけです。

翻訳

makemessages コマンドで、先ほど実装した Python ファイルや HTML ファイルから翻訳用のテキストファイル django.po を生成し、生成された django.po に翻訳入れ、compilemessages コマンドで、翻訳用のバイナリファイル django.mo を生成し、完了です。

  1. makemessages
  2. django.po に翻訳を入れる
  3. compilemessages

この3つを実行するだけです。

makemessages

$ python3.6 manage.py makemessages -l en --no-location
processing locale en
$

makemessages を実行し、翻訳用テキストファイル django.po を生成します。makemessages はファイル名と行数も残してくれて便利なのですが、開発を続けていくと、行数が変わってしまい、コミットするとき、毎回毎回差分が出てしまうので、–no-location をつけましょう。

locale/en/LC_MESSAGES/django.po

$ cat locale/en/LC_MESSAGES/django.po
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-25 08:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

msgid "これはテンプレートの翻訳です。"
msgstr ""

msgid "これはビューの翻訳です。"
msgstr ""

msgid "Japanese"
msgstr ""

msgid "English"
msgstr ""

makemessages の実行で、上記の django.po ファイルを生成しました。このファイルに、下記のように翻訳を入れます。

...
msgid "これはテンプレートの翻訳です。"
msgstr "This is translation of template."

msgid "これはビューの翻訳です。"
msgstr "This is translation of view."
...

compilemessages

$ python3.6 manage.py compilemessages
processing file django.po in /home/vagrant/multi_lang/locale/en/LC_MESSAGES
$

翻訳を入れたら、compilemessges を実行し、django.po ファイルから、翻訳用のバイナリファイル django.mo を生成します。

tree

$ tree
.
├── app
│   ├── __init__.py
│   ├── apps.py
│   ├── templates
│   │   └── app
│   │       └── index.html
│   └── views.py
├── locale
│   └── en
│       └── LC_MESSAGES
│           ├── django.mo
│           └── django.po
├── manage.py
└── multi_lang
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

7 directories, 11 files

最終的にこのようなファイル構成になりました。

動作確認

runserver

$ python3.6 manage.py rumserver 0.0.0.0:8000

ブラウザで動作を確認するため、runserver を実行します。

ブラウザで http://192.168.33.10:8000/ja/ にアクセス

ブラウザで http://192.168.33.10:8000/en/ にアクセス

まとめ

Django で多言語機能 i18n を実装しました。

今回は、実装が簡単な URL に言語コードを含める方法を実装しましたが、django.utils.translation の activate を使えば、URL に言語コードを含めずに、多言語機能を実装することができます。言語コードは URL に含めたいくない場合は、こちらを使用してください。