spring of life

技術、ときどき日常のブログ(予定)

javascript の I18n 対応

Rails に含まれてる javascript に日本語が入ってたので多言語化対応してみた

こういう gem があるみたいなので使ってみた!

github.com

  • まずは gem をインストール
# Gemfile

gem 'i18n-js'
  • application.jsを修正
...
//= require i18n
//= require i18n/translations
...
  • app/views/layouts/application.html.erbを修正
<head>
  ...
  <script type="text/javascript">
    I18n.defaultLocale = "<%= I18n.default_locale %>";
    I18n.locale = "<%= I18n.locale %>";
    I18n.fallbacks = true;
  </script>
  ...
</head>
  • bundle exec rake i18n:js:exportを実行して各言語用のファイルを作成
    • config/locales以下の言語ファイルがtranslations.jsにコピーされる
  • あとはjavascript内でI18n.t('hoge')みたいな感じで書けばOK

以下はおまけ〜

  • config/i18n-js.ymlにいろいろ設定が書ける
    • 詳しくは 上のgithubのREADME見た方がいいかな。。。
    • 例えばこんな感じ
export_i18n_js: 'vendor/assets/javascripts' # i18n.js を出力する場所を指定
translations: # translations.js の設定
  - file: 'app/assets/javascripts/i18n/translations.js' # ファイルの出力場所
    only: '*.hoge' # ここに指定したものがtranslations.jsに追加される

この設定で言語ファイルが↓だと、fugatranslations.jsにコピーされない

# config/locales/ja.yml

ja:
  hoge:
    piyo: ほげ
  fuga:
    piyo: ふが

rails で bootstrap3-datetimepicker を使ってみた

しばらく新しいことをしてなかったので、ブログが書けなかった。。。

7月0回か〜まぁいろいろ忙しかったしなぁ



さてさて今回は、家計簿の登録画面で、日付を入力する時にカレンダーから選択できるようにしたということで、bootstrap3-datetimepckerの使い方の紹介。

Bootstrap 3 Datepicker

github.com


  • gem のインストール
    • rails で使う場合は、bootstrap3-datetimepicker-rails という gem があるので、それをインストールする
    • momentjs-rails と依存関係があるらしいので、一緒にインストールする
    • いちおうgithubに書いてある通りにバージョンも指定
gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47'
gem 'momentjs-rails', '>= 2.9.0'
  • application.js の更新
    • インストールした gem を使えるようにする
    • 日本語対応したい場合は、moment/ja も記載する
...
//= require moment
//= require moment/ja
//= require bootstrap-datetimepicker
...
  • application.css の更新
    • こちらは bootstrap-datetimepicker のみ更新
...
*= require bootstrap-datetimepicker
...
  • カレンダー表示関数作成
    • 最後にカレンダーを表示させる関数を coffeescript や js で書く
    • datetimepickerに渡すパラメーターのキー名はbootstrap3になってちょっと変わったりしてるから注意が必要かも
$ ->
  $('.datepicker').datetimepicker({
    format: 'YYYY-MM-DD',
    locale: 'ja',
    dayViewHeaderFormat: 'YYYY年 MM月'
  })
  return
  • あと、カレンダーがフォームの位置に表示されない場合は、以下のスタイルを追加する
# 入力フォーム

<span id='date-form' class='input-custom'>
  <%= f.label :date, t('views.payment.date').html_safe + ':' %>
  <%= f.text_field :date, {:class => 'form-control datepicker', :required => true} %>
</span>
# CSS

#date-form {
  position: relative;
}

ビューの作成

jenkins の cli でビューを作ってみた

まぁジョブを作った時と同じで設定ファイル(xml)を入力すればいいだけ。

execute 'create view' do
  command <<-EOF
cat /path/to/config.xml |
java -jar #{node[:jenkins][:cli_path]} -s #{node[:jenkins][:host]} create-view <ビュー名> --username=<ユーザー名> --password-file=<パスワードが書かれているファイルのパス>
  EOF
  user 'root'
end

ただ、ビューの設定だけが書かれているファイルは無くて、JENKINS_HOMEの下のconfig.xml( /var/lib/jenkins/config.xml とか)に設定が含まれてる

<views>
    <hudson.model.AllView>
      <owner class="hudson" reference="../../.."/>
      <name>all</name>
      <filterExecutors>false</filterExecutors>
      <filterQueue>false</filterQueue>
      <properties class="hudson.model.View$PropertyList"/>
    </hudson.model.AllView>
    <listView>
      ...
    </listView>
    <listView>
      ...
    </listView>
  </views>

手順としては、

  1. JenkinsのUIでビューを作成
  2. ↑のxml<listView>で囲まれている部分をコピーして別のファイルにペースト
  3. ↑のchefのレシピのcat /path/to/config.xml で作成したファイルを指定して chef 実行

Robotium でダイアログの操作

AndroidのテストでUIの操作する時にRobotium使ってて、今回ダイアログの操作をする必要が出てきたのでちょっと調べてみた。
まぁ大した話じゃないんだけどw

solo.clickOnView(solo.getView(R.id.select_category));  // ダイアログを表示するボタンを押下(ビューのIDで指定)
solo.waitForDialogToOpen();  // ダイアログが表示されるまで待つ 
solo.clickOnText("test");  // "test"を選択(表示されている文字列で指定)
solo.clickOnButton("OK");  // "OK"ボタンを押してダイアログを閉じる(表示されている文字列で指定)
  • soloはRobotiumで定義されているSoloクラスのインスタンス
  • ダイアログにはセレクトボックスが表示されている

Android + Mockito でテスト

また家計簿のアプリの話で、WebAPIを実行する時に使うHTTPクライアントのテストをする時にモックを使ってみた

インストール

下記のページを参考にjarを3つlibsに追加

y-anz-m.blogspot.jp

ただ、記事がちょっと古くて?dexmakerとかのダウンロードページへのリンク先が404なので、こちらからダウンロード

あとは、ダウンロードしたjarをlibsの下に入れてビルドパスの設定したら完了!

使い方

↓みたいな感じでモックを作成するメソッドを作ってみた

private void setupMock(HTTPClient httpClient, int statusCode, final String responseBody) {
  try {
    when(con.getResponseCode()).thenReturn(statusCode);
    when(con.getInputStream()).thenReturn(new InputStream() {
      private int position = 0;
      @Override
      public int read() throws IOException {
        return position < responseBody.length() ? responseBody.charAt(position++) : -1;
      }

      @Override
      public void close() throws IOException {}
    });

    Class<? extends HTTPClient> c = httpClient.getClass();
    Field f = c.getDeclaredField("con");
    f.setAccessible(true);
    f.set(httpClient, con);
  } catch (NoSuchFieldException e) {
    e.printStackTrace();
  } catch (IllegalArgumentException e) {
    e.printStackTrace();
  } catch (IllegalAccessException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

conHttpURLConnectionクラスのインスタンスで、HTTPClientがフィールドとして持ってるので、それをモックに差し替える感じ

で、connect()を実行した時に接続して欲しくないので、

@Before
public void setUp() throws Exception {
  super.setUp();
  System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
  con = mock(HttpURLConnection.class);
  doNothing().when(con).connect();
}

みたいに、doNothing()を使って文字通り何もしないように事前に設定しておく

あと、android で mockito を使う場合はプロパティ設定が必要らしい(自分の場合は下記記事のパターン2が必要だった)

qiita.com

複数選択ダイアログ作成

Android 初心者すぎてちょっと機能足すのにも結構時間かかる。。。

  • 家計簿のアプリで、費目(食費、交通費とか)を今まではキーボードで入力してたけど、選択できるようにした
  • 費目の入力欄のところにボタンを付けて、それを押すとダイアログが出てきて、表示される費目のリストを複数選択する感じ
  • 費目のリストは収支情報が登録されているサーバーのRailsアプリに実装されているWeb APIを使って取得できるようになっている

ビューの作成

カスタムビュー

今回、カスタムビューと呼ばれるものを作ってみたんだが、結構詰まった。。。

qiita.com

ここらへんを参考にしたかな〜

まだinflateとかの使い方がよく分からなくて、
View.inflate(context, R.layout.input_form, this);でビューが生成されるのがようやく分かった。。。

View layout = View.inflate(context, R.layout.registration_view, this);

inputViews = new InputView[INPUT_VIEW_SIZE];
inputViews[INPUT_VIEW_DATE] = (InputView) layout.findViewById(R.id.date);
inputViews[INPUT_VIEW_CONTENT] = (InputView) layout.findViewById(R.id.content);
inputViews[INPUT_VIEW_CATEGORY] = (InputView) layout.findViewById(R.id.category);
inputViews[INPUT_VIEW_PRICE] = (InputView) layout.findViewById(R.id.price);

1度inflateでビューを生成して、その後はfindViewByIdでビュー取得かな

キーボード設定

金額とか数字を入力するのが分かってる場合は、android:inputType="number"とか使うとデフォルトで数値入力のキーボードになってる

他にもいろいろ設定できるようで、下記にいろいろ書いてある

kuwalab.hatenablog.jp

文字の左右中央寄せ

android:gravityで設定できるっぽい

seesaawiki.jp

ちなみに、右寄せにしようとandroid:gravity="right"にしようとしたら警告が出て、android:gravity="end"にしろって言われた。。。

ダイアログの作成

参考にしたのは↓かな。というかコピペして、ちょっと修正するだけでいけたw

androidkaihatsu.seesaa.net

このサイトのサンプルは選択肢が固定値だったので、それをWeb APIを使って動的に作るようにした

その他メモ

res/values-ja/strings.xmlに入ってる文字列情報はgetResourcesメソッドとかを使うと取れるっぽい

getResources().getString(R.string.date);

参考サイト:
android.keicode.com



これでとりあえず参考になったサイトは全部貼り付けたかな。。。w

忘れないように貼り付けていかないと次思い出そうとした時に面倒だからな〜ブクマでもいいんだけどね

シーケンス図・クラス図の書き方 etc

自分で仕様書書くときに sphinx で plantuml 使ってて、主にシーケンス図・クラス図を書いてるので、参考にしたページをペタペタ貼っておきます(と言っても同じサイトですが。。。)

  • シーケンス図

yohshiy.blog.fc2.com

  • クラス図

yohshiy.blog.fc2.com

というか多分、検索したらトップに出てくるから載せる必要もないかもw

まぁ自分が作ってるアプリだと、このサイトの載ってるので十分UML作れるかな


あと、emacs で書いてるので専用のパッケージを入れてみた。手順としては

1. .emacs.el にパッケージの追加

(add-to-list 'package-archives '("melpa-milkbox" . "http://melpa.milkbox.net/packages/") t)

2. パッケージインストール

# emacs コマンド実行後
M-x package-install [RET] plantuml-mode [RET]

3. plantuml-mode 自動適用設定

(require 'plantuml-mode)
(add-to-list 'auto-mode-alist '("\\.uml$" . plantuml-mode))
(setq plantuml-jar-path "/path/to/plantuml.jar")

M-x plantuml-previewで作成中のUML図が emacs 上で見れるのが結構便利だった!