tenjin 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.txt +54 -0
  3. data/benchmark/bench.rb +502 -0
  4. data/benchmark/bench_context.rb +17 -0
  5. data/benchmark/bench_context.yaml +141 -0
  6. data/benchmark/templates/_footer.html +4 -0
  7. data/benchmark/templates/_header.html +52 -0
  8. data/benchmark/templates/bench_eruby.rhtml +29 -0
  9. data/benchmark/templates/bench_tenjin.rbhtml +29 -0
  10. data/bin/rbtenjin +449 -0
  11. data/doc-api/classes/Tenjin.html +141 -0
  12. data/doc-api/classes/Tenjin/ArrayBufferTemplate.html +270 -0
  13. data/doc-api/classes/Tenjin/BaseContext.html +312 -0
  14. data/doc-api/classes/Tenjin/Context.html +126 -0
  15. data/doc-api/classes/Tenjin/ContextHelper.html +433 -0
  16. data/doc-api/classes/Tenjin/Engine.html +616 -0
  17. data/doc-api/classes/Tenjin/ErubisTemplate.html +166 -0
  18. data/doc-api/classes/Tenjin/HtmlHelper.html +359 -0
  19. data/doc-api/classes/Tenjin/Preprocessor.html +242 -0
  20. data/doc-api/classes/Tenjin/Template.html +916 -0
  21. data/doc-api/created.rid +1 -0
  22. data/doc-api/files/README_txt.html +185 -0
  23. data/doc-api/files/lib/tenjin_rb.html +136 -0
  24. data/doc-api/fr_class_index.html +36 -0
  25. data/doc-api/fr_file_index.html +28 -0
  26. data/doc-api/fr_method_index.html +89 -0
  27. data/doc-api/index.html +24 -0
  28. data/doc-api/rdoc-style.css +208 -0
  29. data/doc/docstyle.css +188 -0
  30. data/doc/examples.html +312 -0
  31. data/doc/faq.html +909 -0
  32. data/doc/users-guide.html +1691 -0
  33. data/lib/tenjin.rb +959 -0
  34. data/setup.rb +1331 -0
  35. data/tenjin.gemspec +58 -0
  36. data/test/assert-text-equal.rb +45 -0
  37. data/test/data/examples/form/create.rbhtml +4 -0
  38. data/test/data/examples/form/form.rbhtml +14 -0
  39. data/test/data/examples/form/layout.rbhtml +8 -0
  40. data/test/data/examples/form/main.rb +9 -0
  41. data/test/data/examples/form/main.result +21 -0
  42. data/test/data/examples/form/update.rbhtml +4 -0
  43. data/test/data/examples/preprocessing/helper.rb +16 -0
  44. data/test/data/examples/preprocessing/main.rb +11 -0
  45. data/test/data/examples/preprocessing/main.result +17 -0
  46. data/test/data/examples/preprocessing/select.rbhtml +15 -0
  47. data/test/data/examples/preprocessing/select_P.result +18 -0
  48. data/test/data/examples/table/table.rb +9 -0
  49. data/test/data/examples/table/table.rbhtml +16 -0
  50. data/test/data/examples/table/table.result +20 -0
  51. data/test/data/examples/table/table_s.result +18 -0
  52. data/test/data/faq/ex1.rbhtml +5 -0
  53. data/test/data/faq/ex10-baselayout.rbhtml +27 -0
  54. data/test/data/faq/ex10-content.rbhtml +12 -0
  55. data/test/data/faq/ex10-customlayout.rbhtml +11 -0
  56. data/test/data/faq/ex10_inherit.result +25 -0
  57. data/test/data/faq/ex11-bench.rb +28 -0
  58. data/test/data/faq/ex11-content.rbhtml +9 -0
  59. data/test/data/faq/ex11-layout1.rbhtml +5 -0
  60. data/test/data/faq/ex11-layout2.rbhtml +6 -0
  61. data/test/data/faq/ex11.rb +5 -0
  62. data/test/data/faq/ex11.rbhtml +8 -0
  63. data/test/data/faq/ex11.source +11 -0
  64. data/test/data/faq/ex11_arraybuffer.result +15 -0
  65. data/test/data/faq/ex1_chksyntax.result +3 -0
  66. data/test/data/faq/ex2-content.rbhtml +3 -0
  67. data/test/data/faq/ex2-layout.rbhtml +11 -0
  68. data/test/data/faq/ex2_removenl.result +19 -0
  69. data/test/data/faq/ex3.rb +4 -0
  70. data/test/data/faq/ex3.rbhtml +1 -0
  71. data/test/data/faq/ex3_escapefunc1.result +2 -0
  72. data/test/data/faq/ex3_escapefunc2.result +2 -0
  73. data/test/data/faq/ex5.rbhtml +7 -0
  74. data/test/data/faq/ex5_template_args.source +9 -0
  75. data/test/data/faq/ex6-content.rhtml +6 -0
  76. data/test/data/faq/ex6-layout.rhtml +6 -0
  77. data/test/data/faq/ex6.rb +10 -0
  78. data/test/data/faq/ex6_eruby.result +12 -0
  79. data/test/data/faq/ex7-expr-pattern.rb +34 -0
  80. data/test/data/faq/ex7-expr-pattern.rbhtml +3 -0
  81. data/test/data/faq/ex7_expr_pattern.result +4 -0
  82. data/test/data/faq/ex8-m18n.rb +77 -0
  83. data/test/data/faq/ex8-m18n.rbhtml +4 -0
  84. data/test/data/faq/ex8_m18n.result +10 -0
  85. data/test/data/faq/ex9-baselayout.rbhtml +8 -0
  86. data/test/data/faq/ex9-content.rbhtml +6 -0
  87. data/test/data/faq/ex9-mylayout.rbhtml +5 -0
  88. data/test/data/faq/ex9_changelayout.result +11 -0
  89. data/test/data/users_guide/content6.rbhtml +3 -0
  90. data/test/data/users_guide/content7.rbhtml +5 -0
  91. data/test/data/users_guide/content8.rbhtml +2 -0
  92. data/test/data/users_guide/contextdata.rb +7 -0
  93. data/test/data/users_guide/datafile.rb +5 -0
  94. data/test/data/users_guide/datafile.yaml +10 -0
  95. data/test/data/users_guide/ex.rbhtml +6 -0
  96. data/test/data/users_guide/ex.result +7 -0
  97. data/test/data/users_guide/ex.script +5 -0
  98. data/test/data/users_guide/ex_script.result +7 -0
  99. data/test/data/users_guide/ex_source.result +8 -0
  100. data/test/data/users_guide/example1.rbhtml +12 -0
  101. data/test/data/users_guide/example1.result +17 -0
  102. data/test/data/users_guide/example10.rbhtml +4 -0
  103. data/test/data/users_guide/example10_template_args.result +6 -0
  104. data/test/data/users_guide/example11.rbhtml +5 -0
  105. data/test/data/users_guide/example11_template_args_result +2 -0
  106. data/test/data/users_guide/example12.rbhtml +12 -0
  107. data/test/data/users_guide/example12_preprocessed.result +10 -0
  108. data/test/data/users_guide/example12_preprocessed_source.result +10 -0
  109. data/test/data/users_guide/example13.rbhtml +6 -0
  110. data/test/data/users_guide/example13_preprocessed.result +2 -0
  111. data/test/data/users_guide/example13_preprocessed_source.result +2 -0
  112. data/test/data/users_guide/example14.rb +32 -0
  113. data/test/data/users_guide/example14.rbhtml +6 -0
  114. data/test/data/users_guide/example14_tmplclass.result +15 -0
  115. data/test/data/users_guide/example15.rb +10 -0
  116. data/test/data/users_guide/example15_escapefunc.result +14 -0
  117. data/test/data/users_guide/example16.rbhtml +4 -0
  118. data/test/data/users_guide/example16a.rb +10 -0
  119. data/test/data/users_guide/example16a.result +4 -0
  120. data/test/data/users_guide/example16b.rb +13 -0
  121. data/test/data/users_guide/example16b.result +4 -0
  122. data/test/data/users_guide/example16c.rb +12 -0
  123. data/test/data/users_guide/example16c.result +4 -0
  124. data/test/data/users_guide/example1_S.result +14 -0
  125. data/test/data/users_guide/example1_SXNC.result +10 -0
  126. data/test/data/users_guide/example1_source.result +14 -0
  127. data/test/data/users_guide/example2.rbhtml +3 -0
  128. data/test/data/users_guide/example2_sb.result2 +9 -0
  129. data/test/data/users_guide/example3.rbhtml +5 -0
  130. data/test/data/users_guide/example3_syntaxcheck.result +2 -0
  131. data/test/data/users_guide/example4.rbhtml +13 -0
  132. data/test/data/users_guide/example4_datafile_rb.result +13 -0
  133. data/test/data/users_guide/example4_yaml.result +13 -0
  134. data/test/data/users_guide/example5.rbhtml +9 -0
  135. data/test/data/users_guide/example5_datastr_rb.result +9 -0
  136. data/test/data/users_guide/example5_datastr_yaml.result +9 -0
  137. data/test/data/users_guide/example6.rbhtml +19 -0
  138. data/test/data/users_guide/example6_layout.result +29 -0
  139. data/test/data/users_guide/example6_nested.result +28 -0
  140. data/test/data/users_guide/example7_layout2.result +13 -0
  141. data/test/data/users_guide/example8_layout3.result +8 -0
  142. data/test/data/users_guide/example9.rbhtml +18 -0
  143. data/test/data/users_guide/example9_capture.result +26 -0
  144. data/test/data/users_guide/footer.html +5 -0
  145. data/test/data/users_guide/footer.rbhtml +4 -0
  146. data/test/data/users_guide/layout6.rbhtml +17 -0
  147. data/test/data/users_guide/layout7.rbhtml +9 -0
  148. data/test/data/users_guide/layout8_html.rbhtml +5 -0
  149. data/test/data/users_guide/layout8_xhtml.rbhtml +6 -0
  150. data/test/data/users_guide/layout9.rbhtml +25 -0
  151. data/test/data/users_guide/sidemenu.rbhtml +5 -0
  152. data/test/data/users_guide/user_app.cgi +39 -0
  153. data/test/data/users_guide/user_app.result +30 -0
  154. data/test/data/users_guide/user_create.rbhtml +6 -0
  155. data/test/data/users_guide/user_edit.rbhtml +7 -0
  156. data/test/data/users_guide/user_form.rbhtml +10 -0
  157. data/test/data/users_guide/user_layout.rbhtml +16 -0
  158. data/test/test_all.rb +23 -0
  159. data/test/test_engine.rb +526 -0
  160. data/test/test_engine.yaml +2039 -0
  161. data/test/test_examples.rb +81 -0
  162. data/test/test_faq.rb +60 -0
  163. data/test/test_htmlhelper.rb +78 -0
  164. data/test/test_main.rb +564 -0
  165. data/test/test_main.yaml +174 -0
  166. data/test/test_template.rb +113 -0
  167. data/test/test_template.yaml +1244 -0
  168. data/test/test_users_guide.rb +75 -0
  169. data/test/testcase-helper.rb +166 -0
  170. metadata +226 -0
data/tenjin.gemspec ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/ruby
2
+
3
+ ###
4
+ ### $Rev: 61 $
5
+ ### $Release: 0.6.0 $
6
+ ### copyright(c) 2007 kuwata-lab all rights reserved.
7
+ ###
8
+
9
+ require 'rubygems'
10
+
11
+ spec = Gem::Specification.new do |s|
12
+ ## package information
13
+ s.name = "tenjin"
14
+ s.author = "kwatch"
15
+ s.version = ("$Release: 0.6.0 $" =~ /[\.\d]+/) && $&
16
+ s.platform = Gem::Platform::RUBY
17
+ s.homepage = "http://www.kuwata-lab.com/tenjin"
18
+ s.summary = "eRuby-like template engine"
19
+ s.description = <<-'END'
20
+ Tenjin is a template engine which is similar to eRuby.
21
+ Tenjin has the following features.
22
+ * Very fast and lightweight
23
+ * Auto escaping support
24
+ * Auto trimming spaces around embedded statements
25
+ * Context object available and easy to combine eRuby template with YAML datafile
26
+ END
27
+
28
+ ## files
29
+ files = []
30
+ files += Dir.glob('lib/**/*')
31
+ files += Dir.glob('bin/*')
32
+ #files += Dir.glob('examples/**/*')
33
+ files += Dir.glob('test/**/*')
34
+ files += Dir.glob('doc/**/*')
35
+ #files += %w[README.txt MIT-LICENSE setup.rb tenjin.gemspec CHANGES]
36
+ files += %w[README.txt MIT-LICENSE setup.rb tenjin.gemspec]
37
+ #files += Dir.glob('contrib/*')
38
+ files += Dir.glob('benchmark/**/*')
39
+ files += Dir.glob('doc-api/**/*')
40
+ s.files = files
41
+ s.executables = ['rbtenjin']
42
+ s.bindir = 'bin'
43
+ s.test_file = 'test/test_all.rb'
44
+ end
45
+
46
+ # Quick fix for Ruby 1.8.3 / YAML bug (thanks to Ross Bamford)
47
+ if (RUBY_VERSION == '1.8.3')
48
+ def spec.to_yaml
49
+ out = super
50
+ out = '--- ' + out unless out =~ /^---/
51
+ out
52
+ end
53
+ end
54
+
55
+ if $0 == __FILE__
56
+ Gem::manage_gems
57
+ Gem::Builder.new(spec).build
58
+ end
@@ -0,0 +1,45 @@
1
+ ###
2
+ ### $Rev: 30 $
3
+ ### 0.6.0
4
+ ### copyright(c) 2007 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'test/unit'
8
+ require 'tempfile'
9
+
10
+
11
+ module Test
12
+ module Unit
13
+ class TestCase
14
+
15
+ def assert_text_equal(expected, actual, message=nil, diffopt='-u', flag_cut=true)
16
+ if expected == actual
17
+ assert(true)
18
+ return
19
+ end
20
+ if expected && actual && (expected[-1] != ?\n || actual[-1] != ?\n)
21
+ expected += "\n"
22
+ actual += "\n"
23
+ end
24
+ begin
25
+ expfile = Tempfile.new(".expected.")
26
+ expfile.write(expected); expfile.flush()
27
+ actfile = Tempfile.new(".actual.")
28
+ actfile.write(actual); actfile.flush()
29
+ diff = `diff #{diffopt} #{expfile.path} #{actfile.path}`
30
+ ensure
31
+ expfile.close(true) if expfile
32
+ actfile.close(true) if actfile
33
+ end
34
+ # cut 1st & 2nd lines
35
+ message = (flag_cut ? diff.gsub(/\A.*\n.*\n/, '') : diff) unless message
36
+ #raise Test::Unit::AssertionFailedError.new(message)
37
+ assert_block(message) { false } # or assert(false, message)
38
+ end
39
+
40
+ alias assert_equal_with_diff assert_text_equal # for compatibility
41
+ alias assert_text_equals assert_text_equal # for typo
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,4 @@
1
+ <?rb @title = 'Create user' ?>
2
+ <?rb @label = 'Create' ?>
3
+ <?rb @action = 'action.cgi' ?>
4
+ <?rb import(:form) ?>
@@ -0,0 +1,14 @@
1
+ <?rb #@ARGS action, params, label ?>
2
+ <form action="${@action}" method="post">
3
+ <p>
4
+ <label>Name:</label>
5
+ <input type="text" name="name" value="${@params[:name]}" />
6
+ </p>
7
+ <p>
8
+ <label>Gender:</label>
9
+ <?rb gender = @params[:gender] ?>
10
+ <input type="radio" name="gender" value="M" #{checked(gender=='M')} />Man
11
+ <input type="radio" name="gender" value="W" #{checked(gender=='W')} />Woman
12
+ </p>
13
+ <input type="submit" value="${@label}" />
14
+ </form>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <body>
3
+ <h1>${@title}</h1>
4
+ <div class="main-content">
5
+ #{@_content}
6
+ </div>
7
+ </body>
8
+ </html>
@@ -0,0 +1,9 @@
1
+ ## create Engine object
2
+ require 'tenjin'
3
+ engine = Tenjin::Engine.new(:postfix=>'.rbhtml', :layout=>'layout.rbhtml')
4
+
5
+ ## render template with context data
6
+ params = { :name=>'Foo', :gender=>'M' }
7
+ context = { :params=>params }
8
+ output = engine.render(:update, context) # :update == 'update'+postfix
9
+ puts output
@@ -0,0 +1,21 @@
1
+ $ ruby main.rb
2
+ <html>
3
+ <body>
4
+ <h1>Update user</h1>
5
+ <div class="main-content">
6
+ <form action="update.cgi" method="post">
7
+ <p>
8
+ <label>Name:</label>
9
+ <input type="text" name="name" value="Foo" />
10
+ </p>
11
+ <p>
12
+ <label>Gender:</label>
13
+ <input type="radio" name="gender" value="M" checked="checked" />Man
14
+ <input type="radio" name="gender" value="W" />Woman
15
+ </p>
16
+ <input type="submit" value="Update" />
17
+ </form>
18
+
19
+ </div>
20
+ </body>
21
+ </html>
@@ -0,0 +1,4 @@
1
+ <?rb @title = 'Update user' ?>
2
+ <?rb @label = 'Update' ?>
3
+ <?rb @action = 'update.cgi' ?>
4
+ <?rb import(:form) ?>
@@ -0,0 +1,16 @@
1
+ LANGUAGES = [
2
+ ['en', 'Engilish'],
3
+ ['fr', 'French'],
4
+ ['de', 'German'],
5
+ ['es', 'Spanish'],
6
+ ['ch', 'Chinese'],
7
+ ['ja', 'Japanese'],
8
+ ]
9
+
10
+ def link_to(label, options={})
11
+ action, id = options[:action], options[:id]
12
+ url = '/app'
13
+ url << '/' << action if action && !action.empty?
14
+ url << '/' << id if id
15
+ return "<a href=\"#{CGI::escape(url).gsub(/%2F/i, '/')}\">#{label}</a>"
16
+ end
@@ -0,0 +1,11 @@
1
+ require 'helper'
2
+
3
+ ## create engine
4
+ require 'tenjin'
5
+ engine = Tenjin::Engine.new(:postfix=>'.rbhtml', :preprocess=>true)
6
+
7
+ ## render template with context data
8
+ params = { :id=>1234, :name=>'Foo', :lang=>'ch' }
9
+ context = { :params => params }
10
+ output = engine.render(:select, context)
11
+ puts output
@@ -0,0 +1,17 @@
1
+ $ ruby main.rb
2
+ <form>
3
+ <label>Select your language:</label>
4
+ <select name="lang">
5
+ <option value="en" >Engilish</option>
6
+ <option value="fr" >French</option>
7
+ <option value="de" >German</option>
8
+ <option value="es" >Spanish</option>
9
+ <option value="ch" selected="selected">Chinese</option>
10
+ <option value="ja" >Japanese</option>
11
+ </select>
12
+ <input type="submit" value="OK" />
13
+ </form>
14
+ <p>
15
+ <a href="/app/index">Back</a> |
16
+ <a href="/app/show/1234">Show Foo</a>
17
+ </p>
@@ -0,0 +1,15 @@
1
+ <?RB require 'helper' ?>
2
+ <form>
3
+ <label>Select your language:</label>
4
+ <select name="lang">
5
+ <?rb table = { @params[:lang] => ' selected="selected"' } ?>
6
+ <?RB for val, name in LANGUAGES ?>
7
+ <option value="${{val}}" #{table[#{{val.inspect}}]}>${{name}}</option>
8
+ <?RB end ?>
9
+ </select>
10
+ <input type="submit" value="OK" />
11
+ </form>
12
+ <p>
13
+ #{{link_to('Back', :action=>'index')}} |
14
+ #{{link_to('Show '+_P('@params[:name]'), :action=>'show', :id=>_p('@params[:id]'))}}
15
+ </p>
@@ -0,0 +1,18 @@
1
+ $ rbtenjin -a preprocess select.rbhtml
2
+ <form>
3
+ <label>Select your language:</label>
4
+ <select name="lang">
5
+ <?rb table = { @params[:lang] => ' selected="selected"' } ?>
6
+ <option value="en" #{table["en"]}>Engilish</option>
7
+ <option value="fr" #{table["fr"]}>French</option>
8
+ <option value="de" #{table["de"]}>German</option>
9
+ <option value="es" #{table["es"]}>Spanish</option>
10
+ <option value="ch" #{table["ch"]}>Chinese</option>
11
+ <option value="ja" #{table["ja"]}>Japanese</option>
12
+ </select>
13
+ <input type="submit" value="OK" />
14
+ </form>
15
+ <p>
16
+ <a href="/app/index">Back</a> |
17
+ <a href="/app/show/#{@params[:id]}">Show ${@params[:name]}</a>
18
+ </p>
@@ -0,0 +1,9 @@
1
+ ## create Engine object
2
+ require 'tenjin'
3
+ engine = Tenjin::Engine.new()
4
+
5
+ ## render template with context data
6
+ context = { :title => 'Bordered Table Example',
7
+ :items => [ '<AAA>', 'B&B', '"CCC"' ] }
8
+ output = engine.render('table.rbhtml', context)
9
+ puts output
@@ -0,0 +1,16 @@
1
+ <html>
2
+ <body>
3
+ <h1>${@title}</h1>
4
+ <table>
5
+ <?rb i = 0 ?>
6
+ <?rb for item in @items ?>
7
+ <?rb i += 1 ?>
8
+ <?rb color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' ?>
9
+ <tr bgcolor="#{color}">
10
+ <td>#{i}</td>
11
+ <td>${item}</td>
12
+ </tr>
13
+ <?rb end ?>
14
+ </table>
15
+ </body>
16
+ </html>
@@ -0,0 +1,20 @@
1
+ $ ruby table.rb
2
+ <html>
3
+ <body>
4
+ <h1>Bordered Table Example</h1>
5
+ <table>
6
+ <tr bgcolor="#CCCCFF">
7
+ <td>1</td>
8
+ <td>&lt;AAA&gt;</td>
9
+ </tr>
10
+ <tr bgcolor="#FFCCCC">
11
+ <td>2</td>
12
+ <td>B&amp;B</td>
13
+ </tr>
14
+ <tr bgcolor="#CCCCFF">
15
+ <td>3</td>
16
+ <td>&quot;CCC&quot;</td>
17
+ </tr>
18
+ </table>
19
+ </body>
20
+ </html>
@@ -0,0 +1,18 @@
1
+ $ rbtenjin -a convert table.rbhtml
2
+ _buf = ''; _buf << %Q`<html>
3
+ <body>
4
+ <h1>#{escape((@title).to_s)}</h1>
5
+ <table>\n`
6
+ i = 0
7
+ for item in @items
8
+ i += 1
9
+ color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'
10
+ _buf << %Q` <tr bgcolor="#{color}">
11
+ <td>#{i}</td>
12
+ <td>#{escape((item).to_s)}</td>
13
+ </tr>\n`
14
+ end
15
+ _buf << %Q` </table>
16
+ </body>
17
+ </html>\n`
18
+ _buf.to_s
@@ -0,0 +1,5 @@
1
+ <ul>
2
+ <?rb (0..10).each { |i| ?>
3
+ <li>#{i}</li>
4
+ <?rb end ?>
5
+ </ul>
@@ -0,0 +1,27 @@
1
+ <html>
2
+ <body>
3
+
4
+ <?rb ## if variable '@header_part' is defined then print it, ?>
5
+ <?rb ## else print default header part. ?>
6
+ <div id="header">
7
+ <?rb unless captured_as(:header_part) ?>
8
+ <img src="img/logo.png" alt="logo" ?>
9
+ <?rb end ?>
10
+ </div>
11
+
12
+ <?rb ## main content part ?>
13
+ <div id="content">
14
+ <?rb _buf << @content_part ?>
15
+ </div>
16
+
17
+ <?rb ## if variable '@footer_part' is defined then print it, ?>
18
+ <?rb ## else print default footer part. ?>
19
+ <div id="footer">
20
+ <?rb unless captured_as(:footer_part) ?>
21
+ <hr />
22
+ <em>webmaster@example.com</em>
23
+ <?rb end ?>
24
+ </div>
25
+
26
+ </body>
27
+ </html>
@@ -0,0 +1,12 @@
1
+ <?rb ## '@_layout' variable is equivarent to '{% extends "foobar.html" %}' ?>
2
+ <?rb ## in Django template engine. ?>
3
+ <?rb @_layout = 'ex10-customlayout.rbhtml' ?>
4
+
5
+ <?rb ## main content part ?>
6
+ <?rb start_capture(:content_part) ?>
7
+ <ul>
8
+ <?rb for item in @items ?>
9
+ <li>${item}</li>
10
+ <?rb end ?>
11
+ </ul>
12
+ <?rb stop_capture() ?>
@@ -0,0 +1,11 @@
1
+ <?rb ## '@_layout' variable is equivarent to '{% extends "foobar.html" %}' ?>
2
+ <?rb ## in Django template engine. ?>
3
+ <?rb @_layout = 'ex10-baselayout.rbhtml' ?>
4
+
5
+ <?rb ## you can override header or footer by capturing. ?>
6
+ <?rb start_capture(:footer_part) ?>
7
+ <address style="text-align:right">
8
+ copyright&copy; 2007 kuwata-lab all rights reserved<br />
9
+ <a href="webmaster&#64;kuwata-lab.com">webmaster&#64;kuwata-lab.com</a>
10
+ </address>
11
+ <?rb stop_capture() ?>
@@ -0,0 +1,25 @@
1
+ $ rbtenjin -c "@items=['AAA', 'BBB', 'CCC']" ex10-content.rbhtml
2
+ <html>
3
+ <body>
4
+
5
+ <div id="header">
6
+ <img src="img/logo.png" alt="logo" ?>
7
+ </div>
8
+
9
+ <div id="content">
10
+ <ul>
11
+ <li>AAA</li>
12
+ <li>BBB</li>
13
+ <li>CCC</li>
14
+ </ul>
15
+ </div>
16
+
17
+ <div id="footer">
18
+ <address style="text-align:right">
19
+ copyright&copy; 2007 kuwata-lab all rights reserved<br />
20
+ <a href="webmaster&#64;kuwata-lab.com">webmaster&#64;kuwata-lab.com</a>
21
+ </address>
22
+ </div>
23
+
24
+ </body>
25
+ </html>
@@ -0,0 +1,28 @@
1
+ ## create Engine object for each layout file
2
+ require 'tenjin'
3
+ engine1 = Tenjin::Engine.new(:layout=>'ex11-layout1.rbhtml')
4
+ engine2 = Tenjin::Engine.new(:layout=>'ex11-layout2.rbhtml')
5
+
6
+ ## warm up
7
+ filename = 'ex11-content.rbhtml'
8
+ output1 = engine1.render(filename)
9
+ output2 = engine2.render(filename)
10
+ raise "*** output1 != output2" if output1 != output2
11
+
12
+ ## do benchmark
13
+ require 'benchmark'
14
+ N = 10000
15
+ Benchmark.bm(20) do |job|
16
+ GC.start()
17
+ job.report('layout1') do
18
+ N.times do
19
+ output1 = engine1.render(filename)
20
+ end
21
+ end
22
+ GC.start()
23
+ job.report('layout2') do
24
+ N.times do
25
+ output2 = engine2.render(filename)
26
+ end
27
+ end
28
+ end