Maputnik を翻訳可能にしています!

Posted by keita-kobayashi on August 19, 2024 · 2 mins read

お久しぶりです、Geolonia 小林です!

今回のトピックですが、 MapLibre / Mapbox GL のスタイルを編集するツール maputnik の翻訳の仕組み導入について書こうと思います。

背景

Geolonia は一般的なウェブサイトに地図を埋め込むツールとして最初立ち上げました。当時は日本のみならず、英語エリアもサービス提供したいと思ってサービスの管理画面を多言語対応するようにしていました(私がジョインする前の頃ですが笑)。そのときは、開発者が WordPress の開発に慣れていたので、 WordPress で使っている @wordpress/i18n を選択しました。

WordPress の PHP バックエンドは、昔から GNU gettext を利用しています。 gettext で使う PO ファイルを管理、生成したりするパイプラインや、そのプロセスに慣れているボランテイアの翻訳者が大勢いたため、 JavaScript の利用が多くなったときに JavaScript でも gettext と同様に開発できるように、先程の @wordpress/i18n が作られました。

利点としては翻訳ツールや翻訳用ストリングを抽出するツールのエコシステムが豊富(例えば、 Poedit というエディタは自動翻訳からプロジェクトごとの翻訳メモリ、20年以上前から開発してきている)

ただ、弱点としてはライセンスが GPL だ。 JavaScript の世界は、 MIT または ISC ライセンスが多く、 GPL との相性があまり良くなく、特にライブラリに GPL ライセンスを導入することはほぼ無理。

使用する翻訳ライブラリについて

2021年から「翻訳できますか?」という課題がずーとオープンし、maputnikのメンテナーの一人が react-i18next はいかがでしょう?というところからヒントをもらいました。

調べたら、 React との相性がとても良くて、クラスコンポーネントや関数コンポーネント、React外のコードでも簡単に使える。個人的に魅力的だったところは拡張性でした。例えばブラウザで稼働する前提なら i18next-browser-languageDetector や、翻訳ファイルを外部サービスでホスティングしたり、翻訳されていないストリングを検知したときにサーバーにお知らせする拡張など、エコシステムが揃っています。

react-i18next の導入

基本的に “Step by step guide” をそのまま上から下に使いました。

  1. i18n.ts ファイルを作成し、基本的な設定を行う。一番最初では、テスト用に翻訳ストリングをすべてそのままハードコードしました。
  2. maputnik はクラスコンポーネントを使うため、翻訳が必要なコンポーネントを withTranslationHigher-Order Component (HOC) でラッピングしました。
  3. 翻訳する箇所を t 関数でラッピングした。例えば、 <a href="..">Help</a> の箇所は、 <a href="..">{t("Help")}</a> というように変更。

クラスコンポーネントの場合

import { WithTranslation, withTranslation } from 'react-i18next';

type MyComponentInternalProps = {
  ...
} & WithTranslation;

class MyComponentInternal extends React.Component<MyComponentInternalProps> {
  render() {
    const t = this.props.t;
    return <a href="..">{t("Hello!")}</a>;
  }
}

const MyComponent = withTranslation()(MyComponentInternal);
export default MyComponent;

関数コンポーネントの場合

const MyComponent: React.FC<MyComponentProps> = () => {
  const { t } = useTranslation();
  return <a href="..">{t("Hello!")}</a>;
};

export default MyComponent;

先ほどリンクした HOC のドキュメンテーション ではクラスコンポーネントがもう推奨されていなくて、関数コンポーネントを推奨します、と書いてあるのでそのうちマイグレーションしていきたいと思っています。 react-i18next も、関数コンポーネントの方の書き方もシンプルになります。

テストについて

maputnik は単体テストも導入されていますが、 エンド・ツー・エンド(E2E)テストも含まれています。翻訳機能も、E2Eテスト対象となるので、翻訳切り替え等のテストも追加しております。 maputnik は cypress というE2Eテストフレームワークを導入していて、初めて使ったので合わせて感想を書きます。

cypress のサイトの表紙にある動画通り、ローカルでテスト実行するときは実際の画面を見ることができます。また、それぞれのテストの中にステップ等ありますが、失敗あるときにそれぞれのステップを見ることができ、「失敗したときの画面」「どこで失敗した」が非常にわかりやすい。

現在 Geolonia の社内プロジェクトではいくつかのテストフレームワークを puppeteer とつなぎ合わせてE2Eテストを実施したりしているのですが、今後 cypress を導入したいと思いました。

最後に

現在、プルリクがまだ作成途中です!翻訳ストリングを追加したり、手伝いたいなら声をかけてください!プルリクがマージされたら、他の言語もどんどん追加していきましょう。



Geolonia Maps を無料で試してみる

Geolonia では、ウェブ地図や位置情報を利用したウェブアプリケーションや、モバイルアプリケーションの開発を承っています。

お問い合わせ