xxxcaqui.log

ツッコミお待ちしています

Spree2.0のローカライズ(1)

Spreeのデフォルト言語は当然ながら英語なので、日本語化してみます。

なお、前回からの続きでspree_fancyが入っている場合、

Routing Error
No route matches {:controller=>"spree/taxons", :action=>"show", :id=>nil}
Try running rake routes for more information on available routes.

が出るので、spree_fancyが入っていないアプリケーションを作って試してください。

環境

spree_i18nを入れる

Spreeの多言語対応はRails標準のi18nを使って行われており、そのための辞書ファイルがspree_i18nとして開発されています。

というわけで、このgemを入れていきます。*1

まずはGemfileを設定。*2

#Gemfile
gem 'spree_i18n', github: 'spree/spree_i18n', branch: "3-0-stable"

そして、インストール。*3

$ bundle install
$ rails g spree_i18n:install
Would you like to run the migrations now? [Y/n] y

ロケールの設定

コメントアウトされているデフォルトロケールをアンコメントし、さらにデンマーク語(:de)を日本語(:ja)に変更します。

#config/application.rb
module Mystore
  class Application < Rails::Application
    config.i18n.default_locale = :ja
  end
end

これで、サイトの表示が日本語になるはずです。

f:id:xxxcaqui:20130526012000p:plain

通貨の設定

Webの管理画面から設定できます。

f:id:xxxcaqui:20130526015503p:plain

その他

他にもゾーンや都道府県の設定を行う必要があり、これらは通貨と同様にWebの管理画面から設定することができます。

しかし、現在、spree_i18nを有効にすると、管理画面のJavaScriptが有効に動作しなくなるために、ゾーンなどの設定を行うことができません。*4

この問題が解決し次第、続きを書こうと思っています。

*1:未確認ですが、「最低1回はデフォルト言語が英語の状態で管理画面にログインしていないとエラーが出る」という情報があります。その場合は言語を英語に戻してログインした上で再度下記の設定を行なってください。

*2:このエントリ執筆時点では、masterブランチを指定すると依存関係がぶつかったので、3-0-stableを指定しています。

*3:下記のrails g spree_i18n:installは公式マニュアルに書かれていませんでしたが、実行しないと「ActiveRecord::StatementInvalid in Spree/home#index Could not find table 'spree_taxonomy_translations'」といったエラーが出力されます。

*4:ロケールを:enに設定すると出来る。

Spree2.0をいじってみた。

今年の3月にSpreeの2.0がリリースされたので、いじってみました。

Spreeとは

Rails上でECサイトを簡単に作るためのgemです。
オープンソースで、Githubにて開発されています。

Spreeの特徴を公式サイトから引っ張ってくるとこんな感じ。

  • 全員のニーズを満たすのは無理(90%は用意してやるから10%は書け)
  • スーツではなくギークのために(EC-CUBEとは違うのだよEC-CUBEとは!)
  • 開発者には完全なコントロールを(いつだってビジネスドメインは強敵だ)
  • CMSではない(CMSが欲しけりゃRadiantでも使ってくれ)

環境

何はともあれSpreeを入れてみる

Getting startedに沿って設定していきます。

$ sudo apt-get install imagemagick
$ gem install rails bundler spree_cmd
$ rails new mystore
$ cd mystore
$ spree install
$ rails s

これで、ECサイトのサンプルが立ち上がります。*1

ショップ画面

f:id:xxxcaqui:20130523011933p:plain

管理画面

f:id:xxxcaqui:20130523012444p:plain

エクステンション

Spreeには、アプリケーションを拡張するためのエクステンションが存在します。
Spree Extension Registryには、現在320個ほど登録されています。

エクステンションを入れてみる

ここでは、spree_fancyというエクステンションを入れてみます。

#Gemfile
gem 'spree_fancy', git: 'git://github.com/spree/spree_fancy.git'
$ bundle install
$ bundle exec rails g spree_fancy:install
  append  app/assets/javascripts/store/all.js
  append  app/assets/javascripts/admin/all.js
  insert  app/assets/stylesheets/store/all.css
  insert  app/assets/stylesheets/admin/all.css
     run  bundle exec rake railties:install:migrations FROM=spree_fancy from "."
     run  bundle exec rake db:migrate from "."
==  AddSliderTaxonsAndApplyThem: migrating =================
==  AddSliderTaxonsAndApplyThem: migrated (1.0647s) ========
spree_fancy適用後のショップ画面

f:id:xxxcaqui:20130523015721p:plain

spree_fancyの削除

さくっと調べた感じだと、spree_fancyを一発でアンインストールできるコマンドはありません。

インストール時に表示された

  • app/assets/javascripts/store/all.js
  • app/assets/javascripts/admin/all.js
  • app/assets/stylesheets/store/all.css
  • app/assets/stylesheets/admin/all.css

あたりのspree_fancyに関する記述を削除すれば、とりあえずはspree_fancy適用前の状態に戻せます。

《2013-05-25 追記》
上で「とりあえず戻せる」と書きましたが、この方法で戻すと、後々日本語化をしたときにRoutingErrorが発生しました。
*2

エクステンションの作成

上記のspree_fancyのような便利なエクステンションですが、もちろん自分でも作ることができます。

作り方はこちらにあります。

このあたりは気が向いたら別エントリで書きます。気が向いたら。

*1:spree install実行時にバージョン関係のエラーが出ることがあります。その場合はGemfileで「gem 'spree_auth_devise', :git => 'https://github.com/spree/spree_auth_devise.git', branch: '2-0-stable'」などのようにbranchを指定してください。

*2:spree_fancyが使用しているテンプレートに含まれているnested_taxons_pathという名前付きルートにidを渡さなければならないところを、idなしで呼び出しているためにRoutingErrorが発生している模様。

Vimtutorをまとめてみる。

若者の間ではVimが流行っているらしいので、Vimを勉強するためにvimtutorでやったことをまとめてみる。

モードの概念とかは省きます。めんどいので。

1. カーソル移動

h 1文字左へ
j 1行上へ
k 1行下へ
l 1文字右へ
0 行頭へ
$ 行末へ
w 次の単語の初めへ
e 次の単語の終わりへ
b 前の単語の初めへ
% 対応するカッコへ

2. 保存・終了

:w filename filenameとしてファイルを保存
:q! 変更を破棄して終了
:wq 変更を保存して終了

3. テキストの挿入

i カーソル位置にテキストを挿入
a カーソル位置の後ろにテキストを挿入
A カーソル行の末尾にテキストを挿入
o カーソル行の下に行を挿入し、挿入モードに入る
O カーソル行の上に行を挿入し、挿入モードに入る

4. テキストの削除

x カーソル位置の文字を削除
dw カーソル位置から単語の末尾までを削除
d$ カーソル位置から行末までを削除
dd 行全体を削除

変更に用いるコマンドの形式は

コマンド 繰り返し回数 モーション

となっているため、d2wとすると、単語を2つ削除できます。

5. 範囲選択

v 範囲選択を開始する

範囲選択を開始した後、hjklなどで選択範囲を指定し続けてコマンド(dなど)を実行すると、選択範囲に対してコマンドを適用することができます。

6. テキストのコピー

y vコマンドで指定した選択範囲をコピーする

y$などのように、モーションを指定することもできます。

7. テキストのペースト

p コピーまたは削除したテキストをカーソル位置の後ろに貼り付ける

8. 文字を置き換える

r カーソル下の文字を置き換える(上書きする)
R カーソル下の文字を複数置き換える(上書きする)
cw カーソル位置から単語の末尾までを上書き
c$ カーソル位置から行末までを上書き

dコマンドと同じようにc2wとかもできます。

9. 操作の取り消し

u 前回の操作を取り消し
U 行全体の操作を取り消し
Ctrl-r 取り消しの取り消し

10. ファイルに関する情報を表示

Ctrl-g 全体の行数カーソル行の行数

11. 行の移動

G 最下行に移動
数字 G 数字で指定した行に移動
gg 先頭行に移動

12. 検索

/ 末尾に向かって検索
? 先頭に向かて検索
n 次の候補へ
N 前の候補へ

13. 置換

s/old/new/ カーソル行にある初めのoldをnewに置換する
s/old/new/g カーソル行にある全てのoldをnewに置換する
n,ms/old/new/g n行目からm行目までの全てのoldをnewに置換する
%s/old/new/g ファイル中にある全てのoldをnewに置換する
%s/old/new/gc 確認を行いながらファイル中にある全てのoldをnewに置換する

14. 外部コマンドの実行

:! 外部コマンドの実行
:!ls lsコマンドの実行(例)

15. ファイルの取り込み

:r filename filenameを取り込んでカーソル行の下に挿入する
:r !ls lsコマンドの出力を取り込んでカーソル行の下に挿入する

HerokuでRedmine使ってみた。

Redmineを落とす

$ git clone git://github.com/redmine/redmine.git
$ cd redmine

使用するバージョンを指定する

使いたいバージョンを選んで、git checkoutする。

$ git checkout 2.3-stable

precompile設定をする

#config/application.rb
module RedmineApp
  class Application < Rails::Application
    config.assets.initialize_on_precompile = false
  end
end

environment.rbを編集する

environment.rbの「exit 1」があるとmigration時に怒られるため、コメントアウトします。*1

# Make sure there's no plugin in vendor/plugin before starting
vendor_plugins_dir = File.join(Rails.root, "vendor", "plugins")
  if Dir.glob(File.join(vendor_plugins_dir, "*")).any?
  $stderr.puts "Plugins in vendor/plugins (#{vendor_plugins_dir}) are no longer allowed. " +
    "Please, put your Redmine plugins in the `plugins` directory at the root of your " +
    "Redmine directory (#{File.join(Rails.root, "plugins")})"
# exit 1
end

database.ymlを編集

あらかじめ用意されているスケルトンを編集して、Heroku向けのdatabase.ymlを作成する。

$ cp config/database.yml.example config/database.yml

MySQLの設定をコメントアウトし、下の方にあるPostgreSQLの設定を使用します。

#config/database.yml

production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: postgres
  password: "postgres"

#production:
#  adapter: mysql2
#  database: redmine
#  host: localhost
#  username: root
#  password: ""
#  encoding: utf8

シークレットトークンを作成する

必要なgemを入れ、secret_token.rbを作成します。*2

$ bundle install
$ bundle exec rake generate_secret_token

PostgreSQLのgem「pg」が入らない場合。

gitignoreを編集する

作成したシークレットトークンや編集したdatabase.ymlなどをGitの管理対象に加えるために.gitignoreから以下の6行を削除する。

#.gitignore
/config/database.yml
/config/initializers/session_store.rb
/config/initializers/secret_token.rb
/public/plugin_assets
/Gemfile.lock
/Gemfile.local

Heroku上にアプリケーションを作成・設定する

$ heroku apps:create your_app_name
$ git push heroku 2.3-stable:master
$ heroku run rake db:migrate
$ heroku run rake redmine:load_default_data
Select language[en]: ja
====================================
Default configuration data loaded.
$ heroku restart
$ heroku open

heroku openで開ければOKです。

初期アカウントadmin/adminでログインしてアカウントを作成し、admin/adminを削除してください。

補足:PostgreSQLのgemが入らない場合

bundle installしたときに、以下のようなエラーが出て、pgが入らないとこがあります。

Gem::Installer::ExtensionBuildError:
  ERROR: Failed to build gem native extension.

  ~/.rvm/rubies/ruby-1.9.3-p194/bin/ruby extconf.rb 
checking for pg_config... no
No pg_config... trying anyway.
If building fails, please try again with
 --with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason,
probably lack of necessary libraries and/or headers.
Check the mkmf.log file for more
details.  You may need configuration options.

Gem files will remain installed
in ~/.rvm/gems/ruby-1.9.3-p194/gems/pg-0.15.1 for inspection.
Results logged
to ~/.rvm/gems/ruby-1.9.3-p194/gems/pg-0.15.1/ext/gem_make.out
An error occured while installing pg (0.15.1),
and Bundler cannot continue.

その場合には、libpq-devを入れてください。*3

$ sudo apt-get install libpq-dev

*1:ローカルに/vendor/pluginsがなくても、if文の中に入ります。Heroku側の仕様?

*2:このbundle installはdatabase.ymlの編集後に行なってください。Gemfile内でdatabase.ymlを読み込んで、インストールするgemを判別します。

*3:少なくとも、Ubuntu12.04の場合。

1台のサーバで複数のSSL通信をする

ApacheのNameVirtualHostで設定した複数のサイトでHTTPS通信をしたかったので、いろいろ調べてみた。

その過程でわかったことをまとめてみます。
間違い等あると思うので、ご指摘お願いします。

SSL通信の仕様

SSLの仕様として

あるIPアドレスとポートの組み合わせに対して紐付けられるサーバ証明書は1つだけ

というものがあります。*1

逆に言えば、IPアドレスかポートを変更すれば、複数のサーバ証明書を持つことができます。

IPアドレスを変える場合

  1. xxx.xxx.xxx.xxx(1枚目)
  2. yyy.yyy.yyy.yyy(2枚目)

ポートを変える場合

  1. xxx.xxx.xxx.xxx:443(1枚目)
  2. xxx.xxx.xxx.xxx:444(2枚目)

上記のような形でWebサーバのバーチャルホスト設定をすれば、1台のサーバ上で複数の証明書を用いて通信することができます。

単一のIPアドレスとポートで複数のSSL通信をするには?

IPアドレスやポートを変えれば、1台のサーバで複数のサーバ証明書を持つことができると書きました。
しかし、不特定多数に公開しているサーバでバーチャルホスト設定をするときにはネームベースで設定することが多いと思います。*2

つまり、ドメイン名ごとに証明書を切り替えたい。

ただし、前述の通り、あるIPアドレス:ポートの組み合わせに対して指定できるサーバ証明書は1つだけです。

この制限に引っかからないように、複数ドメインでのSSL通信を実現するための方法が2つあります。*3

  1. ワイルドカード証明書
  2. マルチドメイン証明書

どちらの証明書も単一のサーバ証明書の中に複数のドメインを紐付けすることによって、「あるIPアドレスとポートの組み合わせに対して紐付けられるサーバ証明書は1つだけ」という仕様を守りつつ、複数ドメインのSSL通信に対応しています。

これから、それぞれの証明書について書いていきます。

ワイルドカード証明書

ワイルドカード証明書は1つの証明書でCN(コモンネーム)のサブドメインすべてをカバーする証明書です。

CNを*.example.comで申請した場合

example.com 有効
www.example.com 有効
admin.example.com 有効
smtp.example.com 有効
www.admin.example.com 無効
example.net 無効

同じ階層にある複数のサブドメインSSLを使いたい場合に有効です。
ただし、バーチャルホストで「example.com」と「example.net」を扱いたい場合など、異なるドメインの間では使用出来ません。

また、VeriSignが発行していないなど、入手できるサイトが若干限られています。

マルチドメイン証明書

マルチドメイン証明書は1つの証明書に対し、通常のCNを登録するだけでなく、SANs(Subject Alternative Names)に記載されたドメインへのSSL通信を可能にする証明書です。

ワイルドカード証明書にはできない別ドメインの証明も行える一方、サブドメインについてもひとつひとつ別々に登録する必要があります。

なお、発行会社によって登録可能なドメインの数は異なりますが、概ね100〜150個のドメインをひとつの証明書に登録できます。

このように便利なマルチドメイン証明書ですが、TLS拡張のSNIという技術を使用するため、WindowsXP*4やいわゆるガラケーなどの環境では使えません。*5

まとめ

HTTPSでアクセス可能な複数ドメインをバーチャルホストで運用するためには、

顧客に対して間口を広げる必要があり、かつ、クレジットカード情報等を扱うためにHTTPSを必須とするECサイトとかはどうすればいいんですかね?

*1:SSLハンドシェイクに関連する制約です。

*2:複数のIPアドレスを持っているサーバばかりではないし、ポート指定はいろいろ困る。

*3:他にUCC(Unified Communications Certificate)というものもあるようですが、Windows Exchange Server用の証明書のようなので、とりあえずスルーします。あと、マルチドメイン証明書との具体的な違いもよくわからない。

*4:ただし、Chromeを除く。

*5:ちなみに、前述のUCCはWindowsでサポートされてるみたいです。