menu
書いてる野郎
orebike@gmail.com
静的サイト(HTMLファイルそのもの)を出力、生成するツールはRuby製でもいくつかあるが、そんなに大それたものが必要なかったので ERB を使って適当に作った。 簡易的な CMS と言ってもよいか。
Ruby 1.8 ぐらいで作ったが現状でも動くと思われる。Ruby 2.2.3 でも動作確認OK
require 'erb' title = "" layout = "" content = ERB.new(File.read("hoge.html.erb")).result(binding) # この layout は binding を通じて hoge.html.erb 内部で書き換えられている result = ERB.new(File.read(layout)).result(binding) File.open("hoge.html", "w") do |file| file.puts result end
このようにする。title と layout という2個の変数を作っているのは、 hoge.html.erb に記述した Ruby コードから逆にパラメータをメインルーチンに引き込むため(bindingによりスコープが相互に繋がる)
binding はスコープ内の変数情報とかを詰め込んであるオブジェクトで Ruby 側が用意してくれている。 この場合だと title と layout という変数が erb 側のファイルでも読み書き可能になる。
つまり、各ページごとに変化する記述するメイン部分。駆動部で書かれている hoge.erb.html
頭の部分で title と埋め込むレイアウトを宣言的に入れるようにする。
<% layout = "layout.html.erb" title = "hogehoge" %> <h1>This is hogehoge page.</h1>
これは binding を通じて駆動部で引き出すことができる
これがコンテンツが埋め込まれる共通の外枠部分
content 部分は binding 経由で駆動部から取得できる。header と footer にさらに引きこむ。
<% header = ERB.new(File.read("header.html.erb"), nil, nil, '_header_out').result(binding) footer = ERB.new(File.read("footer.html.erb"), nil, nil, '_footer_out').result(binding) %> <html> <head> <title><%= title %></title> </head> <body> <div id="header"> <%= header %> </div> <div id="content"> <!-- この content は binding を通じてアクセス可能になっている --> <%= content %> </div> <div id="footer"> <%= footer %> </div> </body> </html>
多段でERB出力する時はコンストラクタの第4引数で出力をバッファリングする名前をつけてやる。これをしてやらないと、デフォルトの共通のバッファが使われるので、resultするとそれ以前の出力が上書きされて切れてしまったり、余計なものが出たりする。