blog.katsuma.tv

middleman 3.2系から3.3系へupgrade時、wrap_layoutに気をつける

  • 2014年9月 6日 23:25
  • ruby

ALOHA FISHMANSのサイトで使ってるmiddlemanのバージョンは、長らく3.2.0を使っていたのですが、いい加減そろそろ最新のバージョンにあげておくか。。と思ったところ、結構ハマったのでメモ。

空白のページがrenderされる

バージョンの変更はGemfileを書き換えてbundle updateすると、基本的にはOK。Gemfileのdiff的にはこんなかんじ。

 gem "redcarpet", '~> 3.1.1'
-gem "middleman", "~> 3.2.0"
+gem "middleman", "~> 3.3.5"
 gem "middleman-blog", '~> 3.5.2'
 gem "middleman-minify-html", '~> 3.1.1'
 gem "middleman-deploy", '~> 0.2.3'

renderされるページの内容を確認していたところ、基本的に問題ないように見えつつ、blogページだけ何も出力されません。(bodyがカラ)

何か仕様が変わったんだろうと思いつつ、ChangeLog見てもよくわからないな。。。と途方に暮れて検索検索。

wrap_layout

の、ところ気になるIssueを発見。

見事これでした。テンプレートエンジンにhaml/slim を使っていて、wrap_layoutでレイアウトを上書きしているとき、

- wrap_layout :layout do
  ...

= wrap_layout :layout do
  ...

にしないとダメな模様。これで手元でも正常にbodyが出力されるようになりました。

で、よくよくChangeLog見直すと

Update Padrino to 0.12.1. Introduces BREAKING CHANGE for Haml. Helpers which take blocks used to require - instead of = to work correctly. Now, all helpers which output content should use =.

って、書いてるのが該当する話の模様。(気づかねぇ。。。)

TravisCIの結果を光で通知するtravis-blink1を作りました

  • 2014年9月 3日 01:12
  • ruby

これは何?

blink(1)という、USB接続で発光するガジェットをhmskさんからいただいたので、遊びでつくってみたgemです。

指定したgithubのプロジェクトについて、TravisCIの結果を発光して通知してくれるものです。CIが実行中のときは黄色で点滅、テストに失敗したときは赤色で点滅、テストが通ったときは緑で発光します。 動作の様子はこんなかんじ。

テスト失敗時

テスト成功時

blink(1)がおもしろいのは、プログラマブルに発光できること。色や点滅時間など、ことこまかく調整できるので、任意のイベントの通知として発光させることが可能になります。

いろんな言語からblink(1)のAPIを叩くクライアントがあるのですが、rubyだとrb-blink1がひとまずよさそう。travis-blink1でも内部で利用しています。

とりあえずチカチカさせるには、これだけでOK。

require 'blink1'

Blink1.open do |blink1|
  blink1.blink(255, 255, 0, 5)
end

使い方

お約束の

gem install travis-blink1

でインストール後、手元のディレクトリがプロジェクトをforkした場所でgit remoteの設定がされている場合は

travis-blink1

だけ実行すれば、git remoteの結果から、TravisCIの状態を監視。 また、任意のディレクトリから実行するときは

travis-blink1 katsuma/itunes-client

なんかのように「ユーザ名/プロジェクト名」を指定すればOKです。

雑感

blink(1)は、できることがシンプルなので、すぐに試せるのはいいですね。いっぱい天井からぶら下げるなどして、hueみたいに照明代わりにしみても楽しそうです。

TokyuRuby会議07でitunes-clientの発表をしてきました

  • 2014年3月29日 15:17

TokyuRubyKaigi07itunes-clientの発表をしました。 Rubyを使わずにiTunesを操作していいのは小学生までですよね!!1

あと、スライドの中でいろいろ動画をいれていたのですが、それもあわせて公開しておきます。

Itunes::Track.find_by

Itunes::Track#play/pause/stop

Itunes::Player.add / Itunes::Track#update

Middleman + SinatraでALOHA FISHMANSのサイトをリニューアルしました

  • 2014年3月 9日 03:31
  • ruby

去年の秋頃、友人経由で、Fishmansファンのためのイベント「お彼岸ナイト」を開催しているALOHA FISHMANSの人たちを紹介してもらったのですが、何か僕で手伝えることがあれば、、というわけでサイトのフルリニューアルを手伝わせていただきました。

今回利用した技術としては

フロントエンド

バックエンド

インフラ

コード管理

  • github(のプライベートレポジトリ)

な、感じ。

今回、このリニューアルでいろいろハマったところや工夫できたことがあったので、もろもろまとめたいと思います。

CSSフレームワーク

以前のサイトは、PCでの閲覧のみ意識していたような作りになっていたので、スマホ(というかタッチデバイス)への対応が一番の要件でした。

さて、じゃぁレスポンシブ対応のCSSフレームワークを選ぶか、、と思って選定に入りました。検討したのはこんな感じ。

CSSフレームワークは似たものが乱立していてさてどうするか。。と思ったのですが、こんな基準で選びました。

  1. サイズが小さい
  2. スマートフォンに最適化されたUIが標準で用意
  3. フレームワークに依存したマークアップを強要されない

Bootstrapは1.が引っかかってやめました。あと、デフォルトの見た目が「いかにも」な感じになるのでもうちょっとシンプルで単純なスタイルが欲しかったこともあって利用はヤメ。

Foundationは全体的にバランスがいいのですが、メニューまわりのマークアップがちょっと複雑なので保留に。最終的には利用することにしたのですが、正直いまだにメニューまわりにクセがある印象なので、そんなに強くオススメできません。。

Skeltonはシンプルでいいんだけども2の観点で見ると、自分でスタイルいじるのは最低限に抑えたかったので、全然スマホサイトっぽい感じがしなかったのでヤメ。

HTML KickStartはすごく単純なマークアップで一番最初は利用していたのですが、メニューまわりのデフォルトの見た目がまったくスマホサイトっぽくない感じだったので途中でヤメました。

Pureはフォント周りのスタイルは一番好きなのですが、マークアップにpure-*とフレームワーク依存のclassやdata属性を強要されるのがどうにもシックリこなかったのでヤメ。

ベストなものは無い

これだけ乱立してるCSSフレームワークだから、さすがにグッとくるものがあるだろう。。と思い込んでたのですが、正直いまだにグッとくるものは見つかってません。。 Foundationを消去法的に利用しましたが、デフォルトのリストUIの見た目はあまりグっとこなかったので、結局いろいろベースとなるスタイルは自分で用意しました。

たとえばクックパッドで利用しているSaraフレームワークは、このへん見た目的にもマークアップ的にも、相当使いやすくなっていると実感できたので、SaraがOSSで公開されてれば。。(チラッチラッ)と何度も思った次第です。

そう考えると、これだけCSSフレームワークが乱立するのもやはり一周回って理解できるわけで、みんな痒いところに手を届かせるために「俺の考えた最強CSSフレームワーク」を作ろうとするんでしょうね。。

middleman

フロントエンドの基盤はmiddlemanにするのは最初から決めていました。

オリジナルのサイトはベースはPHPで実装されていて、チケット管理ページなど動的ページが一部あるものの、ユーザに見える部分はほぼ全てのページが静的な情報なため、PHPのメリットはレイアウトをDRYに書ける、というところに留まっていそうでした。

middlemanは最終的に静的なページを出力しつつ、

  • haml/slimなどのテンプレート言語
  • assetパイプライン
  • LiveReload

などのツールがすぐ使えるので、最近のRailsで開発するような感覚で開発を進めることができるのが大きなメリットです。

実際今回触った感想としてmiddlemanは大正解でした。今後も数ページだけのサイトだったらmiddlemanを利用しない理由は無いんじゃないかな、と言えそうです。1点を除いては。。

Sinatra

1点を除いては、と言ったのは動的なページが出てきたときの対応です。

middlemanはそもそも静的サイトジェネレータなので、動的なページなんて入れようとするほうが悪いのですが、いかんせん必要なものは必要です。今回もイベントのチケット予約に1ページだけ必要でした。

ロジックはシンプルなのでSinatraで完結できれば。。と安易に思っていたのですが、いかんせん事例がほとんどありません。milddeman公式サイトにももちろん載っていません。

で、おそらく唯一であろうヒントはmiddleman作者のThomasさんのコードの断片。要するにconfig.rbに特定のパスだけSinatra::Baseにリクエストを処理させる方法です。

「開発時はいいけどリリース時はproduction環境にどうやって載せるんや。。。」と悩んでたのですがnginxで特定のパスへのリクエストだけUnicorn(で動かしたSinatra)へリクエストを流すようにすればなんとかなりそうかも?と思ってトライ。このへんのインフラ全然触ったことなかったのでハマりましたが、なんとかかんとかできました。

ディレクトリ構造

開発時はこんな感じにしてます。

  • build (ビルドしてできる静的HTMLファイル)
  • app (Sinatraなんかの動的な処理をまとめ)
    • config.ru (production用、開発時は使わない)
  • source (静的ページの開発)
  • config.rb (Sinatraの設定)

middleman buildするとminifyやgzip化されたHTMLファイルがbuildディレクトリにできるので、リリース時はこの中身をまるっとrsync。nginxも基本このファイルを直接返します。

appはSinatraの実態。たとえばこんなかんじ。

app/ticket_reservation.rb

require 'sinatra'
require 'active_record'
require 'mysql2'
require_relative 'models/ticket'

config = YAML.load_file('./database.yml')
ActiveRecord::Base.establish_connection(config["db"]["development"])

class TicketReservation < Sinatra::Base
  post '/reserve' do
    ...
    redirect '/events/reserved'
  end
end

こいつをconfig.rbから呼び出しておく。

config.rb

require_relative 'app/ticket_reservation'

...

map '/tickets' do
  run TicketReservation
end

これで、middleman serverで手元でサーバを起動すると/ticketsのリクエストだけSinatraでハンドリングすることができます。

app/config.ru

開発時は利用しないのですが、productionではUnicornで利用するために必要です。プロセスの再起動はいい感じのタイミングにお願いしたいので、unicorn-worker-killerに任せてます。(設定はデフォルトのまま...)

require_relative 'ticket_reservation'

# Unicorn self-process killer
require 'unicorn/worker_killer'

# Max requests per worker
use Unicorn::WorkerKiller::MaxRequests, 3072, 4096

# Max memory size (RSS) per worker
use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2))

# Run main app
run TicketReservation

production環境

こんなかんじのディレクトリツリーにしてます。

  • alohafishmans.com
    • app
    • public

リリース時は

  • build ⇛ public
  • app ⇛ app

へrsyncして、appのコードを変更したときのみUnicornを再起動させています。

nginx

config.rbでの設定と同じような感じで設定します。/ticketsへのリクエストだけをUnicornを利用するようにします。こんなかんじ。

alohafishmans.com.conf

upstream unicorn_alohafishmans {
  server unix:/path/to/alohafishmans.com/app/tmp/sockets/unicorn.sock
  fail_timeout=0;
}

server {
  server_name alohafishmans.com;

  location ^~ /tickets/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn_alohafishmans/;
  }

  location / {
    root /path/to/alohafishmans.com/public;
  }
}

その他の問題

基本的な構成は以上なのですが、その他にも細かいとこにもいろいろハマりました。。一応メモがてら残しておきます。

濁点問題

今回ブログのコンテンツのURLを、SEOを意識してタイトルをパス名に入れたURLにしました。例えばこんな感じ。

これも実際は「3/22「お彼岸ナイトvol.8 2014春」まであと1ヶ月!!」ディレクトリと、その直下にindex.htmlを作っているだけですが、buildしてrsyncするとアクセスできず404が。 どうもディレクトリ名がバグっておかしなものになっている模様。。

日本語が悪い??と思いきや、アクセスできるページもある。1文字づつ削って、問題の切り分けをするとどうやら「まであと1ヶ月」の「で」が悪い模様(!)

なんだこりゃ。。。。と思いきやUTF8-Macのエンコーディングに起因する話な模様。解決策としてはrsyncを3系にバージョンアップして(brew install rsyncでOK)iconvオプションをつければ良い。

rsync --iconv=UTF-8-MAC,UTF-8 -avz build/ foo@bar:/path/to/alohafishmans.com/public

FacebookのLikeをすると「You like 404 Not Found」問題

Likeボタンはそれなりに何度も設置しているつもりなのですが、今回はogpの設定をして、DeveloperページのDebuggerで見て情報が正確に設定されているにもかかわらず。Likeするとダイアログに「You like 404 Not Found」が出る、という謎現象に悩まされました。

類似の話としてSEM pdxの記事で全く同じものがあったのですが、向こうでは「IPv6を無効にしたらどうにかなったよ」と言ってる一方、僕の方では無効にしても全く変化なし。

で、やっとこさ気づいたのですが元々のボタンを

.fb-like{ data: { layout: 'button_count', width: '130', href: CGI.escape(page_url) }}

にしていたのですがdata-hrefの指定がどうも間違っていいた模様。正解は

.fb-like{ data: { layout: 'button_count', width: '130', href: page_url }}

コレ。

日本語がパスに含まれてるのを気にしてURLエンコードしていたのですが、まさかそれが足を引っ張っていたとは。。。 (ドキュメント見てもURLエンコードについて特に何も書いて無さそうなのですが。。)

まとめ

久々にゼロの状態からインフラ、DB、アプリケーションの実装まで全部実装したのですが、いい勉強になりました。特にインフラ面は現職ではセットアップ周りを自分ですることはここ数年ほとんどなかったので、仕組みを理解するいい機会になったと実感しています。

また、middlemanは相当使いやすく便利な一方、少しでも凝ったことをしようとするとハマるポイントも割りとあるので、改めて別途エントリをまとめるなり、プラグイン系へ修正PR投げるなりして貢献したいと思います。

最後に、Fishmans好きな人はお彼岸ナイトもぜひぜひ遊びにきてください :)

JISAの要求工学技術部会でクックパッドのものづくりについて発表をしてきました

  • 2013年12月19日 22:45

JISA(情報サービス産業協会)の要求工学技術部会で、クックパッドのものづくりについて発表をしてきました。 内容としては、ここ1年ほどのサービス開発のフローをざっとまとめたものになっています。

ひょんなこと(WEB+DB PRESSの記事をご覧になられていた模様)から南山大学の青山先生にお声がけいただいて参加することになりましたが、普段は触れることがない世界に入ることができてとても新鮮でした。

「要求工学」という存在もまったく知らなかった初心者がその筋のトップの方々の前に現れてWebサービスについてしゃべる、、、という割と無茶な感じではあったのですが、質疑応答でも鋭いコメントをもいただきつつ、ディスカッションもできて、有意義な時間を過ごさせていただきました。こういう場があると、自分たちの考え方を振り返るいい機会になりますね。

Index of all entries

Home

Search
Feeds

Return to page top