日本語を読めない方または日本に住んでいない方と対応ができたとしたら、ウェブサイトで 売り上げを上げたり、リーチを広げることができます。
国際化のテーマは広いので、このハンズオンは翻訳だけにフォーカスをします。
ハンズオンを始める前に国際化や i18n
の言葉の説明をします。
1970年代か1980年代かにDECで作られた用法といわれる
i18n "internationalisation" と "localization" の違いは微妙です。簡単説明すると i18n は全世界の方々がコンテンツに手を入れることです。l10n は場所、通貨などに対応するコンテンツです。
英語と日本語のウェブサイトは i18n と考えていいです。
USD や GBP や AUDで買い物できるサイトは l10n として考えていいと思います。
残念ながら違いがぼやけていますのであまり重要じゃないと思います。
ハンズオンのために Node.js が必要となります。
そしてサンプルファイルをダウンロードするか、 git 経由で clone してください。
$ git clone https://github.com/kfug/handson
ハンズオンを始める前に、
$ cd [ハンズオンの資料のディレクトリ]/try_i18n
とコマンドを使用し、try_i18n
ディレクトリに入りましょう。
try_i18n
のフォルダーに build.js
というファイルが入っています。 build.js
はフレームワークとライブラリーなしで動いています。ハンズオン中は build.js
を書き変えが必要となります。
node build.js
を呼ぶと すごく簡単な ビルドが動いています。ビルドで src
や template
のフォルダーに入っているファイルを使って build
フォルダーにウェブサイトを書き出しています。
例えば: ソースフォルダーに入っている index.html
は {{head}}
のプレースホルダーがあります。ビルド中にはその {{head}}
が fillPlaceHolder
の関数で template/head.html
にリプレースされています。その上は template/head.html
に {{title}}
というプレースホルダーが入っています。build.js
の VARIABLES
変数に title
というプロパティーが入っていますので テンプレートの代わりにそれを使っています。
ハンズオン中は一つ一つのステップごとに node build.js
を読んでください。build
フォルダーの中のファイルはそのままブラウザーを使って見てください。チェンジをすぐ見たい場合は slr
みたいなウェブサーバーを使ってもいいと思います。(インストールは npm i slr -g
動かすのは slr build
)
メモ:全ての JavaScript コードは standard フォーマッティングに書いています。
翻訳のコストを減らすために、同じサイトストラクチャーを使って二つのサイトを書き出すのがはじめてのタスクです。
そのために build.js
のファイルを書き換えましょう。今のビルドコードの
processFiles(SOURCE, TARGET, {
title: 'Cool Homepage'
})
をこれに書き換えましょう:
processFiles(SOURCE, path.join(TARGET, 'ja'), {
title: 'クール ホームページ'
})
processFiles(SOURCE, path.join(TARGET, 'en'), {
title: 'Cool Homepage'
})
そうするとビルドの後で build
フォルダーには二つのサイトがに入っています。
今のテンプレートは文字コードが付いていません。普通は PHP などが HTTP の ContentType ヘッダーを送ってきています。サーバーを使えない場合は HTML の中に charset のスペックが必要となります。
template/header.html
に <meta charset="utf-8" />
を第1行目につけてください。
メモ: meta の html タグの順番は大事です。Charset のタグは絶対に第一のタイトルタグにしてください。
Google などのクローラーは自分であなたのウェブサイトの言語を調べることがだいたいできます。そのクローラーが間違えないように lang
のプロパティーを html タグにつけましょう。その言語は ISO 639 のコードにしてください。
<html>
を <html lang="...">
に変換してください。
SEO のために alternate リンクをページにつけるのは大事です。Google の三つの方法の中では htmlタグがこのハンズオンのために一番簡単な方法です。 alternate のタグでそれぞれのページと別の言語のバーションにリンクします。
例: en/index.html
は ja/index.html
にリンクして ja/index.html
は en/index.html
をリンクしないといけません。
ヒント: build.js
は {{path}}
to {{file}}
の変数を用意しています。
今のウェブサイトを公開して Google で検索したら、それぞれのウェブサイトを見つけられるはずです。ただ、サイトのリンクは別の方法でもシェアできますので、その場合はユーザーが自分の言語を選ぶ必要があります。
言語メニューは普通のメニューと同じく <nav>
にしましょう。リンクは alternate のリンクと同じにしてください:
<nav>
<a href="...">...</a>
</nav>
en
と ja
は技術者にはわかりやすいと思いますが普通の人はちゃんとした名前を好みます。
言語メニューの名前選ぶ方法は二つが考えられます:
(A) English
と Japanese
(B) English
と 日本語
(A)バーションは間違いです。日本語の方々の中には Japanese
が読めない
人がいるかもしれません。
build.js
に英語版の新しいプロパティー otherLangName
は 日本語
にしましょう。
日本語版は English
にしましょう。そして template/nav.html
は
<a href="...">{{otherLangName}}</a>
は使うようにしましょう。
ヒント:知らない言語の名前であれば ISO 639 の一覧で調べましょう。
サンプルサイトのテキストは相変わらず英語です。それを日本語にしましょう。まずは src/index.html
と src/product.html
のテキストを build.js
にコピーしましょう。
processFiles(SOURCE, path.join(TARGET, 'ja'), {
title: 'クール ホームページ',
lang: 'ja',
otherLang: 'en',
otherLangName: 'English',
index: {
title: '...',
content: '...'
},
product: {
title: '...',
content: '...'
}
})
それから src/index.html
や src/product.html
のテキストを新しいプレスホルダーに書き換えましょう。
<h1>{{index.title}}</h1>
...
日本語のコンテンツは
ID | 日本語 |
---|---|
index.title | Frontend Conference 2016にようこそ! |
index.content | 今日は国際化を学びましょう。プロダクトやエンタテインメントを世界中でシェアできるように。私たちのスキルは関西のために大切です。 |
product.title | 会議用プロダクト! |
product.content | 何かを売らないといけません。この仕事でお金が入った方がいいですよね? |
次のものはすぐできると思います。コンテンツと同じようにリンクの HTML タグを書き換えてください。
<a href="...">{{link.head}}</a>
ID | 日本語 |
---|---|
link.home | ホーム |
link.product | 商品 |
Google Chrome を使っている方は Google の自動翻訳システムを見たことがあるでしょう。
ただ一つの html タグを head に追加したらそのバーが出てるのを減らされます。以下のタグを template/head.html
に追加してください。
<meta name="google" content="notranslate" />
たまに言語によってスタイルシートを書き換える必要があります。スタイルシートは大きくなったらそれぞれの言語に分けた方がいいと思いますが例の CSS は小さくて一つのシートにするのは問題ないです。
以前は HTML タグに lang
のプロパティーを追加したために英語と日本語のサイトのフォントサイズが変わりました。
だからフォントサイズを合わせましょう。
html {
font-size: 14px;
line-height: 1.5em;
}
そして例のために日本版を
html[lang=ja] {
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
}
今のサイトは /en/
または /ja
を使わないとアクセスできません。それをこれから改善しましょう。/
サイトに特別なページを用意しましょう。まずは build.js
に新しいステップをつけましょう。
processFiles(path.join(ROOT, 'global'), TARGET, {})
この行をつけると global
フォルダーをルートに書き出してきます。global
というフォルダーはまだないので作ってください。そして global
に index.html
を作りましょう。
<html>
<head>
<meta charset="utf8" />
<link rel="stylesheet" href="en/css/style.css" />
</head>
<body>
<a href="en/index.html">English</a>
<a href="ja/index.html">日本語</a>
</body>
</html>
ルートサイトがありますが SEO のために en
と ja
のサイトにルートへのリンクをつけましょう。(詳しくは Googleのサイトに) バックリンクは x-default
の link ヘッダータグです。
<link rel="alternate" href="../" hreflang="x-default" />
そのリンクは template/head.html
につけましょう。
基本的に http の Accept-Language のヘッダーはリダイレクトのために使えますがユーザーはそれをあまり喜びません。MDN にも書いてあります。
Site-designers must not be over-zealous by using language detection via this header as it can lead to a poor user experience:
- They should always provide a way to overcome the server-chosen language, e.g., by providing small links near the top of the page. Most user-agents provide a default value for the Accept-Language: header, adapted to the user interface language and end users often do not modify it, either by not knowing how, or by not being able to do it, as in an Internet café for instance.
- Once a user has overridden the server-chosen language, a site should no longer use language detection and should stick with the explicitly-chosen language.. In other words, only entry pages of a site should select the proper language using this header.
日本語に翻訳:
ユーザーエキスペリエンスが悪くならないようにサイトデデザイナーは自動言語検出を使いすぎない方がいいです:
- どんな時でもサーバーが選んだ言語を変える方法を用意した方がいいです。例えば:ページの上の方に言語リンクの一覧をつける。普段はユーザーが Accept-Language ヘッダーのディフォルト設定を使っています。理由はその設定があるのを知らないか設定の変換の許可がないかからです。
- 一度ユーザーがサーバーの選んだ言語を変えたら、自動システムはやめた方がいいです。別の言い方をするとリダイレクトはエントリーページだけに使った方がいいです。
その通りに以下のスクリプトが用意してあります。
autoDetect()
function autoDetect () {
if (!localStorage) {
return // 保存できない場合はリダイレクトしない
}
if (localStorage.getItem('firstRedirect')) {
return // 以前リダイレクトしたから今回はリダイレクトしない
}
// 今回のリダイレクトを保存する
localStorage.setItem('firstRedirect', true)
// ブラウザーの言語
var lang = getBrowserLanguage()
// 言語を選ぶ
lang = lang.toLowerCase()
lang = (lang === 'ja' || lang == 'ja_jp') ? 'ja' : 'en'
document.location.assign(lang + '/index.html')
}
// クロスブラウザーの言語を調べるスクリプト
function getBrowserLanguage () {
var nav = navigator
return (nav.languages && nav.languages[0])
|| nav.userLanguage
|| nav.language
|| 'en-US'
}
そのスクリプトを global/index.html
に追加してください。
<script type="text/javascript">
...
</script>
今までは build.js
のデータはただの JavaScript オブジェクトです。翻訳者にそれを渡すのが難しいです。CSV データに書き換えるとこれからのプロセスが簡単になります。
CSV を Node.js で使うために csv-parse
パッケージを try_i18n
のフォルダーにインストールしないといけません。
$ npm init -y; npm i csv-parse
そしてデータを lang.csv
に書き換えましょう。
id,en,ja
title,"Cool Homepage","クール ホームページ"
lang,en,ja
otherLang,ja,en
otherLangName,日本語,English
index.title,"Welcome to the Frontend Conference 2016!","Frontend Conference 2016にようこそ!"
index.content,"Today we will study internationalization to bring commerce and entertainment from and to Osaka. Our skill is important for making Kansai better.","今日は国際化を学びましょう。プロダクトやエンタテインメントを世界中でシェアできるように。私たちのスキルは関西のために大切です。"
product.title,"Product for the conference!","会議用プロダクト!"
product.content,"Because you will need to buy something, else it isn't gonna pay for itself.","何かを売らないといけません。この仕事でお金が入った方がいいですよね?"
link.home,"Home","ホーム"
link.product,"Product","商品"
build.js
の CSV 用の変数 readLangCSV
は用意してあります。
var ALL_VARIABLES = readLangCSV('lang.csv', ['en', 'ja'])
ALL_VARIABLES
にこのようなオブジェクトが入っています。
{ en:
{ title: 'Cool Homepage',
... } },
ja:
{ title: 'クール ホームページ',
... } }
そうして ALL_VARIABLES
の変数を使って processFiles
を書き換えてください。
processFiles(SOURCE, path.join(TARGET, 'en'), ALL_VARIABLES.en)
processFiles(SOURCE, path.join(TARGET, 'ja'), ALL_VARIABLES.ja)
CSV ファイルを GIT またはメールで管理するワークフローは、翻訳者には不便なことがあります。
Google Spreadsheetsを使うと幾つかいいことがあります。lang.csv
のデータを新しいシートにインポートして下さい。
スプレッドシートを作った時に翻訳者とシェアする。
そしてノティフィケーション設定をつけましょう。
そうすると翻訳者または別のチームメンバーは何かチェンジがあった場合すぐメールでノティフィケーションが入ります。変わった時にすぐに CSV エキスパートしたらすぐサイトをアップデートできます。
Google だけではなくて Facebook も国際化のルールがあります。まずは FB は全ての ISO 639 の
言語に対応していません。言語の XMLをチェックすると en
の代わりに en_US
などを使わないといけません。 ja
は ja_JP
になります。
それを踏まえて og:language
のタグをつけましょう。lang.csv
に fbLang
をつけるのを忘れないでください。
<meta property="og:locale" content="{{fbLang}}" />
残念ながら Facebook の言語サポートはサーバーソフトなしでは対応できません。別の言語に対応したい場合 は ?fb_locale=ja_JP
または ?fb_locale=en_US
のリクエストでそれぞれのバーションを出さないといけません。今のサイトの URL パターンを http://site.com/product.html?fb_locale=en_US
にするのが役に立つと思います。
og
タグがサイトについてからはサイトもシェアしたいですよね。そのまま Facebook のシェアスクリプトを使って Like ボタンをつけたら en_GB
の UI が出てきます。
<div class="fb-like" data-href="https://developers.facebook.com/docs/plugins/" data-layout="standard" data-action="like" data-show-faces="true" data-share="true"></div>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v2.5&appId=<app_id>";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
ちゃんと言語が出るように頑張りたかったらスクリプトの en_GB
の部分の代わりに以前に用意した {{fbLang}}
を使って template/footer.html
に追加してください。
メモ:build
フォルダーの中のファイルをそのままブラウザーで開いたら Facebook のボタンが出てきません。ウェブスペースにアップロードしたら動くようになります。ローカルでサイトをテストしたい場合はパソコンにサーバーを立ち上げてください。私は開発するためによく slr
を使います。
お疲れ様です! この小さなサイトで一応翻訳ワークフローができたと思います。それ以上は色々細かいことがありますが、このワークフローを使うと一応自分のウェブサイトを翻訳できると思います。
「はい!サイトを翻訳したい!」と思うようになったら、たぶん次の質問は「翻訳者どこで見つけるか?」となります。基本的に最近では三つのオプションがあります。
今回使ったツールは全て軽くてあまりフィーチャーがありません。それより格好いいサイトをもっと早く国際化したいと思ったら以下のリンクリストを見てください。