erubis 2.3.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. data/{CHANGES → CHANGES.txt} +373 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.txt +6 -5
  4. data/benchmark/bench.rb +18 -11
  5. data/bin/erubis +3 -4
  6. data/contrib/erubis +3462 -5
  7. data/contrib/inline-require +54 -28
  8. data/doc/docstyle.css +25 -4
  9. data/doc/users-guide.html +814 -110
  10. data/doc-api/classes/ActionView/TemplateHandlers/ErubisHandler.html +209 -0
  11. data/doc-api/classes/ActionView.html +105 -0
  12. data/doc-api/classes/Erubis/ArrayBufferEnhancer.html +14 -14
  13. data/doc-api/classes/Erubis/ArrayEnhancer.html +16 -16
  14. data/doc-api/classes/Erubis/Basic/Converter.html +36 -31
  15. data/doc-api/classes/Erubis/BiPatternEnhancer.html +16 -13
  16. data/doc-api/classes/Erubis/CGenerator.html +70 -70
  17. data/doc-api/classes/Erubis/Context.html +49 -49
  18. data/doc-api/classes/Erubis/Converter.html +30 -29
  19. data/doc-api/classes/Erubis/CppGenerator.html +382 -0
  20. data/doc-api/classes/Erubis/DeleteIndentEnhancer.html +7 -7
  21. data/doc-api/classes/Erubis/Ecpp.html +126 -0
  22. data/doc-api/classes/Erubis/Engine.html +46 -43
  23. data/doc-api/classes/Erubis/ErboutEnhancer.html +16 -16
  24. data/doc-api/classes/Erubis/EscapeEnhancer.html +7 -7
  25. data/doc-api/classes/Erubis/EscapedEcpp.html +120 -0
  26. data/doc-api/classes/Erubis/Evaluator.html +22 -22
  27. data/doc-api/classes/Erubis/Generator.html +70 -70
  28. data/doc-api/classes/Erubis/HeaderFooterEnhancer.html +18 -15
  29. data/doc-api/classes/Erubis/Helpers/RailsFormHelper.html +787 -0
  30. data/doc-api/classes/Erubis/Helpers/RailsHelper/TemplateConverter.html +213 -0
  31. data/doc-api/classes/Erubis/Helpers/RailsHelper.html +103 -54
  32. data/doc-api/classes/Erubis/Helpers.html +6 -1
  33. data/doc-api/classes/Erubis/InterpolationEnhancer.html +42 -41
  34. data/doc-api/classes/Erubis/JavaGenerator.html +69 -69
  35. data/doc-api/classes/Erubis/JavascriptGenerator.html +79 -74
  36. data/doc-api/classes/Erubis/Main.html +49 -48
  37. data/doc-api/classes/Erubis/NoCodeEnhancer.html +35 -35
  38. data/doc-api/classes/Erubis/NoTextEnhancer.html +7 -7
  39. data/doc-api/classes/Erubis/OptimizedEruby.html +7 -7
  40. data/doc-api/classes/Erubis/OptimizedGenerator.html +84 -84
  41. data/doc-api/classes/Erubis/OptimizedXmlEruby.html +7 -7
  42. data/doc-api/classes/Erubis/PI/Converter.html +23 -22
  43. data/doc-api/classes/Erubis/PI/Ec.html +7 -7
  44. data/doc-api/classes/Erubis/PI/Ecpp.html +166 -0
  45. data/doc-api/classes/Erubis/PI/Ejava.html +7 -7
  46. data/doc-api/classes/Erubis/PI/Ejavascript.html +7 -7
  47. data/doc-api/classes/Erubis/PI/Eperl.html +7 -7
  48. data/doc-api/classes/Erubis/PI/Ephp.html +7 -7
  49. data/doc-api/classes/Erubis/PI/Eruby.html +6 -6
  50. data/doc-api/classes/Erubis/PI/Escheme.html +7 -7
  51. data/doc-api/classes/Erubis/PI/TinyEruby.html +28 -27
  52. data/doc-api/classes/Erubis/PI.html +1 -0
  53. data/doc-api/classes/Erubis/PercentLineEnhancer.html +18 -29
  54. data/doc-api/classes/Erubis/PerlGenerator.html +63 -63
  55. data/doc-api/classes/Erubis/PhpGenerator.html +63 -63
  56. data/doc-api/classes/Erubis/PrefixedLineEnhancer.html +210 -0
  57. data/doc-api/classes/Erubis/PrefixedLineEruby.html +120 -0
  58. data/doc-api/classes/Erubis/PreprocessingEruby.html +183 -0
  59. data/doc-api/classes/Erubis/PreprocessingHelper.html +212 -0
  60. data/doc-api/classes/Erubis/PrintEnabledEnhancer.html +23 -23
  61. data/doc-api/classes/Erubis/PrintOutEnhancer.html +38 -38
  62. data/doc-api/classes/Erubis/RubyEvaluator.html +59 -22
  63. data/doc-api/classes/Erubis/RubyGenerator.html +53 -52
  64. data/doc-api/classes/Erubis/SchemeGenerator.html +70 -70
  65. data/doc-api/classes/Erubis/SimplifyEnhancer.html +10 -9
  66. data/doc-api/classes/Erubis/StdoutEnhancer.html +3 -3
  67. data/doc-api/classes/Erubis/StringBufferEnhancer.html +16 -16
  68. data/doc-api/classes/Erubis/TinyEruby.html +33 -33
  69. data/doc-api/classes/Erubis/XmlHelper.html +80 -15
  70. data/doc-api/classes/Erubis.html +25 -1
  71. data/doc-api/classes/Kernel.html +155 -0
  72. data/doc-api/created.rid +1 -1
  73. data/doc-api/files/README_txt.html +8 -8
  74. data/doc-api/files/erubis/context_rb.html +2 -2
  75. data/doc-api/files/erubis/converter_rb.html +3 -3
  76. data/doc-api/files/erubis/engine/ec_rb.html +2 -2
  77. data/doc-api/files/erubis/engine/ecpp_rb.html +115 -0
  78. data/doc-api/files/erubis/engine/ejava_rb.html +2 -2
  79. data/doc-api/files/erubis/engine/ejavascript_rb.html +2 -2
  80. data/doc-api/files/erubis/engine/enhanced_rb.html +2 -2
  81. data/doc-api/files/erubis/engine/eperl_rb.html +2 -2
  82. data/doc-api/files/erubis/engine/ephp_rb.html +2 -2
  83. data/doc-api/files/erubis/engine/eruby_rb.html +2 -2
  84. data/doc-api/files/erubis/engine/escheme_rb.html +2 -2
  85. data/doc-api/files/erubis/engine/optimized_rb.html +2 -2
  86. data/doc-api/files/erubis/engine_rb.html +2 -2
  87. data/doc-api/files/erubis/enhancer_rb.html +2 -2
  88. data/doc-api/files/erubis/error_rb.html +2 -2
  89. data/doc-api/files/erubis/evaluator_rb.html +2 -2
  90. data/doc-api/files/erubis/generator_rb.html +3 -3
  91. data/doc-api/files/erubis/helper_rb.html +2 -2
  92. data/doc-api/files/erubis/helpers/rails_form_helper_rb.html +107 -0
  93. data/doc-api/files/erubis/helpers/rails_helper_rb.html +3 -2
  94. data/doc-api/files/erubis/local-setting_rb.html +2 -2
  95. data/doc-api/files/erubis/main_rb.html +4 -2
  96. data/doc-api/files/erubis/preprocessing_rb.html +114 -0
  97. data/doc-api/files/erubis/tiny_rb.html +2 -2
  98. data/doc-api/files/erubis/util_rb.html +107 -0
  99. data/doc-api/files/erubis_rb.html +2 -2
  100. data/doc-api/fr_class_index.html +13 -0
  101. data/doc-api/fr_file_index.html +4 -0
  102. data/doc-api/fr_method_index.html +237 -179
  103. data/examples/basic/Makefile +7 -2
  104. data/examples/basic/example.ecpp +33 -0
  105. data/lib/erubis/context.rb +2 -3
  106. data/lib/erubis/converter.rb +17 -11
  107. data/lib/erubis/engine/ec.rb +2 -3
  108. data/lib/erubis/engine/ecpp.rb +113 -0
  109. data/lib/erubis/engine/ejava.rb +9 -10
  110. data/lib/erubis/engine/ejavascript.rb +14 -9
  111. data/lib/erubis/engine/enhanced.rb +7 -3
  112. data/lib/erubis/engine/eperl.rb +2 -3
  113. data/lib/erubis/engine/ephp.rb +2 -3
  114. data/lib/erubis/engine/eruby.rb +8 -8
  115. data/lib/erubis/engine/escheme.rb +2 -3
  116. data/lib/erubis/engine/optimized.rb +2 -3
  117. data/lib/erubis/engine.rb +13 -11
  118. data/lib/erubis/enhancer.rb +101 -34
  119. data/lib/erubis/error.rb +2 -3
  120. data/lib/erubis/evaluator.rb +27 -10
  121. data/lib/erubis/generator.rb +3 -4
  122. data/lib/erubis/helper.rb +14 -3
  123. data/lib/erubis/helpers/rails_form_helper.rb +197 -0
  124. data/lib/erubis/helpers/rails_helper.rb +219 -77
  125. data/lib/erubis/local-setting.rb +2 -3
  126. data/lib/erubis/main.rb +85 -60
  127. data/lib/erubis/preprocessing.rb +58 -0
  128. data/lib/erubis/tiny.rb +9 -9
  129. data/lib/erubis/util.rb +22 -0
  130. data/lib/erubis.rb +4 -4
  131. data/test/assert-text-equal.rb +2 -3
  132. data/test/data/users-guide/bufvar-example.rb +10 -0
  133. data/test/data/users-guide/bufvar-example.result +17 -0
  134. data/test/data/users-guide/def_method.rb +14 -0
  135. data/test/data/users-guide/def_method.result +3 -0
  136. data/test/data/users-guide/example.ecpp +30 -0
  137. data/test/data/users-guide/example1.rb +1 -0
  138. data/test/data/users-guide/example_c.result +22 -19
  139. data/test/data/users-guide/fasteruby-example.rb +8 -0
  140. data/test/data/users-guide/fasteruby-example.result +18 -0
  141. data/test/data/users-guide/main_program1.rb +8 -0
  142. data/test/data/users-guide/main_program1.result +6 -0
  143. data/test/data/users-guide/main_program2.rb +8 -0
  144. data/test/data/users-guide/main_program2.result +6 -0
  145. data/test/data/users-guide/percentline-example.rhtml +3 -1
  146. data/test/data/users-guide/percentline_example.result +5 -3
  147. data/test/data/users-guide/prefixedline-example.rb +9 -0
  148. data/test/data/users-guide/prefixedline-example.rhtml +6 -0
  149. data/test/data/users-guide/prefixedline_example.result +9 -0
  150. data/test/data/users-guide/tail_260.result +4 -0
  151. data/test/data/users-guide/tailnewline.rhtml +3 -0
  152. data/test/data/users-guide/template1.rhtml +4 -0
  153. data/test/data/users-guide/template2.rhtml +4 -0
  154. data/test/test-engines.rb +88 -5
  155. data/test/test-enhancers.rb +83 -6
  156. data/test/test-erubis.rb +115 -11
  157. data/test/test-index-cgi.rb +191 -0
  158. data/test/test-main.rb +143 -31
  159. data/test/test-users-guide.rb +20 -3
  160. data/test/test.rb +18 -3
  161. data/test/testutil.rb +44 -8
  162. metadata +104 -67
  163. data/contrib/action_view_base_rb.patch +0 -23
data/doc/users-guide.html CHANGED
@@ -13,11 +13,7 @@
13
13
  <div class="mainbody">
14
14
 
15
15
  <div align="left"><h1>Erubis Users' Guide</h1></div>
16
- <div align="left">
17
- last update: $Date: 2007-05-26 13:29:48 +0900 (Sat, 26 May 2007) $<br>
18
- </div>
19
-
20
- <p>release: 2.3.1
16
+ <p>release: 2.7.0
21
17
  </p>
22
18
  <a name="preface"></a>
23
19
  <h2 class="section1">Preface</h2>
@@ -25,32 +21,33 @@
25
21
  It has the following features.
26
22
  </p>
27
23
  <ul type="disc">
28
- <li><a href="#topics-benchmark">Very fast</a>, almost three times faster than ERB and about ten percent faster than eruby (implemented in C)
24
+ <li>Very fast, almost three times faster than ERB and about ten percent faster than eruby (implemented in C)
29
25
  </li>
30
- <li><a href="#topics-caching">File caching of converted Ruby script support</a>
26
+ <li>File caching of converted Ruby script support
31
27
  </li>
32
- <li><a href="#tut-escape">Auto escaping support</a>
28
+ <li>Auto escaping support
33
29
  </li>
34
- <li><a href="#tut-trim">Auto trimming spaces around '&lt;% %&gt;'</a>
30
+ <li>Auto trimming spaces around '&lt;% %&gt;'
35
31
  </li>
36
- <li><a href="#tut-pattern">Embedded pattern changeable</a> (default '&lt;% %&gt;')
32
+ <li>Embedded pattern changeable (default '&lt;% %&gt;')
37
33
  </li>
38
- <li><a href="#tut-pi">Enable to handle Processing Instructions (PI) as embedded pattern</a> (ex. '&lt;?rb ... ?&gt;')
34
+ <li>Enable to handle Processing Instructions (PI) as embedded pattern (ex. '&lt;?rb ... ?&gt;')
39
35
  </li>
40
- <li><a href="#lang">Multi-language support</a> (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
36
+ <li>Multi-language support (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
41
37
  </li>
42
- <li><a href="#tut-context">Context object available</a> and <a href="#tut-datafile">easy to combine eRuby template with YAML datafile</a>
38
+ <li>Context object available and easy to combine eRuby template with YAML datafile
43
39
  </li>
44
- <li><a href="#printenabled-enhancer">Print statement available</a>
40
+ <li>Print statement available
45
41
  </li>
46
- <li><a href="#enhancer">Easy to expand and customize in subclass</a>
42
+ <li>Easy to expand and customize in subclass
47
43
  </li>
48
- <li><a href="#topics-rails">Ruby on Rails support</a>
44
+ <li><a href="#rails">Ruby on Rails support</a>
49
45
  </li>
50
- <li><a href="#topcs-modruby">mod_ruby support</a>
46
+ <li>mod_ruby support|#topcs-modruby
51
47
  </li>
52
48
  </ul>
53
49
  <p>Erubis is implemented in pure Ruby. It requires Ruby 1.8 or higher.
50
+ Erubis now supports Ruby 1.9.
54
51
  </p>
55
52
  <a name="toc"></a>
56
53
  <h3 class="section2">Table of Contents</h3>
@@ -115,6 +112,8 @@ It has the following features.
115
112
  </li>
116
113
  <li><a href="#percentline-enhancer">PercentLineEnhancer</a>
117
114
  </li>
115
+ <li><a href="#prefixedline-enhancer">PrefixedLineEnhancer</a>
116
+ </li>
118
117
  <li><a href="#headerfooter-enhancer">HeaderFooterEnhancer</a>
119
118
  </li>
120
119
  <li><a href="#interpolation-enhancer">InterpolationEnhancer</a>
@@ -129,6 +128,8 @@ It has the following features.
129
128
  </li>
130
129
  <li><a href="#lang-c">C</a>
131
130
  </li>
131
+ <li><a href="#lang-cpp">C++</a>
132
+ </li>
132
133
  <li><a href="#lang-java">Java</a>
133
134
  </li>
134
135
  <li><a href="#lang-scheme">Scheme</a>
@@ -139,8 +140,30 @@ It has the following features.
139
140
  </li>
140
141
  </ul>
141
142
  </li>
143
+ <li><a href="#rails">Ruby on Rails Support</a>
144
+ <ul>
145
+ <li><a href="#rails-settings">Settings</a>
146
+ </li>
147
+ <li><a href="#rails-preprocessing">Preprosessing</a>
148
+ </li>
149
+ <li><a href="#rails-formhelpers">Form Helpers for Preprocessing</a>
150
+ </li>
151
+ <li><a href="#rails-others">Others</a>
152
+ </li>
153
+ </ul>
154
+ </li>
142
155
  <li><a href="#topics">Other Topics</a>
143
156
  <ul>
157
+ <li><a href="#topics-fasteruby"><code>Erubis::FastEruby</code> Class</a>
158
+ </li>
159
+ <li><a href="#topics-bufvar"><code>:bufvar</code> Option</a>
160
+ </li>
161
+ <li><a href="#topics-trimspaces">'&lt;%= =%&gt;' and '&lt;%= -%&gt;'</a>
162
+ </li>
163
+ <li><a href="#topics-doublepercent">'&lt;%% %&gt;' and '&lt;%%= %&gt;'</a>
164
+ </li>
165
+ <li><a href="#topics-context-vs-binding">evaluate(context) v.s. result(binding)</a>
166
+ </li>
144
167
  <li><a href="#topics-fasteruby">Class Erubis::FastEruby</a>
145
168
  </li>
146
169
  <li><a href="#topics-syntax">Syntax Checking</a>
@@ -149,12 +172,14 @@ It has the following features.
149
172
  </li>
150
173
  <li><a href="#topics-tinyeruby">Erubis::TinyEruby class</a>
151
174
  </li>
152
- <li><a href="#topics-rails">Ruby on Rails Support</a>
153
- </li>
154
175
  <li><a href="#topics-php">NoTextEnhancer and NoCodeEnhancer in PHP</a>
155
176
  </li>
156
177
  <li><a href="#topcs-modruby">Helper Class for mod_ruby</a>
157
178
  </li>
179
+ <li><a href="#topics-index-cgi">Helper CGI Script for Apache</a>
180
+ </li>
181
+ <li><a href="#topics-defmethod">Define method</a>
182
+ </li>
158
183
  <li><a href="#topics-benchmark">Benchmark</a>
159
184
  </li>
160
185
  </ul>
@@ -238,6 +263,7 @@ puts <strong>eruby.src</strong> # print script source
238
263
  puts "---------- result ----------"
239
264
  list = ['aaa', 'bbb', 'ccc']
240
265
  puts <strong>eruby.result(binding())</strong> # get result
266
+ ## or puts eruby.result(<strong>:list=&gt;list</strong>) # or pass Hash instead of Binding
241
267
 
242
268
  ## # or
243
269
  ## eruby = Erubis::Eruby.new
@@ -602,22 +628,22 @@ This means that data is passed into eRuby script via local variables when Eruby:
602
628
  </p>
603
629
  <div class="program_caption">
604
630
  definition of result(binding) and evaluate(context)</div>
605
- <pre class="program">def result(_binding)
631
+ <pre class="program">def result(_binding=TOPLEVEL_BINDING)
606
632
  if _binding.is_a?(Hash)
607
633
  # load hash data as local variable
608
634
  _h = _binding
609
- eval _h.keys.inject("") {|s,k| s &lt;&lt; "#{k} = _h[#{k.inspect}];"}
610
635
  _binding = binding()
636
+ eval _h.collect{|k,v| "#{k} = _h[#{k.inspect}];"}.join, _binding
611
637
  end
612
638
  return <strong>eval(@src, _binding)</strong>
613
639
  end
614
640
 
615
- def evaluate(_context)
641
+ def evaluate(_context=Erubis::Context.new)
616
642
  if _context.is_a?(Hash)
617
643
  # convert hash object to Context object
618
644
  _hash = _context
619
645
  _context = Erubis::Context.new
620
- _hash.each { |key, val| _context[key] = val }
646
+ _hash.each {|k, v| _context[k] = v }
621
647
  end
622
648
  return <strong>_context.instance_eval(@src)</strong>
623
649
  end
@@ -651,6 +677,9 @@ output</div>
651
677
  &lt;li&gt;ccc&lt;/li&gt;
652
678
  &lt;/ul&gt;
653
679
  </pre>
680
+ <p>It is recommended to use 'Erubis::Eruby#evaluate(context)' rather than 'Erubis::Eruby#result(binding())' because the latter has some problems.
681
+ See <a href="#topics-context-vs-binding">evaluate(context) v.s. result(binding)</a> section for details.
682
+ </p>
654
683
  <br>
655
684
 
656
685
 
@@ -1614,19 +1643,23 @@ This is for compatibility with eruby and ERB.
1614
1643
  <a name="percentline-example.rhtml"></a>
1615
1644
  <div class="program_caption">
1616
1645
  percentline-example.rhtml</div>
1617
- <pre class="program"><strong>% for item in list</strong>
1618
- &lt;b&gt;&lt;%= item %&gt;&lt;/b&gt;
1646
+ <pre class="program">&lt;ul&gt;
1647
+ <strong>% for item in list</strong>
1648
+ &lt;li&gt;&lt;%= item %&gt;&lt;/li&gt;
1619
1649
  <strong>% end</strong>
1620
- %% lines with '%%'
1650
+ &lt;/ul&gt;
1651
+ <strong>%% lines with '%%'</strong>
1621
1652
  </pre>
1622
1653
  <a name="percentline_example.result"></a>
1623
1654
  <div class="terminal_caption">
1624
1655
  compiled source code</div>
1625
1656
  <pre class="terminal">$ erubis -xE PercentLine percentline-example.rhtml
1626
- _buf = ''; <strong>for item in list</strong>
1627
- _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
1657
+ _buf = ''; _buf &lt;&lt; '&lt;ul&gt;
1658
+ '; <strong>for item in list</strong>
1659
+ _buf &lt;&lt; ' &lt;li&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/li&gt;
1628
1660
  '; <strong>end</strong>
1629
- _buf &lt;&lt; '% lines with \'%%\'
1661
+ _buf &lt;&lt; '&lt;/ul&gt;
1662
+ <strong>% lines with \'%%\'</strong>
1630
1663
  ';
1631
1664
  _buf.to_s
1632
1665
  </pre>
@@ -1635,6 +1668,58 @@ _buf.to_s
1635
1668
  <br>
1636
1669
 
1637
1670
 
1671
+ <a name="prefixedline-enhancer"></a>
1672
+ <h3 class="section2">PrefixedLineEnhancer</h3>
1673
+ <p>PrefixedlineEnhancer regards lines starting with '%' as Ruby code.
1674
+ It is similar to <a href="#percentline-enhancer">PercentLineEnhancer</a>, but there are some differences.
1675
+ </p>
1676
+ <ul type="disc">
1677
+ <li>PrefixedlineEnhancer allows to indent lines starting with '%', but PercentLineEnhancer doesn't.
1678
+ </li>
1679
+ <li>PrefixedlineEnhancer allows to change prefixed character (default '%'), but PercentLineEnhancer doesn't.
1680
+ </li>
1681
+ </ul>
1682
+ <a name="prefixedline-example.rhtml"></a>
1683
+ <div class="program_caption">
1684
+ prefixedline-example.rhtml</div>
1685
+ <pre class="program">&lt;ul&gt;
1686
+ <strong>! for item in list</strong>
1687
+ &lt;li&gt;&lt;%= item %&gt;&lt;/li&gt;
1688
+ <strong>! end</strong>
1689
+ &lt;/ul&gt;
1690
+ <strong>!! lines with '!!'</strong>
1691
+ </pre>
1692
+ <a name="prefixedline-example.rb"></a>
1693
+ <div class="program_caption">
1694
+ prefixedline-example.rb</div>
1695
+ <pre class="program">require 'erubis'
1696
+
1697
+ class PrefixedLineEruby &lt; Erubis::Eruby
1698
+ include Erubis::PrefixedLineEnhancer
1699
+ end
1700
+
1701
+ input = File.read('prefixedline-example.rhtml')
1702
+ eruby = PrefixedLineEruby.new(input, :prefixchar=&gt;'!') # default '%'
1703
+ print eruby.src
1704
+ </pre>
1705
+ <a name="prefixedline_example.result"></a>
1706
+ <div class="terminal_caption">
1707
+ compiled source code</div>
1708
+ <pre class="terminal">$ ruby prefixedline-example.rb
1709
+ _buf = ''; _buf &lt;&lt; '&lt;ul&gt;
1710
+ '; <strong>for item in list</strong>
1711
+ _buf &lt;&lt; ' &lt;li&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/li&gt;
1712
+ '; <strong>end</strong>
1713
+ _buf &lt;&lt; '&lt;/ul&gt;
1714
+ <strong>! lines with \'!!\'</strong>
1715
+ ';
1716
+ _buf.to_s
1717
+ </pre>
1718
+ <p>PrefixedLineEnhancer is language-independent.
1719
+ </p>
1720
+ <br>
1721
+
1722
+
1638
1723
  <a name="headerfooter-enhancer"></a>
1639
1724
  <h3 class="section2">HeaderFooterEnhancer</h3>
1640
1725
  <p>[experimental]
@@ -1807,24 +1892,30 @@ It deletes indentations even if they are in &lt;PRE&gt;&lt;/PRE&gt;.
1807
1892
 
1808
1893
  <a name="lang"></a>
1809
1894
  <h2 class="section1">Multi-Language Support</h2>
1810
- <p>Erubis supports the following language currently:
1895
+ <p>Erubis supports the following languages<sup>(<a href="#fnref:2" name="fnlink:2">*2</a>)</sup>:
1811
1896
  </p>
1812
1897
  <ul type="disc">
1813
1898
  <li>Ruby
1814
1899
  </li>
1815
- <li>PHP
1900
+ <li><a href="#lang-php">PHP</a>
1816
1901
  </li>
1817
- <li>C
1902
+ <li><a href="#lang-c">C</a>
1818
1903
  </li>
1819
- <li>Java
1904
+ <li><a href="#lang-java">Java</a>
1820
1905
  </li>
1821
- <li>Scheme
1906
+ <li><a href="#lang-scheme">Scheme</a>
1822
1907
  </li>
1823
- <li>Perl
1908
+ <li><a href="#lang-perl">Perl</a>
1824
1909
  </li>
1825
- <li>JavaScript
1910
+ <li><a href="#lang-javascript">JavaScript</a>
1826
1911
  </li>
1827
1912
  </ul>
1913
+ <div class="footnote">
1914
+ <dl compact>
1915
+ <dt>(<a name="fnref:2" href="#fnlink:2">*2</a>)</dt>
1916
+ <dd>If you need template engine in pure PHP/Perl/JavaScript, try <a href="http://www.kuwata-lab.com/tenjin/">Tenjin</a> (<a href="http://www.kuwata-lab.com/tenjin/">http://www.kuwata-lab.com/tenjin/</a>). Tenjin is a very fast and full-featured template engine implemented in pure PHP/Perl/JavaScript.</dd>
1917
+ </dl>
1918
+ </div>
1828
1919
  <a name="lang-php"></a>
1829
1920
  <h3 class="section2">PHP</h3>
1830
1921
  <a name="example.ephp"></a>
@@ -1944,6 +2035,81 @@ fputs(" &lt;/tbody&gt;\n"
1944
2035
  <br>
1945
2036
 
1946
2037
 
2038
+ <a name="lang-cpp"></a>
2039
+ <h3 class="section2">C++</h3>
2040
+ <a name="example.ecpp"></a>
2041
+ <div class="program_caption">
2042
+ example.ecpp</div>
2043
+ <pre class="program"><strong>&lt;%
2044
+ #include &lt;string&gt;
2045
+ #include &lt;iostream&gt;
2046
+ #include &lt;sstream&gt;
2047
+
2048
+ int main(int argc, char *argv[])
2049
+ {
2050
+ std::stringstream _buf;
2051
+ %&gt;</strong>
2052
+ &lt;html&gt;
2053
+ &lt;body&gt;
2054
+ &lt;p&gt;Hello <strong>&lt;%= argv[0] %&gt;</strong>!&lt;/p&gt;
2055
+ &lt;table&gt;
2056
+ &lt;tbody&gt;
2057
+ <strong>&lt;% for (int i = 1; i &lt; argc; i++) { %&gt;</strong>
2058
+ &lt;tr bgcolor="<strong>&lt;%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %&gt;</strong>"&gt;
2059
+ &lt;td&gt;<strong>&lt;%= i %&gt;</strong>&lt;/td&gt;
2060
+ &lt;td&gt;<strong>&lt;%= argv[i] %&gt;</strong>&lt;/td&gt;
2061
+ &lt;/tr&gt;
2062
+ <strong>&lt;% } %&gt;</strong>
2063
+ &lt;/tbody&gt;
2064
+ &lt;/table&gt;
2065
+ &lt;/body&gt;
2066
+ &lt;/html&gt;
2067
+ <strong>&lt;%
2068
+ std::string output = _buf.str();
2069
+ std::cout &lt;&lt; output;
2070
+ return 0;
2071
+ }
2072
+ %&gt;</strong>
2073
+ </pre>
2074
+ <a name="example_c.result"></a>
2075
+ <div class="terminal_caption">
2076
+ compiled source code</div>
2077
+ <pre class="terminal">$ erubis -l cpp example.ecpp
2078
+ #line 1 "example.ecpp"
2079
+
2080
+ #include &lt;string&gt;
2081
+ #include &lt;iostream&gt;
2082
+ #include &lt;sstream&gt;
2083
+
2084
+ int main(int argc, char *argv[])
2085
+ {
2086
+ std::stringstream _buf;
2087
+
2088
+ _buf &lt;&lt; "&lt;html&gt;\n"
2089
+ " &lt;body&gt;\n"
2090
+ " &lt;p&gt;Hello "; _buf &lt;&lt; (argv[0]); _buf &lt;&lt; "!&lt;/p&gt;\n"
2091
+ " &lt;table&gt;\n"
2092
+ " &lt;tbody&gt;\n";
2093
+ for (int i = 1; i &lt; argc; i++) {
2094
+ _buf &lt;&lt; " &lt;tr bgcolor=\""; _buf &lt;&lt; (i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"); _buf &lt;&lt; "\"&gt;\n"
2095
+ " &lt;td&gt;"; _buf &lt;&lt; (i); _buf &lt;&lt; "&lt;/td&gt;\n"
2096
+ " &lt;td&gt;"; _buf &lt;&lt; (argv[i]); _buf &lt;&lt; "&lt;/td&gt;\n"
2097
+ " &lt;/tr&gt;\n";
2098
+ }
2099
+ _buf &lt;&lt; " &lt;/tbody&gt;\n"
2100
+ " &lt;/table&gt;\n"
2101
+ " &lt;/body&gt;\n"
2102
+ "&lt;/html&gt;\n";
2103
+
2104
+ std::string output = _buf.str();
2105
+ std::cout &lt;&lt; output;
2106
+ return 0;
2107
+ }
2108
+
2109
+ </pre>
2110
+ <br>
2111
+
2112
+
1947
2113
  <a name="lang-java"></a>
1948
2114
  <h3 class="section2">Java</h3>
1949
2115
  <a name="Example.ejava"></a>
@@ -2138,7 +2304,7 @@ compiled source code</div>
2138
2304
  </pre>
2139
2305
  <a name="example_scheme_display.result"></a>
2140
2306
  <div class="terminal_caption">
2141
- compiled source code (with --func=display property)</div>
2307
+ compiled source code (with <code>--func=display</code> property)</div>
2142
2308
  <pre class="terminal">$ erubis -l scheme --func=display example.escheme
2143
2309
  (display "&lt;html&gt;
2144
2310
  &lt;body&gt;\n")
@@ -2176,7 +2342,7 @@ compiled source code (with --func=display property)</div>
2176
2342
  <h3 class="section2">Perl</h3>
2177
2343
  <a name="example.eperl"></a>
2178
2344
  <div class="program_caption">
2179
- example.eprl</div>
2345
+ example.eperl</div>
2180
2346
  <pre class="program"><strong>&lt;%
2181
2347
  my $user = 'Erubis';
2182
2348
  my @list = ('&lt;aaa&gt;', 'b&amp;b', '"ccc"');
@@ -2275,6 +2441,308 @@ _buf.push(" &lt;/tbody&gt;\n\
2275
2441
  &lt;/html&gt;\n");
2276
2442
  document.write(_buf.join(""));
2277
2443
  </pre>
2444
+ <p>If command-line option '<code>--docwrite=false</code>' is specified,
2445
+ '<code>_buf.join("");</code>' is used instead of '<code>document.write(_buf.join(""));</code>'.
2446
+ This is useful when passing converted source code to eval() function in JavaScript.
2447
+ </p>
2448
+ <p>You can pass <code>:docwrite=&gt;false</code> to Erubis::Ejavascript.new() in your Ruby script.
2449
+ </p>
2450
+ <pre class="program">s = File.read('example.jshtml')
2451
+ engine = Erubis::Ejavascript.new(s, <code>:docwrite=&gt;false</code>)
2452
+ </pre>
2453
+ <p>If you want to specify any JavaScript code, use '--postamble=...'.
2454
+ </p>
2455
+ <p>Notice that default value of 'docwrite' property will be false in the future release.
2456
+ </p>
2457
+ <br>
2458
+
2459
+
2460
+ <br>
2461
+
2462
+
2463
+ <a name="rails"></a>
2464
+ <h2 class="section1">Ruby on Rails Support</h2>
2465
+ <p><span style="color:#FF0000">NOTICE: Rails 3 adopts Erubis as default default engine. You don't need to do anything at all when using Rails 3. This section is for Rails 2.</span>
2466
+ </p>
2467
+ <p>Erubis supports Ruby on Rails.
2468
+ This section describes how to use Erubis with Ruby on Rails.
2469
+ </p>
2470
+ <a name="rails-settings"></a>
2471
+ <h3 class="section2">Settings</h3>
2472
+ <p>Add the following code to your 'config/environment.rb' and restart web server.
2473
+ This replaces ERB in Rails by Erubis entirely.
2474
+ </p>
2475
+ <div class="program_caption">
2476
+ config/environment.rb</div>
2477
+ <pre class="program">require 'erubis/helpers/rails_helper'
2478
+ #Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby # or Erubis::FastEruby
2479
+ #Erubis::Helpers::RailsHelper.init_properties = {}
2480
+ #Erubis::Helpers::RailsHelper.show_src = nil
2481
+ #Erubis::Helpers::RailsHelper.preprocessing = false
2482
+ </pre>
2483
+ <p>Options:
2484
+ </p>
2485
+ <dl class="dl2">
2486
+ <dt class="dt2">
2487
+ Erubis::Helpers::RailsHelper.engine_class (=Erubis::Eruby)</dt>
2488
+ <dd class="dd2">
2489
+ <p> Erubis engine class (default Erubis::Eruby).
2490
+ </p>
2491
+ </dd>
2492
+ <dt class="dt2">
2493
+ Erubis::Helpers::RailsHelper.init_properties (={})</dt>
2494
+ <dd class="dd2">
2495
+ <p> Optional arguments for Erubis::Eruby#initialize() method (default {}).
2496
+ </p>
2497
+ </dd>
2498
+ <dt class="dt2">
2499
+ Erubis::Helpers::RailsHelper.show_src (=nil)</dt>
2500
+ <dd class="dd2">
2501
+ <p> Whether to print converted Ruby code into log file.
2502
+ If true, Erubis prints coverted code into log file.
2503
+ If false, Erubis doesn't.
2504
+ If nil, Erubis prints when ENV['RAILS_ENV'] == 'development'.
2505
+ Default is nil.
2506
+ </p>
2507
+ </dd>
2508
+ <dt class="dt2">
2509
+ Erubis::Helpers::RailsHelper.preprocessing (=false)</dt>
2510
+ <dd class="dd2">
2511
+ <p> Enable preprocessing if true (default false).
2512
+ </p>
2513
+ </dd>
2514
+ </dl>
2515
+ <br>
2516
+
2517
+
2518
+ <a name="rails-preprocessing"></a>
2519
+ <h3 class="section2">Preprosessing</h3>
2520
+ <p>Erubis supports preprocessing of template files.
2521
+ Preprocessing make your Ruby on Rails application about 20-40 percent faster.
2522
+ To enable preprocessing, set Erubis::Helpers::RailsHelper.preprocessing to true in your 'environment.rb' file.
2523
+ </p>
2524
+ <p>For example, assume the following template.
2525
+ This is slow because link_to() method is called every time when template is rendered.
2526
+ </p>
2527
+ <pre class="program">&lt;%= link_to 'Create', :action=&gt;'create' %&gt;
2528
+ </pre>
2529
+ <p>The following is faster than the above, but not flexible because url is fixed.
2530
+ </p>
2531
+ <pre class="program">&lt;a href="/users/create"&gt;Create&lt;/a&gt;
2532
+ </pre>
2533
+ <p>Preprocessing solves this problem.
2534
+ If you use '[%= %]' instead of '&lt;%= %&gt;', preprocessor evaluate it only once when template is loaded.
2535
+ </p>
2536
+ <pre class="program"><strong>[%= link_to 'Create', :action=&gt;'create'%]</strong>
2537
+ </pre>
2538
+ <p>The above is evaluated by preprocessor and replaced to the following code automatically.
2539
+ </p>
2540
+ <pre class="program">&lt;a href="/users/create"&gt;Create&lt;/a&gt;
2541
+ </pre>
2542
+ <p>Notice that this is done only once when template file is loaded.
2543
+ It means that link_to() method is not called when template is rendered.
2544
+ </p>
2545
+ <p>If link_to() method have variable arguments, use <code>_?()</code> helper method.
2546
+ </p>
2547
+ <pre class="program">&lt;% for user in @users %&gt;
2548
+ [%= link_to <strong>_?('user.name')</strong>, :action=&gt;'show', :id=&gt;<strong>_?('user.id')</strong> %]
2549
+ &lt;% end %&gt;
2550
+ </pre>
2551
+ <p>The above is evaluated by preprocessor when template is loaded and expanded into the following code.
2552
+ This will be much faster because link_to() method is not called when rendering.
2553
+ </p>
2554
+ <pre class="program">&lt;% for user in @users %&gt;
2555
+ &lt;a href="/users/show/<strong>&lt;%=user.id%&gt;</strong>"&gt;<strong>&lt;%=user.name%&gt;</strong>&lt;/a&gt;
2556
+ &lt;% end %&gt;
2557
+ </pre>
2558
+ <p>Preprocessing statement (<code>[% %]</code>) is also available as well as preprocessing expression (<code>[%= %]</code>).
2559
+ </p>
2560
+ <pre class="program">&lt;select name="state"&gt;
2561
+ &lt;option value=""&gt;-&lt;/option&gt;
2562
+ <strong>[% for code in states.keys.sort %]</strong>
2563
+ &lt;option value="<strong>[%= code %]</strong>"&gt;<strong>[%= states[code] %]</strong>&lt;/option&gt;
2564
+ <strong>[% end %]</strong>
2565
+ &lt;/select&gt;
2566
+ </pre>
2567
+ <p>The above will be evaluated by preprocessor and expanded into the following when template is loaded.
2568
+ In the result, rendering speed will be much faster because for-loop is not executed when rendering.
2569
+ </p>
2570
+ <pre class="program">&lt;select name="state"&gt;
2571
+ &lt;option value=""&gt;-&lt;/option&gt;
2572
+ &lt;option value="AK"&gt;Alaska&lt;/option&gt;
2573
+ &lt;option value="AL"&gt;Alabama&lt;/option&gt;
2574
+ &lt;option value="AR"&gt;Arkansas&lt;/option&gt;
2575
+ &lt;option value="AS"&gt;American Samoa&lt;/option&gt;
2576
+ &lt;option value="AZ"&gt;Arizona&lt;/option&gt;
2577
+ &lt;option value="CA"&gt;California&lt;/option&gt;
2578
+ &lt;option value="CO"&gt;Colorado&lt;/option&gt;
2579
+ ....
2580
+ &lt;/select&gt;
2581
+ </pre>
2582
+ <p>Notice that it is not recommended to use preprocessing with tag helpers,
2583
+ because tag helpers generate different html code when form parameter has errors or not.
2584
+ </p>
2585
+ <p>Helper methods of Ruby on Rails are divided into two groups.
2586
+ </p>
2587
+ <ul type="disc">
2588
+ <li>link_to() or _() (method of gettext package) are not need to call for every time
2589
+ as template is rendered because it returns same value when same arguments are passed.
2590
+ These methods can be got faster by preprocessing.
2591
+ </li>
2592
+ <li>Tag helper methods should be called for every time as template is rendered
2593
+ because it may return differrent value even if the same arguments are passed.
2594
+ Preprocessing is not available with these methods.
2595
+ </li>
2596
+ </ul>
2597
+ <p>In Ruby on Rails 2.0, <code>_?('user_id')</code> is OK but <code>_?('user.id')</code> is NG
2598
+ because the latter contains period ('.') character.
2599
+ </p>
2600
+ <pre class="program">&lt;!-- NG in Rails 2.0, because _?('') contains period --&gt;
2601
+ [%= link_to 'Edit', edit_user_path(<strong>_?('@user.id')</strong>) %]
2602
+ [%= link_to 'Show', <strong>@user</strong> %]
2603
+ [%= link_to 'Delete', <strong>@user</strong>, :confirm=&gt;'OK?', :method=&gt;:delete %]
2604
+
2605
+ &lt;!-- OK in Rails 2.0 --&gt;
2606
+ <strong>&lt;%= user_id = @user.id %&gt;</strong>
2607
+ [%= link_to 'Edit', edit_user_path(<strong>_?('user_id')</strong>) %]
2608
+ [%= link_to 'Show', <strong>:action=&gt;'show', :id=&gt;_?('user_id')</strong> %]
2609
+ [%= link_to 'Delete', <strong>{:action=&gt;'destroy', :id=&gt;_?('user_id')}</strong>,
2610
+ {:confirm=&gt;'OK?', :method=&gt;:delete} %]
2611
+ </pre>
2612
+ <br>
2613
+
2614
+
2615
+ <a name="rails-formhelpers"></a>
2616
+ <h3 class="section2">Form Helpers for Preprocessing</h3>
2617
+ <p><strong>(Experimental)</strong>
2618
+ </p>
2619
+ <p>Erubis provides form helper methods for preprocessing.
2620
+ These are defined in 'erubis/helpers/rails_form_helper.rb'.
2621
+ If you want to use it, require it and include Erubis::Helpers::RailsFormHelper in 'app/helpers/applition_helper.rb'
2622
+ </p>
2623
+ <div class="program_caption">
2624
+ app/helpers/xxx_helper.rb</div>
2625
+ <pre class="program">require 'erubis/helpers/rails_form_helper'
2626
+ module ApplicationHelper
2627
+ include Erubis::Helpers::RailsFormHelper
2628
+ end
2629
+ </pre>
2630
+ <p>Form helper methods defined in Erubis::Helpers::RailsFormHelper are named as 'pp_xxxx'
2631
+ ('pp' represents preprocessing).
2632
+ </p>
2633
+ <p>Assume the following view template:
2634
+ </p>
2635
+ <div class="program_caption">
2636
+ _form.rhtml</div>
2637
+ <pre class="program"> &lt;p&gt;
2638
+ Name: &lt;%= text_field :user, :name %&gt;
2639
+ &lt;/p&gt;
2640
+ &lt;p&gt;
2641
+ Name: <strong>[%= pp_text_field :user, :name %]</strong>
2642
+ &lt;/p&gt;
2643
+ </pre>
2644
+ <p>Erubis preprocessor converts it to the following eRuby string:
2645
+ </p>
2646
+ <div class="program_caption">
2647
+ preprocessed</div>
2648
+ <pre class="program"> &lt;p&gt;
2649
+ Name: &lt;%= text_field :user, :name %&gt;
2650
+ &lt;/p&gt;
2651
+ &lt;p&gt;
2652
+ Name: <strong>&lt;input id="stock_name" name="stock[name]" size="30" type="text" value="&lt;%=h @stock.name%&gt;" /&gt;</strong>
2653
+ &lt;/p&gt;
2654
+ </pre>
2655
+ <p>Erubis converts it to the following Ruby code:
2656
+ </p>
2657
+ <div class="program_caption">
2658
+ Ruby code</div>
2659
+ <pre class="program"> _buf &lt;&lt; ' &lt;p&gt;
2660
+ Name: '; _buf &lt;&lt; ( text_field :stock, :name ).to_s; _buf &lt;&lt; '
2661
+ '; _buf &lt;&lt; ' &lt;/p&gt;
2662
+ &lt;p&gt;
2663
+ Name: &lt;input id="stock_name" name="stock[name]" size="30" type="text" value="'; _buf &lt;&lt; (h @stock.name).to_s; _buf &lt;&lt; '" /&gt;
2664
+ &lt;/p&gt;
2665
+ ';
2666
+ </pre>
2667
+ <p>The above Ruby code shows that text_field() is called everytime when rendering,
2668
+ but pp_text_field() is called only once when template is loaded.
2669
+ This means that pp_text_field() with preprocessing makes view layer very fast.
2670
+ </p>
2671
+ <p>Module Erubis::Helpers::RailsFormHelper defines the following form helper methods.
2672
+ </p>
2673
+ <ul type="disc">
2674
+ <li>pp_render_partial(basename)
2675
+ </li>
2676
+ <li>pp_form_tag(url_for_options={}, options={}, *parameters_for_url, &amp;block)
2677
+ </li>
2678
+ <li>pp_text_field(object_name, method, options={})
2679
+ </li>
2680
+ <li>pp_password_field(object_name, method, options={})
2681
+ </li>
2682
+ <li>pp_hidden_field(object_name, method, options={})
2683
+ </li>
2684
+ <li>pp_file_field(object_name, method, options={})
2685
+ </li>
2686
+ <li>pp_text_area(object_name, method, options={})
2687
+ </li>
2688
+ <li>pp_check_box(object_name, method, options={}, checked_value="1", unchecked_value="0")
2689
+ </li>
2690
+ <li>pp_radio_button(object_name, method, tag_value, options={})
2691
+ </li>
2692
+ <li>pp_select(object, method, collection, options={}, html_options={})
2693
+ </li>
2694
+ <li>pp_collection_select(object, method, collection, value_method, text_method, options={}, html_options={})
2695
+ </li>
2696
+ <li>pp_country_select(object, method, priority_countries=nil, options={}, html_options={})
2697
+ </li>
2698
+ <li>pp_time_zone_select(object, method, priority_zones=nil, options={}, html_options={})
2699
+ </li>
2700
+ <li>pp_submit_tag(value="Save changes", options={})
2701
+ </li>
2702
+ <li>pp_image_submit_tag(source, options={})
2703
+ </li>
2704
+ </ul>
2705
+ <p>Notice that pp_form_for() is not provided.
2706
+ </p>
2707
+ <p><span style="color:#FF0000">CAUTION:</span> These are experimental and may not work in Ruby on Rails 2.0.
2708
+ </p>
2709
+ <br>
2710
+
2711
+
2712
+ <a name="rails-others"></a>
2713
+ <h3 class="section2">Others</h3>
2714
+ <ul type="disc">
2715
+ <li>ActionView::Helpers::CaptureHelper#capture() and ActionView::Helpers::Texthelper#concat() are available.
2716
+ </li>
2717
+ </ul>
2718
+ <ul type="disc">
2719
+ <li>Form helper methods are not tested in Ruby on Rails 2.0.
2720
+ </li>
2721
+ </ul>
2722
+ <ul type="disc">
2723
+ <li>ERB::Util.h() is redefined if you require 'erubis/helpers/rails_helper.rb'.
2724
+ Original definition of ERB::Util.h() is the following and it is slow
2725
+ because it scans string four times.
2726
+ <pre class="program"> def html_escape(s)
2727
+ s.to_s.gsub(/&amp;/, "&amp;amp;").gsub(/\"/, "&amp;quot;").gsub(/&gt;/, "&amp;gt;").gsub(/&lt;/, "&amp;lt;")
2728
+ end
2729
+ alias h html_escape
2730
+ </pre>
2731
+ <p> New definition in 'erubis/helpers/rails_helper.rb' is faster than the above
2732
+ because it scans string only once.
2733
+ </p>
2734
+ <pre class="program"> ESCAPE_TABLE = { '&amp;'=&gt;'&amp;amp;', '&lt;'=&gt;'&amp;lt;', '&gt;'=&gt;'&amp;gt;', '"'=&gt;'&amp;quot;', "'"=&gt;'&amp;#039;', }
2735
+ def h(value)
2736
+ value.to_s.gsub(/[&amp;&lt;&gt;"]/) { |s| ESCAPE_TABLE[s] }
2737
+ end
2738
+ </pre>
2739
+ <p> Notice that the new definition may be slow if string contains
2740
+ many '&lt; &gt; &amp; "' characters because block is call many time.
2741
+ You should use ERB::Util.html_hscape() if string contains a lot of '&lt; &gt; &amp; "'
2742
+ characters.
2743
+ </p>
2744
+ </li>
2745
+ </ul>
2278
2746
  <br>
2279
2747
 
2280
2748
 
@@ -2283,6 +2751,237 @@ document.write(_buf.join(""));
2283
2751
 
2284
2752
  <a name="topics"></a>
2285
2753
  <h2 class="section1">Other Topics</h2>
2754
+ <a name="topics-fasteruby"></a>
2755
+ <h3 class="section2"><code>Erubis::FastEruby</code> Class</h3>
2756
+ <p><code>Erubis::FastEruby</code> class generates more effective code than <code>Erubis::Eruby</code>.
2757
+ </p>
2758
+ <a name="fasteruby-example.rb"></a>
2759
+ <div class="program_caption">
2760
+ fasteruby-example.rb</div>
2761
+ <pre class="program">require 'erubis'
2762
+ input = File.read('example.eruby')
2763
+
2764
+ puts "----- Erubis::Eruby -----"
2765
+ print Erubis::Eruby.new(input).src
2766
+
2767
+ puts "----- Erubis::FastEruby -----"
2768
+ print <strong>Erubis::FastEruby</strong>.new(input).src
2769
+ </pre>
2770
+ <a name="fasteruby-example.result"></a>
2771
+ <div class="terminal_caption">
2772
+ result</div>
2773
+ <pre class="terminal">$ ruby fasteruby-example.rb
2774
+ ----- Erubis::Eruby -----
2775
+ _buf = ''; _buf &lt;&lt; '&lt;div&gt;
2776
+ '; for item in list
2777
+ _buf &lt;&lt; ' &lt;p&gt;'; <strong>_buf &lt;&lt; ( item ).to_s;</strong> _buf &lt;&lt; '&lt;/p&gt;
2778
+ &lt;p&gt;'; <strong>_buf &lt;&lt; Erubis::XmlHelper.escape_xml( item );</strong> _buf &lt;&lt; '&lt;/p&gt;
2779
+ '; end
2780
+ _buf &lt;&lt; '&lt;/div&gt;
2781
+ ';
2782
+ _buf.to_s
2783
+ ----- Erubis::FastEruby -----
2784
+ _buf = ''; _buf &lt;&lt; %Q`&lt;div&gt;\n`
2785
+ for item in list
2786
+ _buf &lt;&lt; %Q` &lt;p&gt;<strong>#{ item }</strong>&lt;/p&gt;
2787
+ &lt;p&gt;<strong>#{Erubis::XmlHelper.escape_xml( item )}</strong>&lt;/p&gt;\n`
2788
+ end
2789
+ _buf &lt;&lt; %Q`&lt;/div&gt;\n`
2790
+ _buf.to_s
2791
+ </pre>
2792
+ <p>Technically, <code>Erubis::FastEruby</code> is just a subclass of <code>Erubis::Eruby</code> and includes <code><a href="#interpolation-enhancer">InterpolationEnhancer</a></code>. <code>Erubis::FastEruby</code> is faster than <code>Erubis::Eruby</code> but is not extensible compared to <code>Erubis::Eruby</code>. This is the reason why <code>Erubis::FastEruby</code> is not the default class of Erubis.
2793
+ </p>
2794
+ <br>
2795
+
2796
+
2797
+ <a name="topics-bufvar"></a>
2798
+ <h3 class="section2"><code>:bufvar</code> Option</h3>
2799
+ <p>Since 2.7.0, Erubis supports <code>:bufvar</code> option which allows you to change buffer variable name (default '<code>_buf</code>').
2800
+ </p>
2801
+ <a name="bufvar-example.rb"></a>
2802
+ <div class="program_caption">
2803
+ bufvar-example.rb</div>
2804
+ <pre class="program">require 'erubis'
2805
+ input = File.read('example.eruby')
2806
+
2807
+ puts "----- default -----"
2808
+ eruby = Erubis::FastEruby.new(input)
2809
+ puts eruby.src
2810
+
2811
+ puts "----- with :bufvar option -----"
2812
+ eruby = Erubis::FastEruby.new(input, <strong>:bufvar=&gt;'@_out_buf'</strong>)
2813
+ print eruby.src
2814
+ </pre>
2815
+ <a name="bufvar-example.result"></a>
2816
+ <div class="terminal_caption">
2817
+ result</div>
2818
+ <pre class="terminal">$ ruby bufvar-example.rb
2819
+ ----- default -----
2820
+ _buf = ''; _buf &lt;&lt; %Q`&lt;div&gt;\n`
2821
+ for item in list
2822
+ _buf &lt;&lt; %Q` &lt;p&gt;#{ item }&lt;/p&gt;
2823
+ &lt;p&gt;#{Erubis::XmlHelper.escape_xml( item )}&lt;/p&gt;\n`
2824
+ end
2825
+ _buf &lt;&lt; %Q`&lt;/div&gt;\n`
2826
+ _buf.to_s
2827
+ ----- with :bufvar option -----
2828
+ <strong>@_out_buf</strong> = ''; <strong>@_out_buf</strong> &lt;&lt; %Q`&lt;div&gt;\n`
2829
+ for item in list
2830
+ <strong>@_out_buf</strong> &lt;&lt; %Q` &lt;p&gt;#{ item }&lt;/p&gt;
2831
+ &lt;p&gt;#{Erubis::XmlHelper.escape_xml( item )}&lt;/p&gt;\n`
2832
+ end
2833
+ <strong>@_out_buf</strong> &lt;&lt; %Q`&lt;/div&gt;\n`
2834
+ <strong>@_out_buf</strong>.to_s
2835
+ </pre>
2836
+ <br>
2837
+
2838
+
2839
+ <a name="topics-trimspaces"></a>
2840
+ <h3 class="section2">'&lt;%= =%&gt;' and '&lt;%= -%&gt;'</h3>
2841
+ <p>Since 2.6.0, '&lt;%= -%&gt;' remove tail spaces and newline.
2842
+ This is for compatibiliy with ERB when trim mode is '-'.
2843
+ '&lt;%= =%&gt;' also removes tail spaces and newlines, and this is
2844
+ Erubis-original enhancement (cooler than '&lt;%= -%&gt;', isn't it?).
2845
+ </p>
2846
+ <a name="tailnewline.rhtml.comment_filter"></a>
2847
+ <div class="program_caption">
2848
+ tailnewline.rhtml</div>
2849
+ <pre class="program">&lt;div&gt;
2850
+ &lt;%= @var -%&gt; # or &lt;%= @var =%&gt;
2851
+ &lt;/div&gt;
2852
+ </pre>
2853
+ <div class="terminal_caption">
2854
+ result (version 2.5.0):</div>
2855
+ <pre class="terminal">$ erubis -c '{var: "AAA\n"}' tailnewline.rhtml
2856
+ &lt;div&gt;
2857
+ AAA
2858
+
2859
+ &lt;/div&gt;
2860
+ </pre>
2861
+ <a name="tail_260.result"></a>
2862
+ <div class="terminal_caption">
2863
+ result (version 2.6.0):</div>
2864
+ <pre class="terminal">$ erubis -c '{var: "AAA\n"}' tailnewline.rhtml
2865
+ &lt;div&gt;
2866
+ AAA
2867
+ &lt;/div&gt;
2868
+ </pre>
2869
+ <br>
2870
+
2871
+
2872
+ <a name="topics-doublepercent"></a>
2873
+ <h3 class="section2">'&lt;%% %&gt;' and '&lt;%%= %&gt;'</h3>
2874
+ <p>Since 2.6.0, '&lt;%% %&gt;' and '&lt;%%= %&gt;' are converted into '&lt;% %&gt;' and '&lt;%= %&gt;' respectively.
2875
+ This is for compatibility with ERB.
2876
+ </p>
2877
+ <div class="program_caption">
2878
+ doublepercent.rhtml:</div>
2879
+ <pre class="program">&lt;ul&gt;
2880
+ &lt;%% for item in @list %&gt;
2881
+ &lt;li&gt;&lt;%%= item %&gt;&lt;/li&gt;
2882
+ &lt;%% end %&gt;
2883
+ &lt;/ul&gt;
2884
+ </pre>
2885
+ <div class="terminal_caption">
2886
+ result:</div>
2887
+ <pre class="terminal">$ erubis doublepercent.rhtml
2888
+ &lt;ul&gt;
2889
+ &lt;% for item in @list %&gt;
2890
+ &lt;li&gt;&lt;%= item %&gt;&lt;/li&gt;
2891
+ &lt;% end %&gt;
2892
+ &lt;/ul&gt;
2893
+ </pre>
2894
+ <br>
2895
+
2896
+
2897
+ <a name="topics-context-vs-binding"></a>
2898
+ <h3 class="section2">evaluate(context) v.s. result(binding)</h3>
2899
+ <p>It is recommended to use 'Erubis::Eruby#evaluate(context)' instead of 'Erubis::Eruby#result(binding)' because Ruby's Binding object has some problems.
2900
+ </p>
2901
+ <ul type="disc">
2902
+ <li>It is not able to specify variables to use.
2903
+ Using binding() method, all of local variables are passed to templates.
2904
+ </li>
2905
+ <li>Changing local variables in templates may affect to varialbes in main program.
2906
+ If you assign '10' to local variable 'x' in templates, it may change variable 'x' in main program unintendedly.
2907
+ </li>
2908
+ </ul>
2909
+ <p>The following example shows that assignment of some values into variable 'x' in templates affect to local variable 'x' in main program unintendedly.
2910
+ </p>
2911
+ <a name="template1.rhtml"></a>
2912
+ <div class="program_caption">
2913
+ template1.rhtml (intended to be passed 'items' from main program)</div>
2914
+ <pre class="program">&lt;% for <strong>x</strong> in <strong>items</strong> %&gt;
2915
+ item = &lt;%= x %&gt;
2916
+ &lt;% end %&gt;
2917
+ ** debug: local variables=&lt;%= local_variables().inspect() %&gt;
2918
+ </pre>
2919
+ <a name="main_program1.rb"></a>
2920
+ <div class="program_caption">
2921
+ main_program1.rb (intended to pass 'items' to template)</div>
2922
+ <pre class="program">require 'erubis'
2923
+ eruby = Erubis::Eruby.new(File.read('template1.rhtml'))
2924
+ items = ['foo', 'bar', 'baz']
2925
+ x = 1
2926
+ ## local variable 'x' and 'eruby' are passed to template as well as 'items'!
2927
+ print <strong>eruby.result(binding())</strong>
2928
+ ## local variable 'x' is changed unintendedly because it is changed in template!
2929
+ puts "** debug: x=#{x.inspect}" #=&gt; "baz"
2930
+ </pre>
2931
+ <a name="main_program1.result"></a>
2932
+ <div class="terminal_caption">
2933
+ Result:</div>
2934
+ <pre class="terminal">$ ruby main_program1.rb
2935
+ item = foo
2936
+ item = bar
2937
+ item = baz
2938
+ ** debug: local variables=["eruby", "items", "x", "_buf"]
2939
+ ** debug: x="baz"
2940
+ </pre>
2941
+ <p>This problem is caused because Ruby's Binding class is poor to use in template engine.
2942
+ Binding class should support the following features.
2943
+ </p>
2944
+ <pre class="program">b = Binding.new # create empty Binding object
2945
+ b['x'] = 1 # set local variables using binding object
2946
+ </pre>
2947
+ <p>But the above features are not implemented in Ruby.
2948
+ </p>
2949
+ <p>A pragmatic solution is to use 'Erubis::Eruby#evaluate(context)' instead of 'Erubis::Eruby#result(binding)'.
2950
+ 'evaluate(context)' uses Erubis::Context object and instance variables instead of Binding object and local variables.
2951
+ </p>
2952
+ <a name="template2.rhtml"></a>
2953
+ <div class="program_caption">
2954
+ template2.rhtml (intended to be passed '@items' from main program)</div>
2955
+ <pre class="program">&lt;% for <strong>x</strong> in <strong>@items</strong> %&gt;
2956
+ item = &lt;%= x %&gt;
2957
+ &lt;% end %&gt;
2958
+ ** debug: local variables=&lt;%= local_variables().inspect() %&gt;
2959
+ </pre>
2960
+ <a name="main_program2.rb"></a>
2961
+ <div class="program_caption">
2962
+ main_program2.rb (intended to pass '@items' to template)</div>
2963
+ <pre class="program">require 'erubis'
2964
+ eruby = Erubis::Eruby.new(File.read('template2.rhtml'))
2965
+ items = ['foo', 'bar', 'baz']
2966
+ x = 1
2967
+ ## only 'items' are passed to template
2968
+ print <strong>eruby.evaluate(:items=&gt;items)</strong>
2969
+ ## local variable 'x' is not changed!
2970
+ puts "** debug: x=#{x.inspect}" #=&gt; 1
2971
+ </pre>
2972
+ <a name="main_program2.result"></a>
2973
+ <div class="terminal_caption">
2974
+ Result:</div>
2975
+ <pre class="terminal">$ ruby main_program2.rb
2976
+ item = foo
2977
+ item = bar
2978
+ item = baz
2979
+ ** debug: local variables=["_context", "x", "_buf"]
2980
+ ** debug: x=1
2981
+ </pre>
2982
+ <br>
2983
+
2984
+
2286
2985
  <a name="topics-fasteruby"></a>
2287
2986
  <h3 class="section2">Class Erubis::FastEruby</h3>
2288
2987
  <p>[experimental]
@@ -2397,6 +3096,13 @@ if test(?f, cachename)
2397
3096
  puts "*** cache file '#{cachename}' created."
2398
3097
  end
2399
3098
  </pre>
3099
+ <p>Since 2.6.0, it is able to specify cache filename.
3100
+ </p>
3101
+ <div class="program_caption">
3102
+ specify cache filename.</div>
3103
+ <pre class="program">filename = 'example.rhtml'
3104
+ eruby = Erubis::Eruby.load_file(filename, :cachename=&gt;filename+'.cache')
3105
+ </pre>
2400
3106
  <p>Caching makes Erubis about 40-50 percent faster than no-caching.
2401
3107
  See <a href="#topics-benchmark">benchmark</a> for details.
2402
3108
  </p>
@@ -2412,73 +3118,6 @@ try Erubis::TinyEruby class.
2412
3118
  <br>
2413
3119
 
2414
3120
 
2415
- <a name="topics-rails"></a>
2416
- <h3 class="section2">Ruby on Rails Support</h3>
2417
- <p>Erubis supports Ruby on Rails.
2418
- </p>
2419
- <ol type="1">
2420
- <li>Add the following code to your 'config/environment.rb'.
2421
- <div class="program_caption">
2422
- config/environment.rb</div>
2423
- <pre class="program">require 'erubis/helpers/rails_helper'
2424
- #Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby # or Erubis::FastEruby
2425
- #Erubis::Helpers::RailsHelper.init_properties = {}
2426
- #Erubis::Helpers::RailsHelper.show_src = false
2427
- </pre>
2428
- <p> This will replace ERB in Rails by Erubis entirely.
2429
- </p>
2430
- </li>
2431
- <li>(Optional) apply the following patch to 'action_pack/lib/action_view/base.rb'.
2432
- <div class="program_caption">
2433
- action_view_base_rb.patch</div>
2434
- <pre class="program">--- lib/action_view/base.rb (original)
2435
- +++ lib/action_view/base.rb (working copy)
2436
- @@ -445,6 +445,11 @@
2437
- end
2438
- end
2439
-
2440
- + # convert template into ruby code
2441
- + def convert_template_into_ruby_code(template)
2442
- + ERB.new(template, nil, @@erb_trim_mode).src
2443
- + end
2444
- +
2445
- # Create source code for given template
2446
- def create_template_source(extension, template, render_symbol, locals)
2447
- if template_requires_setup?(extension)
2448
- @@ -458,7 +463,7 @@
2449
- "update_page do |page|\n#{template}\nend"
2450
- end
2451
- else
2452
- - body = ERB.new(template, nil, @@erb_trim_mode).src
2453
- + body = convert_template_into_ruby_code(template)
2454
- end
2455
-
2456
- @@template_args[render_symbol] ||= {}
2457
- </pre>
2458
- <p> This patch is included in erubis_2.X.X/contrib directory and the following is an
2459
- example to apply this patch.
2460
- </p>
2461
- <div class="terminal_caption">
2462
- how to apply patch:</div>
2463
- <pre class="terminal">$ cd /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/action_view/
2464
- $ sudo patch -p1 &lt; /tmp/erubis_2.X.X/contrib/action_view_base_rb.patch
2465
- </pre>
2466
- <p> Notice that this patch is not necessary if you are using Ruby on Rails ver 1.1 or 1.2, but it is recommended.
2467
- </p>
2468
- </li>
2469
- <li>Restart web server.
2470
- <pre class="terminal">$ ruby script/server
2471
- </pre>
2472
- </li>
2473
- </ol>
2474
- <p>ActionView::Helpers::CaptureHelper#capture() and ActionView::Helpers::Texthelper#concat() are available.
2475
- </p>
2476
- <p>If Erubis::Helper::Rails.show_src is ture, Erubis prints converted Ruby code into log file (ex. 'log/development.log').
2477
- It is useful for debugging.
2478
- </p>
2479
- <br>
2480
-
2481
-
2482
3121
  <a name="topics-php"></a>
2483
3122
  <h3 class="section2">NoTextEnhancer and NoCodeEnhancer in PHP</h3>
2484
3123
  <p>NoTextEnhancer and NoCodEnahncer are quite useful not only for eRuby but also for PHP.
@@ -2571,8 +3210,8 @@ example of using NoCodeEnhancer with PHP file</div>
2571
3210
  <p>Thanks Andrew R Jackson, he developed 'erubis-run.rb' which enables you to use Erubis with mod_ruby.
2572
3211
  </p>
2573
3212
  <ol type="1">
2574
- <li>Copy 'erubis-2.3.1/contrib/erubis-run.rb' to the 'RUBYLIBDIR/apache' directory (for example '/usr/local/lib/ruby/1.8/apache') which contains 'ruby-run.rb', 'eruby-run.rb', and so on.
2575
- <pre class="terminal">$ cd erubis-2.3.1/
3213
+ <li>Copy 'erubis-2.7.0/contrib/erubis-run.rb' to the 'RUBYLIBDIR/apache' directory (for example '/usr/local/lib/ruby/1.8/apache') which contains 'ruby-run.rb', 'eruby-run.rb', and so on.
3214
+ <pre class="terminal">$ cd erubis-2.7.0/
2576
3215
  $ sudo copy contrib/erubis-run.rb /usr/local/lib/ruby/1.8/apache/
2577
3216
  </pre>
2578
3217
  </li>
@@ -2618,19 +3257,84 @@ $ sudo chmod 775 .
2618
3257
  </ol>
2619
3258
  <p>You must set your directories to be writable by web server process, because
2620
3259
  Apache::ErubisRun calls Erubis::Eruby.load_file() internally which creates cache files
2621
- in the same directory as '*.rhtml' file.
3260
+ in the same directory in which '*.rhtml' file exists.
3261
+ </p>
3262
+ <br>
3263
+
3264
+
3265
+ <a name="topics-index-cgi"></a>
3266
+ <h3 class="section2">Helper CGI Script for Apache</h3>
3267
+ <p>Erubis provides helper CGI script for Apache.
3268
+ Using this script, it is very easy to publish *.rhtml files as *.html.
3269
+ </p>
3270
+ <pre class="terminal">### install Erubis
3271
+ $ tar xzf erubis-X.X.X.tar.gz
3272
+ $ cd erubis-X.X.X/
3273
+ $ ruby setup.py install
3274
+ ### copy files to ~/public_html
3275
+ $ mkdir -p ~/public_html
3276
+ $ cp public_html/_htaccess ~/public_html/.htaccess
3277
+ $ cp public_html/index.cgi ~/public_html/
3278
+ $ cp public_html/index.rhtml ~/public_html/
3279
+ ### add executable permission to index.cgi
3280
+ $ chmod a+x ~/public_html/index.cgi
3281
+ ### edit .htaccess
3282
+ $ vi ~/public_html/.htaccess
3283
+ ### (optional) edit index.cgi to configure
3284
+ $ vi ~/public_html/index.cgi
3285
+ </pre>
3286
+ <p>Edit ~/public_html/.htaccess and modify user name.
3287
+ </p>
3288
+ <div class="program_caption">
3289
+ ~/public_html/.htaccess</div>
3290
+ <pre class="program">## enable mod_rewrie
3291
+ RewriteEngine on
3292
+ ## deny access to *.rhtml and *.cache
3293
+ #RewriteRule \.(rhtml|cache)$ - [R=404,L]
3294
+ RewriteRule \.(rhtml|cache)$ - [F,L]
3295
+ ## rewrite only if requested file is not found
3296
+ RewriteCond %{SCRIPT_FILENAME} !-f
3297
+ ## handle request to *.html and directories by index.cgi
3298
+ RewriteRule (\.html|/|^)$ /~<strong>username</strong>/index.cgi
3299
+ #RewriteRule (\.html|/|^)$ index.cgi
3300
+ </pre>
3301
+ <p>After these steps, *.rhtml will be published as *.html.
3302
+ For example, if you access to <code>http://<em>host</em>.<em>domain</em>/~<em>username</em>/index.html</code> (or <code>http://<em>host</em>.<em>domain</em>/~<em>username</em>/</code>), file <code>~/public_html/index.rhtml</code> will be displayed.
2622
3303
  </p>
2623
3304
  <br>
2624
3305
 
2625
3306
 
3307
+ <a name="topics-defmethod"></a>
3308
+ <h3 class="section2">Define method</h3>
3309
+ <p>Erubis::Eruby#def_method() defines instance method or singleton method.
3310
+ </p>
3311
+ <a name="def_method.rb"></a>
3312
+ <pre class="program">require 'erubis'
3313
+ s = "hello &lt;%= name %&gt;"
3314
+ eruby = Erubis::Eruby.new(s)
3315
+ filename = 'hello.rhtml'
3316
+
3317
+ ## define instance method to Dummy class (or module)
3318
+ class Dummy; end
3319
+ <strong>eruby.def_method(Dummy, 'render(name)', filename)</strong> # filename is optional
3320
+ p Dummy.new.render('world') #=&gt; "hello world"
3321
+
3322
+ ## define singleton method to dummy object
3323
+ obj = Object.new
3324
+ <strong>eruby.def_method(obj, 'render(name)', filename)</strong> # filename is optional
3325
+ p obj.render('world') #=&gt; "hello world"
3326
+ </pre>
3327
+ <br>
3328
+
3329
+
2626
3330
  <a name="topics-benchmark"></a>
2627
3331
  <h3 class="section2">Benchmark</h3>
2628
- <p>A benchmark script is included in Erubis package at 'erubis-2.3.1/benchark/' directory.
3332
+ <p>A benchmark script is included in Erubis package at 'erubis-2.7.0/benchark/' directory.
2629
3333
  Here is an example result of benchmark.
2630
3334
  </p>
2631
3335
  <div class="terminal_caption">
2632
3336
  MacOS X 10.4 Tiger, Intel CoreDuo 1.83GHz, Ruby1.8.6, eruby1.0.5, gcc4.0.1</div>
2633
- <pre class="terminal">$ cd erubis-2.3.1/benchmark/
3337
+ <pre class="terminal">$ cd erubis-2.7.0/benchmark/
2634
3338
  $ ruby bench.rb -n 10000 -m execute
2635
3339
  *** ntimes=10000, testmode=execute
2636
3340
  user system total real