Class: Web::Narflates

Inherits:
Object show all
Defined in:
lib/web/template.rb

Overview

Purpose

Templates allow you to seperate the design, which is a constant, from the things that change. Testing is much easier if you can focus on just the things that change.

Note: Narf intends to support multiple templating libraries. After supporting multiple backends, I will work on the supporting multiple templating libraries. I will probably start with rdoc and amrita.

Back to business! Here’s an example Narflate:

<html>
  <body>
    {$myvar}
    <narf:foreach from=alist item=i>
      {$i.x}, {$i.x}<br>
    </narf:foreach>
  </body>
</html>

You use the Web::print_template( template, value_hash ) to print the template merged with values:

--- script.rb:
Web::process do
  Web.print_template "mytemplate.html",
  		   "field1" => "val1",
  		   "field2" => "val2",
	  	   "field3" => "val3",
		   "field4" => "3",
		   "values" => [{ "name" => "one", "value" => "1"},
		                { "name" => "two", "value" => "2"},
				{ "name' => "three", "value" => "3"}]
end

--- mytemplate.html:
<narf:input type="text" name="field1">
<narf:input type="hidden" name="field2">
<narf:textarea name="field3">
<narf:select name="field4" values="values">

This will produce the output:

<input type="text" name="field1" value="val1">
<input type="hidden" name="field2" value="val2">
<textarea name="field3">
val3
</textarea>
<select name="field3">
	<option value="1">one</option>
	<option value="2">two</option>
	<option value="3" selected>three</option>
</select>

Defined Under Namespace

Classes: CheckBox, Data, Foreach, Form, Hidden, If, Include, Link, Password, Select, Text, TextArea, Unless, Var

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template, query = {}) ⇒ Narflates

:nodoc:



210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/web/template.rb', line 210

def initialize template, query = {} 	# :nodoc:
  @templates = [template]
  @template = if (File.exists? Narflates.template_file(template))
                File.open(Narflates.template_file(template), "r") do |file|
                  file.read || "" # this is because of a fixed bug in ruby.
                end                # eventually the || "" should disappear
              else
                template
              end
  @parser = StrScanParser.new(StringScanner.new( @template ))
  @query = query
end

Instance Attribute Details

#templatesObject (readonly)

:nodoc



188
189
190
# File 'lib/web/template.rb', line 188

def templates
  @templates
end

Class Method Details

.template_file(template) ⇒ Object

:nodoc:



199
200
201
202
203
204
205
206
207
208
# File 'lib/web/template.rb', line 199

def Narflates.template_file( template ) #:nodoc:
  template_file = template
  Web.template_include_path.reverse.each{ |dir|
	full_template_path = File.join( dir, template )
	if (File.exists? full_template_path)
	  template_file = full_template_path
	end
  }
  template_file
end

.template_include_pathObject

This is the default template_include_path



191
192
193
194
195
196
197
# File 'lib/web/template.rb', line 191

def Narflates.template_include_path #:nodoc:
  [Dir.pwd,
   File.join(Web.document_root.to_s,
             Web.script_path.to_s,
             "templates" ).gsub( /\/\//, "/" ),
  ]
end

Instance Method Details

#match_identifiers(tree = []) ⇒ Object

:nodoc:



483
484
485
486
487
# File 'lib/web/template.rb', line 483

def match_identifiers tree=[]  	# :nodoc:
  @parser.match_identifier do |identifier|
	tree.push Var.new(identifier)
  end
end

#match_tags(tree = []) ⇒ Object

:nodoc:



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
# File 'lib/web/template.rb', line 490

def match_tags tree=[] 	# :nodoc:
  @parser.match_tag() do |tag|
	case tag.name
	when "input"
	  case tag.attributes["type"]
	  when "text"
 tree.push Text.new(tag.attributes["name"])			
	  when "hidden"
 tree.push Hidden.new(tag.attributes["name"])
	  when "password"
 tree.push Password.new(tag.attributes["name"])
	  when "checkbox"
 tree.push CheckBox.new(tag.attributes["name"])
	  end
	when "textarea"
	  tree.push TextArea.new(tag.attributes["name"],tag.attributes["rows"],tag.attributes["cols"],tag.attributes["virtual"],tag.attributes["style"],tag.attributes["id"])
	when "foreach"
	  parse_recurse("foreach") { |contents| 
 tree.push Foreach.new(tag.attributes["from"],tag.attributes["item"],contents)
	  }
	when "form"
	  parse_recurse("form") { |contents| 
 tree.push Form.new(tag.attributes["name"],tag.attributes["method"],contents,@query)
	  }
	when "link"
	  parse_recurse("link") { |contents| 
 tree.push Link.new(tag.attributes["value"],contents)
	  }
	when "select"
	  tree.push Select.new(tag.attributes["name"], tag.attributes["values"])
	when "if"
	  parse_recurse("if") do |contents|
 tree.push If.new(tag.attributes["condition"],contents)		
	  end
	when "unless"
	  parse_recurse("unless")do |contents|
 tree.push Unless.new(tag.attributes["condition"],contents)
	  end
	when "include"
	  tree.push Include.new(tag.attributes["file"],tag.attributes["vars"],@templates)
	else
	  #TODO: raise unknown token exception
	end
  end
end

#parse(io, vars) ⇒ Object

:nodoc:



223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/web/template.rb', line 223

def parse io, vars 	# :nodoc:
  vars = if vars.kind_of? Scope
    vars
  else
    Scope.new(vars)
  end
  
  parse_recurse.each do |item|
	item.print(vars,io)
  end
 
end

#parse_recurse(closeTag = nil, tree = [], &block) ⇒ Object

:nodoc:



536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/web/template.rb', line 536

def parse_recurse closeTag = nil, tree = [], &block  	# :nodoc:
  catch(:done) do
	while @parser.rest? do
	  @parser.match( NOT_TOKEN ) do |m|
 tree.push Data.new(m[1])
	  end 
	  
	  @parser.match_close_tag do |tag|
 if closeTag # TODO: make sure the correct close tag is given
   yield(tree) if block
   throw :done
 end
	  end ||
 match_identifiers(tree) || 
 match_tags(tree) ||
 (tree.push(Data.new(@parser.rest)) &&
  throw(:done))
	end     
  end
  tree
end