File: template.rb

package info (click to toggle)
html-template 0.16-2.1
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 128 kB
  • ctags: 111
  • sloc: ruby: 869; makefile: 41
file content (186 lines) | stat: -rw-r--r-- 3,452 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

# $Id: template.rb,v 1.4 2002/01/04 18:32:05 ikechin Exp $
# $Revision: 1.4 $

module HTML

  class Template
    def initialize(param = nil)
      @path = ['.','']
      @html
      file = nil
      if param.is_a?(Hash)
	file = param['filename']
	# allow Array and String
	@path.push(*param['path']) if param['path']
      elsif param.is_a?(String)
	file = param
      end
      if file then
	load(file)
      end
    end

    def load(file)
      @path.each do |path|
	if FileTest.exist?(filepath = File.join(path,file))
	  begin
	    fp = File.open(filepath,"r")
	    @html = fp.read
	    fp.close
	  rescue
	    raise IOError
	  end
	end
      end
      if @html
	parse
	return
      end
      raise IOError,"Template file #{file} not found"
    end

    def set_html(html)
      @html = html
      parse
    end

    attr_accessor :html
    attr_accessor :path

    ##
    # set params
    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!(/<!var:#{k}>/i,escape_re(v.to_s))
	end
      end
    end

    ##
    # return HTML::TemplateNode object
    def node(name)
      if @node[name] != nil
	return @node[name]
      else
	raise ArgumentError,"node #{name} not found\n"
      end
    end

    ##
    # return result
    def output
      @html.gsub!(/<!var:[^>]+>/,"")
      @html.gsub!(/<!node:([^>]+)>/,"")
      ret_val = @html.dup
      # recycle the instance, but dirty way :-p
      set_html(@orig_text)
      return ret_val
    end

    ## aliases
    alias expand param
    alias loop node
    alias cond node
    alias to_s output

    private

    def escape_re(str)
      str.gsub(%r/\\/, "\\\\\\") 
    end
    ##
    # parse HTML documents
    def parse
      @node = {}
      # save original HTML
      @orig_text = @html.dup

      # support HTML comment style
      @html.gsub!(%r~<\!\-\-\s+(begin|end|var|include):([\w\./\-]+)\s+\-\->~,'<!\1:\2>')
      # include allow \w,/,- only
      @html.gsub!(%r~<!include:([\/\w\.\-]+)>~m) do 
	fp = nil
	@path.each do |path|
	  if FileTest.exist?(filepath = File.join(path,$1))
	    begin
	      fp = File.open(filepath,"r")
	    rescue
	      raise IOError
	    end
	    break if fp
	  end
	end
	begin
	  fp.read
	rescue NameError
	  raise IOError, "Include template #{$1} not found"
	end
      end

      # block allow \w,-,. only
      @html.gsub!(/<!begin:([\w\-\.]+)>(.*?)<!end:\1>/m) do
	name = $1
	body = $2
	@node[name] = HTML::TemplateNode.new(self,name,body)
	"<!node:#{name}>"
      end
    end
  end

  class TemplateNode < HTML::Template

    def initialize(parent,name,body)
      @parent = parent
      @name = name
      @html = body
      parse
      @original = @html.dup
    end

    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!(/<!var:#{k}>/i,escape_re(v.to_s))
	end
      end
      html = @html.dup
      @parent.html.gsub!(/(<!node:#{@name}>)/) do 
	"#{html}#{$1}"
      end
      @html = @original.dup
    end

    alias expand param
    alias add param
    alias loop node
    alias cond node
  end
end