2002.09.16 - HTML::Template.new()に文字列,ハッシュ以外を与えたときは,エラーとするようにした。 - HTML::Template#html=()を削除。set_html()がある。 - 置換タグが見つからないときは,エラーとするようにした。 2002.11.11 (-q2) - 閉じられていないノードは,エラーとするようにした。 - 子ノードの置換タグが見つからないときも,エラーとするようにした。 - HTML::Template#expand(), HTML::TemplateNode#expand()は,selfを返すようにした。 2002.11.17 (-q3) - set_html()は,selfを返すようにした。 2003.05.10 (-q4) - param()という名前は不明なので、aliasの一つだったexpand()に変更した。 - テストスクリプトを追加した。 2004.07.11 (-q5) - 置換タグが見つからないときエラーにする(q1での修正)を元に戻した。 diff -Naur html-template-0.16.orig/lib/html/template.rb html-template-0.16-cur/lib/html/template.rb --- html-template-0.16.orig/lib/html/template.rb 2002-01-05 03:32:05.000000000 +0900 +++ html-template-0.16-cur/lib/html/template.rb 2004-07-11 13:49:28.851462280 +0900 @@ -6,6 +6,9 @@ class Template def initialize(param = nil) + raise TypeError if !param.is_a?(Hash) && !param.is_a?(String) && + !param.is_a?(NilClass) + @path = ['.',''] @html file = nil @@ -43,14 +46,15 @@ def set_html(html) @html = html parse + return self end - attr_accessor :html + attr_reader :html attr_accessor :path ## # set params - def param(key = {},*val) + def expand(key = {}, *val) hash = if key.is_a?(String) {key => val} else @@ -59,14 +63,15 @@ hash.each do |k,v| if v.is_a?(Array) v.each do |h| - node(k).param(h) + node(k).expand(h) end elsif v.is_a?(Hash) - node(k).param(v) + node(k).expand(v) else - @html.gsub!(//i,escape_re(v.to_s)) + @html.gsub!(//i, escape_re(v.to_s)) end end + return self end ## @@ -75,7 +80,7 @@ if @node[name] != nil return @node[name] else - raise ArgumentError,"node #{name} not found\n" + raise ArgumentError,"node '#{name}' not found" end end @@ -91,7 +96,6 @@ end ## aliases - alias expand param alias loop node alias cond node alias to_s output @@ -137,6 +141,9 @@ @node[name] = HTML::TemplateNode.new(self,name,body) "" end + if @html =~ /(.*?)/ + raise ArgumentError, "block without end-tag: '#{$1}'" + end end end @@ -152,34 +159,15 @@ attr_accessor :body - def param(key = {},*val) - hash = if key.is_a?(String) - {key => val} - else - key - end - hash.each do |k,v| - if v.is_a?(Array) - v.each do |h| - node(k).param(h) - end - elsif v.is_a?(Hash) - node(k).param(v) - else - @html.gsub!(//i,escape_re(v.to_s)) - end - end + def expand(key = {}, *val) + super html = @html.dup @parent.html.gsub!(/()/) do "#{html}#{$1}" end @html = @original.dup + return self end - - alias expand param - alias add param - alias loop node - alias cond node end end diff -Naur html-template-0.16.orig/test/test.rb html-template-0.16-cur/test/test.rb --- html-template-0.16.orig/test/test.rb 1970-01-01 09:00:00.000000000 +0900 +++ html-template-0.16-cur/test/test.rb 2004-07-11 13:48:33.259913480 +0900 @@ -0,0 +1,96 @@ + +require "html/template" +require "runit/testcase" +require "runit/cui/testrunner" + +class Test1 < RUNIT::TestCase + # 変数名が見つからないとエラー + def test10 + tmpl = HTML::Template.new + tmpl.set_html "" + assert_exception(ArgumentError) { + tmpl.expand({"hogevar" => "foo"}) + } + end + + # ノードの中で変数名が見つからないとエラー + def test11 + tmpl = HTML::Template.new + tmpl.set_html "" + assert_exception(ArgumentError) { + tmpl.node("t").expand({"hogevar" => "foo"}) + } + assert_exception(ArgumentError) { + tmpl.expand({"t" => {"hogevar" => "foo"}}) + } + end + + # 閉じていないノードはエラー + def test2 + tmpl = HTML::Template.new + assert_exception(ArgumentError) { + tmpl.set_html "" + } + end + + # ノード名が見つからないとエラー + def test3 + tmpl = HTML::Template.new + tmpl.set_html "" + assert_exception(ArgumentError) { + tmpl.node("hogenode") + } + assert_exception(ArgumentError) { + tmpl.expand({"hogenode" => {}}) + } + end + + # 変数の変換 + def test4 + tmpl = HTML::Template.new + tmpl.set_html("") + assert_equal("bar", tmpl.expand({"foo" => "bar"}).output) + + # 数値は、自動的に文字列に変換する + assert_equal("20", tmpl.expand({"foo" => 20}).output) + end + + def sub_t11 + tmpl = HTML::Template.new + tmpl.set_html(< +EOF + return tmpl + end + + # ノード: node()を通すと,そのノードは展開しない + def test5 + tmpl = sub_t11 + o = tmpl.node("t").expand({"foo" => "bar"}).output + assert_equal("", o) + o = tmpl.expand({}).output + assert_equal("bar\n", o) + end + + # expand()の中にノードを書くと,直接そのノードを展開する + def test6 + tmpl = sub_t11 + o = tmpl.expand({"t" => {"foo" => "bar"}}).output + assert_equal("bar\n", o) + end + + # '<'や'>'はエスケープされない。 + def test7 + tmpl = HTML::Template.new.set_html("").expand({"foo" => ""}) + assert_equal("", tmpl.output) + end + + # 値として汚染された文字列を渡してもエラーにはならない。 + # これをいちいちエラーにしていたら、かえってミスを誘発しそう。 + def test8 + tmpl = HTML::Template.new.set_html("") + assert_equal("bar", tmpl.expand({"foo" => "bar".taint}).output) + end +end + +RUNIT::CUI::TestRunner.run(Test1.suite)