ruby-etude:40lines-template-engine
目次
40行の Ruby製 簡易テンプレートエンジン
テンプレートエンジンのソースコード
require "cgi" class Template # テンプレートから作成したViewを取得する def self.get(tmpl_path, http_headers = "text/html") view_path = tmpl_path + ".view.rb" # Viewのファイルパス view_name = "View_" + tmpl_path.gsub(/[-.]/, "_") # Viewのクラス名 # Viewクラスがまだ無いか、テンプレートより古い場合はViewクラスを作成する if !FileTest.exist?(view_path) || File::stat(tmpl_path).mtime > File::stat(view_path).mtime self.create_view(tmpl_path, view_path, view_name) end load view_path #Viewクラスを読み込む print CGI.new.header(http_headers) # HTTPヘッダ出力 return eval(view_name + ".new") # Viewのインスタンスを返す end # Viewクラスを定義するファイルを生成する def self.create_view(tmpl_path, view_path, view_name) vars = [] # テンプレート内で使っているインスタンス変数をここに溜める view = open(view_path, "w") view.puts "class #{view_name} \n" view.puts " def show \n" tmpl = open(tmpl_path) tmpl.each do |line| vars.concat(line.scan(/@([_0-9a-z]+)/i)) # 使用しているインスタンス変数を洗い出す if line =~ /!\{.+\}/ # !{ }内はRubyのコードとして実行させる view.puts ' ' + line.gsub(/!\{(.+)\}/, '\1') else # それ以外は加工してprintさせる line.gsub!(/"/, '\"') # ダブルクォートのエスケープ line.gsub!(/%\{([^\}]+)\}/, '#{CGI.escapeHTML(\1.to_s)}') # HTMLエスケープ view.puts ' print "' + line.rstrip + '\n"' end end tmpl.close view.puts " end \n" view.puts " attr_accessor :" + vars.uniq.join(", :") if vars.size > 0 # アクセサ view.puts "end \n" view.close end end
dokuwikiのハイライトが途中でずれちゃってる…
使い方の例
実例を見るのが分かりやすいかと。
テンプレートの例(tmpl.html)
<html> <head> <title>%{@title}</title> </head> <body> <h1>%{@title}</h1> <span style="color:green;">%{@message}</span> %{@message2} <hr /> ループ <ul> !{@arr.each do |var|} <li>#{var}</li> !{end} </ul> <hr /> 条件 !{if @flg } TRUE !{else} FALSE !{end} </body> </html>
#{ }でそのまま出力
%{ }でHTMLエスケープして出力
!{ }内はRubyのコードとして実行する
データはインスタンス変数としてセットされるので@で使える
テンプレートを使う側の例
require "template" v = Template.get("tmpl.html") v.title = "<タイトル>" v.message = "こんにちは!" v.message2 = "こんばんは!" v.arr = ['a', 'b', 'c'] v.flg = true v.show
Template.get()でgetして、プロパティ感覚で値をセットして、show()する。
実行結果
テンプレートから作られたRubyのコード
class View_tmpl_html def show print "<html>\n" print "<head>\n" print "<title>#{CGI.escapeHTML(@title.to_s)}</title>\n" print "</head>\n" print "<body>\n" print "<h1>#{CGI.escapeHTML(@title.to_s)}</h1>\n" print "<span style=\"color:green;\">#{CGI.escapeHTML(@message.to_s)}</span> #{CGI.escapeHTML(@message2.to_s)}\n" print "<hr />\n" print "ループ\n" print "<ul>\n" @arr.each do |var| print " <li>#{var}</li>\n" end print "</ul>\n" print "<hr />\n" print "条件\n" if @flg print " TRUE\n" else print " FALSE\n" end print "</body>\n" print "</html>\n" print "\n" end attr_writer :title, :message, :message2, :arr, :flg end
実行結果のHTML
ruby-etude/40lines-template-engine.txt · 最終更新: 2008/08/01 22:55 by dgbadmin