Meteor + Blaze で匿名質問サービスをつくろう：第4夜 UI作成 前編

[Meteor + Blaze で匿名質問サービスをつくろう：第3夜 ルーティング](https://qiita.com/plageoj/items/f67f0a0d457c969cc063) から続きです。

# 多言語対応について
このプロジェクトのモデルにしていたサービスが日・英・中に対応していたので、
こちらも多言語対応を追加しましょう。
この決定は後になればなるほど大変ですからね。

とりあえず最初は日本語 (JA-JP) だけで作って、後で

+ 英語 (EN-US)
+ 日本語 (広島)
+ 日本語 (博多)

あたりを追加することにしましょう。いい考えじゃないですか。

## パッケージの導入

> すこしのことにも、先達はあらまほしきことなり。

と言うくらいですから、ただでさえ大変な多国語対応に先達がなかったら
とんでもないです。
幸い素晴らしい先達がいますので、ありがたく使わせていただきましょう。

```bash
$  meteor add tap:i18n

Changes to your project's package version selections:

aldeed:simple-schema  added, version 1.3.3
cfs:http-methods      added, version 0.0.32
coffeescript          added, version 1.0.17
meteorspark:util      added, version 0.2.0
raix:eventemitter     added, version 0.1.3
tap:i18n              added, version 1.8.2


tap:i18n: A comprehensive internationalization solution for Meteor
```

## 設定
言語を設定しないと、デフォルトの英語を読みにいってしまいます。
現段階では、とりあえず日本語決め打ちにしておきます。
ついでに元からあったコードも削除してしまいましょう。

```javascript:client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

const getUserLanguage = () => {
    return 'ja';
};

TAPi18n.setLanguage(getUserLanguage());
```

## 翻訳ファイルを用意
プロジェクトルートに `i18n` というフォルダを掘って、翻訳ファイルは
そこに入れておきます。
ファイル名のフォーマットは `<lang>.i18n.yml` もしくは `<lang>.i18n.json` です。

まずは `i18n/ja.i18n.yml` を用意しました。
中身は後で書きます。

## HTML への組み込み方
Blaze テンプレートでは、`{{_ "KEY"}}` と書くだけで探しに行ってくれます。
他にも構文があるのですが、それは [公式ドキュメント](https://atmospherejs.com/tap/i18n#languages-tags-and-translations-prioritization) を参照してください。

# UI を組む
UI、一番楽しい部分なんですが、一番手間のかかる部分でもあります。

私のような衝動的にサービスを作ってしまう人は bootstrap を使うのが
常套手段ですが、私はあれがどうも好きになれないのです。

細かいデザインは後編 (3月中旬を予定) に任せて、
純粋に機能を満足するための UI を作っていくことにしましょう。

**フルスクラッチで。**

具体的に言うと、HTMLしか書きません。

第3夜で作成したテンプレートに実装していきます。

また、`header` `footer` の2つのテンプレートを追加します。
これは router によって直接表示はしない、全ページ共通の要素です。

## body
現在 `{{> loginButtons}}` がありますが、これを削除します。

```html:client/main.html
<body></body>
```

## header
画面上部に常時表示されるやつです。サービス名と、ログインのボタンがあればひとまず十分でしょう。
ログインボタンは、ログイン中は表示しないようにしておきます。

```html:client/Templates/header.html
<template name="header">
    <header>
        <div class="center">
            <img src="" alt="{{_ "queuestion"}}">
        </div>
        <div class="right">
            {{#if loggingIn}}
                <button id="logout">{{_ "header.logout"}}</button>
            {{else}}
                <button id="login">{{_ "header.loginWithTwitter"}}</button>
            {{/if}}
        </div>
    </header>
</template>
```

`loggingIn` は、ログインされていれば `true` になる `accounts-ui` の関数です。
JS からは、`Meteor.loggingIn()` で参照できます。

## footer
画面下部に常時表示されるやつです。著作権表記だけ入れておきましょう。
後々こっそりプライバシーポリシーとかを追加するでしょう。

```html:client/Templates/footer.html
<template name="footer">
    <footer>
        <p class="center">
            queuestion<br>
            Copyright (c) 2018 by Penta
        </p>
    </footer>
</template>
```

## Home
デザインの凝った LP を作りたいのはやまやまですが、それは後です。
文面だけはこだわります。

```html:client/Templates/Home.html
<template name="Home">
    {{>header}}
    <h1>
        {{_ "home.intro"}}
    </h1>
    <p>
        <img src="" alt="{{_ "appName"}}">
    </p>
    <ol>
        <li>{{_ "home.feature1"}}</li>
        <li>{{_ "home.feature2"}}</li>
        <li>{{_ "home.feature3"}}</li>
    </ol>
    {{>footer}}
</template>
```
さきほど作った `header` `footer` テンプレートをインクルードするのを
忘れないように。

## User
質問一覧はこのあと DB から読み出すことになります。
ここではモックアップだけ作成しておきましょう。

```html:client/Templates/User.html
<template name="User">
    {{>header}}
    <h1>
        {{_ "user.queue"}}
    </h1>
    <ul>
        <li></li>
    </ul>
    <!-- TODO: ここにTwitterタイムラインを埋め込む -->
    {{>footer}}
</template>
```

## Enqueue
Meteor には `autoform` という強力なフォーム支援パッケージがありますが、
あえて使いません。超強力なので、いつか使うかもしれませんが。

```html:client/Templates/Enqueue.html
<template name="Enqueue">
    {{>header}}
    <h1>
        {{_ "enqueue.askQuestion"}}
    </h1>
    <form>
        <textarea id="question-content" placeholder="{{_ "enqueue.question"}}"></textarea><br>
        <label><input id="enable-ogiri" type="checkbox"> {{_ "enqueue.enableOgiri"}}</label><br>
        <button id="enqueue">{{_ "enqueue.enqueue"}}</button>
    </form>
    {{>footer}}
</template>
```

大喜利モードと称して、質問を投げられた人以外でも回答できる
仕組みを導入します。匿名でお題を投げるわけですね。
大喜利モードを選択するチェックボックスを設けました。

## Question
`User` 同様、モックアップを作成しておきます。

```html:client/Templates/Question.html
<template name="Question">
    {{>header}}
    <p>
        {{_ "question.question"}}<br>
    </p>
    <p>
        <button id="dequeue">{{_ "question.dequeue"}}</button>
        <button id="discard">{{_ "question.discard"}}</button>
    </p>
    {{>footer}}
</template>
```

## 翻訳

```yaml:i18n/ja.i18n.yml
queuestion: queuestion
header:
  logout: ログアウト
  loginWithTwitter: Twitter でログイン
home:
  intro: 自由で、オープンで、匿名の質問を。わずか2タップで。
  feature1: Twitter でログインして 質問受け付け用のURLをツイートする
  feature2: フォロワーさんがあなたに匿名で質問する
  feature3: Twitter タイムラインで質問に答える
enqueue:
  askQuestion: %s さんに質問してみましょう。
  question: 質問を入力
  enableOgiri: 大喜利モード ( %s さん以外も回答できるようになります)
  enqueue: 質問する
user:
  queue: あなたに寄せられた %s 件の質問
question:
  question: 質問が届いています：
  dequeue: 回答する
  discard: 破棄する
```

`%s` は動的置換の部分です。ぶっちゃけこの i18n フレームワークは使ったことが
ないので、うまく動くかどうかちょっと怖いですね。

# デザイン……
今は HTML しか書いていませんので、非常に残念な感じです。

が、

現役女子大生のつぶあんさん(仮)に、ロゴとページのデザインを手伝って
いただけることになりました。

> こいつぁちょいと他とちがうぜ!!ってキラキラ女子が思うやつにしよう
> - つぶあん

乞うご期待。

第5夜ではモックアップと DB を結びつけていきます。
いよいよ Meteor の本領発揮です。

[ソースをGitHubで見る](https://github.com/plageoj/queuestion/tree/5617f871a1c4fba99df46b8039426b776c483603)