くろねこ日記

ソフトウェアに関する技術メモが多いです.

フレームワーク素人がRubyのSinatra触ってみた

こんにちは

最近,Python以外にもちょっとしたきっかけでRubySinatraに手を出しました.

僕自身もともとウェブフレームワークに触れることを今までしなかったことから,あの独特の開発のしかたに妙な苦手意識を持ってました.

ここでは似たような境遇にある?かたへ少し参考になればと思い残しておきます.

まずはハローワールド

main.rb

require 'sinatra'

get '/' do
   "HelloWorld"
end

まずはrequireでsinatraを呼んできます. そのあとにget '/' doというsinatra流の文があります. これはgetメソッド(普通にURLでアクセスした場合のこと)と'/'というlocalhost直下を意味する文からなりたってます. この場合意味は「普通にURLでlocalhostを叩いた場合に実行」と読むことができます で,"HelloWorld"と書いてあるのが文字列となってまして,これが表示されます.

ちゃんとしたhtmlページに表示させたい

今のような書きかたでは"hello world"を出すだけであまりできそうなことがありません. 通常はhtml(例えばindex)を意味するファイルを生成してひっぱってきて表示するのが基本です.

Sinatraの場合,erbという形式でhtmlを表現することになります(他にもHAMLというものがありますが,ここではerbにしておきます). 以下にこれらの基本構成を表示しておきます.

.
├── main.rb
└── views
    ├── index.erb
    └── layout.erb

main.rbに先程のような呼び出されたアクションを記述して views以下にその結果を垂れ流すイメージですね.

views以下を見るとindex.erbとlayout.erbの二つがあると思います. これはテンプレートエンジンの特徴なのですが,基本的な共通するコードをlayoutに書いておいて,index.erbにはindexが呼び出されたときの処理を書くというやりかたです. 例えばabout.erbのようにaboutページを生成された場合ヘッダーの部分やtitleの部分,cssの部分などはindexと同じようにしておきたいというケースがあるかと思いますが,そのような場合に有効です.

以下にそれっぽく動くmain.rb,index.erb,layout.erbを記述しておきます.

main.rb

require 'sinatra'

get '/' do
    @title = "ハローワールド"
    erb :index
end

layout.erb

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title><%= @title %></title>
</head>
<body>
    <%= yield %>
</body>
</html>

index.erb

<h2>テスト</h2>

このように書くだけです. まずmain.rbの@title = "ハローワールド"はindexにtitleという"ハローワールド"が代入された変数をindex.erbに渡すための書きかたです.@変数名としておくことこのような機能が使えます. erb :indexというのはindex.erbを呼びだすときの文です. たとえばhamlで書きたいときにはhaml :indexという形式になります.

次に,layout.erbですが,これはhtmlの基本的な骨組だけを書いておく部分です. <!DOCTYPE html>は必ずどのページにも登場しますね?そういった決まりきった共通項を書いておく部分です.このようにlayout.erbに書いておくと勝手にsinatraが解釈してくれます. それからlayout.erbの中には<%= @title %><%= yield %>とありますね. <%= @title %>の場合はrbファイルで書かれた@titleが渡された内容を出力していることになります. <%= yield %>のほうは,indexページが呼ばれたときには「index.erbの中身を展開しなさい」という意味になります <%= なんとか %>という書きかたに違和感があると思いますが,こちらはerb流の書きかたになっております.

つぎにindex.erbはといえば<h2>テスト</h2>ですね つまりルートにアクセスした場合ページにはテストとh2のサイズで表示されます.

erbからテキストボックスの内容をrubyに送信

今はただ単純にウェブページに記述しておくだけでした. ここではユーザの入力に応じた処理としてテキストボックスの内容をボタンが押されたらrbファイルにpost形式で送る方法を書いておきます.例としてタイトルを逐一変更するようなものを作ってみます.

先程と同じディレクトリ構成で記述していきますと,

main.rb

require 'sinatra'

get '/' do
    @title = "ハローワールド"
    erb :index
end
post '/sendtext' do
    @title = params[:message]
    erb :index
end

index.erb

<h2>テスト</h2>
<form method="post" action="/sendtext">
    <input type="text" name="message"><input type="submit" value="Send">
</form>

layout.erb 先程と同様なので省略

main.rbではpost '/sendtext' doというgetからpostになっていることがわかると思います. これはpostで送られてきた処理に対して実行されるものです./sendtextとありますからlocalhost以下に/sendtextというurlが付加されてきた場合を指します.

つまりこの場合「sendtextというurlが末尾についてきてかつpostの場合はここを実行」ということになります.

中身はと言えば,@title = params[:message]とありますね.index.erbで定義したinputのname名]で受けとれます.この場合は@titleに代入しているので

「erbで定義したinput textのname名の値をタイトルにする」ということになります.

erb :indexでこの処理が終ったら次に飛ばす場所を指定してます.今回は元の画面に飛んでもらえば良いのでこのような書き方になってます. redirectでルートを指定できますが,そうすると変数が消えてしまうので,erb :indexという書き方にしました.

以上でしょうか.一先ず文字を出力したり入力したりといったことを簡単にまとめてみました. helperというのを使えばメソッドを定義して実行できるという便利なメソッドもありますが,疲れたのでここまでとします.