JavaScript
HTML5
Meteor
BlazeJS
iron-router

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

Meteor + Blaze で匿名質問サービスをつくろう:第3夜 ルーティング から続きです。

多言語対応について

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

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

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

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

パッケージの導入

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

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

$  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

設定

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

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"}} と書くだけで探しに行ってくれます。
他にも構文があるのですが、それは 公式ドキュメント を参照してください。

UI を組む

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

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

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

フルスクラッチで。

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

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

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

body

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

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

header

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

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

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

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

Home

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

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 から読み出すことになります。
ここではモックアップだけ作成しておきましょう。

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

Enqueue

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

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 同様、モックアップを作成しておきます。

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>

翻訳

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で見る