Ruby/ERB/静的HTMLを出力する

Ruby/ERB/静的HTMLを出力する

静的サイト(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するとそれ以前の出力が上書きされて切れてしまったり、余計なものが出たりする。

ruby/erb/gen_static_html.txt · 最終更新: 2020-02-04 12:45 by ore