Class: TemplatePage
- Inherits:
-
Object
- Object
- TemplatePage
- Defined in:
- lib/rdoc/template.rb
Overview
Cheap-n-cheerful HTML page template system. You create a template containing:
-
variable names between percent signs (
%fred%
) -
blocks of repeating stuff:
START:key ... stuff END:key
You feed the code a hash. For simple variables, the values are resolved directly from the hash. For blocks, the hash entry corresponding to key
will be an array of hashes. The block will be generated once for each entry. Blocks can be nested arbitrarily deeply.
The template may also contain
IF:key
... stuff
ENDIF:key
stuff will only be included in the output if the corresponding key is set in the value hash.
Usage: Given a set of templates T1, T2,
etc
values = { "name" => "Dave", state => "TX" }
t = TemplatePage.new(T1, T2, T3)
File.open(name, "w") {|f| t.write_html_on(f, values)}
or
res = ''
t.write_html_on(res, values)
Defined Under Namespace
Classes: Context, LineReader
Instance Method Summary collapse
-
#expand_line(line) ⇒ Object
Given an individual line, we look for %xxx% constructs and HREF:ref:name: constructs, substituting for each.
-
#initialize(*templates) ⇒ TemplatePage
constructor
templates
is an array of strings containing the templates. -
#substitute_into(lines, values) ⇒ Object
Substitute a set of key/value pairs into the given template.
-
#write_html_on(op, value_hash) ⇒ Object
Render the templates into HTML, storing the result on
op
using the method<<
.
Constructor Details
#initialize(*templates) ⇒ TemplatePage
templates
is an array of strings containing the templates. We start at the first, and substitute in subsequent ones where the string !INCLUDE!
occurs. For example, we could have the overall page template containing
<html><body>
<h1>Master</h1>
!INCLUDE!
</bost></html>
and substitute subpages in to it by passing [master, sub_page]. This gives us a cheap way of framing pages
132 133 134 135 136 137 138 |
# File 'lib/rdoc/template.rb', line 132 def initialize(*templates) result = "!INCLUDE!" templates.each do |content| result.sub!(/!INCLUDE!/, content) end @lines = LineReader.new(result.split($/)) end |
Instance Method Details
#expand_line(line) ⇒ Object
Given an individual line, we look for %xxx% constructs and HREF:ref:name: constructs, substituting for each.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/rdoc/template.rb', line 201 def (line) # Generate a cross reference if a reference is given, # otherwise just fill in the name part line.gsub!(/HREF:(\w+?):(\w+?):/) { ref = @context.lookup($1) name = @context.find_scalar($2) if ref and !ref.kind_of?(Array) "<a href=\"#{ref}\">#{name}</a>" else name end } # Substitute in values for %xxx% constructs. This is made complex # because the replacement string may contain characters that are # meaningful to the regexp (like \1) line = line.gsub(/%([a-zA-Z]\w*)%/) { val = @context.find_scalar($1) val.tr('\\', "\000") } line rescue Exception => e $stderr.puts "Error in template: #{e}" $stderr.puts "Original line: #{line}" exit end |
#substitute_into(lines, values) ⇒ Object
Substitute a set of key/value pairs into the given template. Keys with scalar values have them substituted directly into the page. Those with array values invoke substitute_array
(below), which examples a block of the template once for each row in the array.
This routine also copes with the IF:
key directive, removing chunks of the template if the corresponding key does not appear in the hash, and the START: directive, which loops its contents for each value in an array
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 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/rdoc/template.rb', line 161 def substitute_into(lines, values) @context.push(values) skip_to = nil result = [] while line = lines.read case line when /^IF:(\w+)/ lines.read_up_to(/^ENDIF:#$1/) unless @context.lookup($1) when /^IFNOT:(\w+)/ lines.read_up_to(/^ENDIF:#$1/) if @context.lookup($1) when /^ENDIF:/ ; when /^START:(\w+)/ tag = $1 body = lines.read_up_to(/^END:#{tag}/) inner_values = @context.lookup(tag) raise "unknown tag: #{tag}" unless inner_values raise "not array: #{tag}" unless inner_values.kind_of?(Array) inner_values.each do |vals| result << substitute_into(body.dup, vals) end else result << (line.dup) end end @context.pop result.join("\n") end |
#write_html_on(op, value_hash) ⇒ Object
Render the templates into HTML, storing the result on op
using the method <<
. The value_hash
contains key/value pairs used to drive the substitution (as described above)
144 145 146 147 |
# File 'lib/rdoc/template.rb', line 144 def write_html_on(op, value_hash) @context = Context.new op << substitute_into(@lines, value_hash).tr("\000", '\\') end |