a5e08f7bcc
I installed the rails_xss plugin, for the main purpose of seeing what will break with Rails 3.0 (where the behaviour of the plugin is the default). I think I've fixed everything, but let me know if you see stuff that is HTML-escaped, which shouldn't be. As a side benefit, we now use Erubis, rather than ERB, to render templates. They tell me it's faster ...
3286 lines
101 KiB
HTML
3286 lines
101 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html">
|
|
<title>Erubis Users' Guide</title>
|
|
<meta name="generator" content="kwaser">
|
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
|
<link rel="stylesheet" href="docstyle.css" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<blockquote>
|
|
<div class="mainbody">
|
|
|
|
<div align="left"><h1>Erubis Users' Guide</h1></div>
|
|
<div align="left">
|
|
last update: $Date$<br>
|
|
</div>
|
|
|
|
<p>release: 2.6.5
|
|
</p>
|
|
<a name="preface"></a>
|
|
<h2 class="section1">Preface</h2>
|
|
<p>Erubis is an implementation of eRuby.
|
|
It has the following features.
|
|
</p>
|
|
<ul type="disc">
|
|
<li>Very fast, almost three times faster than ERB and about ten percent faster than eruby (implemented in C)
|
|
</li>
|
|
<li>File caching of converted Ruby script support
|
|
</li>
|
|
<li>Auto escaping support
|
|
</li>
|
|
<li>Auto trimming spaces around '<% %>'
|
|
</li>
|
|
<li>Embedded pattern changeable (default '<% %>')
|
|
</li>
|
|
<li>Enable to handle Processing Instructions (PI) as embedded pattern (ex. '<?rb ... ?>')
|
|
</li>
|
|
<li>Multi-language support (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
|
|
</li>
|
|
<li>Context object available and easy to combine eRuby template with YAML datafile
|
|
</li>
|
|
<li>Print statement available
|
|
</li>
|
|
<li>Easy to expand and customize in subclass
|
|
</li>
|
|
<li><a href="#rails">Ruby on Rails support</a>
|
|
</li>
|
|
<li>mod_ruby support|#topcs-modruby
|
|
</li>
|
|
</ul>
|
|
<p>Erubis is implemented in pure Ruby. It requires Ruby 1.8 or higher.
|
|
Erubis now supports Ruby 1.9.
|
|
</p>
|
|
<a name="toc"></a>
|
|
<h3 class="section2">Table of Contents</h3>
|
|
<ul>
|
|
<li><a href="#preface">Preface</a>
|
|
<ul>
|
|
<li><a href="#toc">Table of Contents</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#install">Installation</a>
|
|
</li>
|
|
<li><a href="#tutorial">Tutorial</a>
|
|
<ul>
|
|
<li><a href="#tut-basic">Basic Example</a>
|
|
</li>
|
|
<li><a href="#tut-trim">Trimming Spaces</a>
|
|
</li>
|
|
<li><a href="#tut-escape">Escape</a>
|
|
</li>
|
|
<li><a href="#tut-pattern">Embedded Pattern</a>
|
|
</li>
|
|
<li><a href="#tut-context">Context Object</a>
|
|
</li>
|
|
<li><a href="#tut-datafile">Context Data File</a>
|
|
</li>
|
|
<li><a href="#tut-datastr">Context Data String</a>
|
|
</li>
|
|
<li><a href="#tut-preamble">Preamble and Postamble</a>
|
|
</li>
|
|
<li><a href="#tut-pi">Processing Instruction (PI) Converter</a>
|
|
</li>
|
|
<li><a href="#tut-notext">Retrieve Ruby Code</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#enhancer">Enhancer</a>
|
|
<ul>
|
|
<li><a href="#escape-enhancer">EscapeEnhancer</a>
|
|
</li>
|
|
<li><a href="#stdout-enhancer">StdoutEnhancer</a>
|
|
</li>
|
|
<li><a href="#printout-enhancer">PrintOutEnhancer</a>
|
|
</li>
|
|
<li><a href="#printenabled-enhancer">PrintEnabledEnhancer</a>
|
|
</li>
|
|
<li><a href="#array-enhancer">ArrayEnhancer</a>
|
|
</li>
|
|
<li><a href="#arraybuffer-enhancer">ArrayBufferEnhancer</a>
|
|
</li>
|
|
<li><a href="#stringbuffer-enhancer">StringBufferEnhancer</a>
|
|
</li>
|
|
<li><a href="#erbout-enhancer">ErboutEnhancer</a>
|
|
</li>
|
|
<li><a href="#notext-enhancer">NoTextEnhancer</a>
|
|
</li>
|
|
<li><a href="#nocode-enhancer">NoCodeEnhancer</a>
|
|
</li>
|
|
<li><a href="#simplify-enhancer">SimplifyEnhancer</a>
|
|
</li>
|
|
<li><a href="#bipattern-enhancer">BiPatternEnhancer</a>
|
|
</li>
|
|
<li><a href="#percentline-enhancer">PercentLineEnhancer</a>
|
|
</li>
|
|
<li><a href="#headerfooter-enhancer">HeaderFooterEnhancer</a>
|
|
</li>
|
|
<li><a href="#interpolation-enhancer">InterpolationEnhancer</a>
|
|
</li>
|
|
<li><a href="#deleteindent-enhancer">DeleteIndentEnhancer</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#lang">Multi-Language Support</a>
|
|
<ul>
|
|
<li><a href="#lang-php">PHP</a>
|
|
</li>
|
|
<li><a href="#lang-c">C</a>
|
|
</li>
|
|
<li><a href="#lang-java">Java</a>
|
|
</li>
|
|
<li><a href="#lang-scheme">Scheme</a>
|
|
</li>
|
|
<li><a href="#lang-perl">Perl</a>
|
|
</li>
|
|
<li><a href="#lang-javascript">JavaScript</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#rails">Ruby on Rails Support</a>
|
|
<ul>
|
|
<li><a href="#rails-settings">Settings</a>
|
|
</li>
|
|
<li><a href="#rails-preprocessing">Preprosessing</a>
|
|
</li>
|
|
<li><a href="#rails-formhelpers">Form Helpers for Preprocessing</a>
|
|
</li>
|
|
<li><a href="#rails-others">Others</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#topics">Other Topics</a>
|
|
<ul>
|
|
<li><a href="#'<%= =%>' and '<%= -%>'">'<%= =%>' and '<%= -%>'</a>
|
|
</li>
|
|
<li><a href="#'<%% %>' and '<%%= %>'">'<%% %>' and '<%%= %>'</a>
|
|
</li>
|
|
<li><a href="#topics-context-vs-binding">evaluate(context) v.s. result(binding)</a>
|
|
</li>
|
|
<li><a href="#topics-fasteruby">Class Erubis::FastEruby</a>
|
|
</li>
|
|
<li><a href="#topics-syntax">Syntax Checking</a>
|
|
</li>
|
|
<li><a href="#topics-caching">File Caching</a>
|
|
</li>
|
|
<li><a href="#topics-tinyeruby">Erubis::TinyEruby class</a>
|
|
</li>
|
|
<li><a href="#topics-php">NoTextEnhancer and NoCodeEnhancer in PHP</a>
|
|
</li>
|
|
<li><a href="#topcs-modruby">Helper Class for mod_ruby</a>
|
|
</li>
|
|
<li><a href="#topics-defmethod">Define method</a>
|
|
</li>
|
|
<li><a href="#topics-benchmark">Benchmark</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#command">Command Reference</a>
|
|
<ul>
|
|
<li><a href="#command-usage">Usage</a>
|
|
</li>
|
|
<li><a href="#command-options">Options</a>
|
|
</li>
|
|
<li><a href="#command-props">Properties</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="install"></a>
|
|
<h2 class="section1">Installation</h2>
|
|
<ul type="disc">
|
|
<li>If you have installed RubyGems, just type <code>gem install --remote erubis</code>.
|
|
<pre class="terminal">$ sudo gem install --remote erubis
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
<ul type="disc">
|
|
<li>Else install <a href="http://rubyforge.org/projects/erubis/">abstract</a> at first,
|
|
and download erubis_X.X.X.tar.bz2 and install it by setup.rb.
|
|
<pre class="terminal">$ tar xjf abstract_X.X.X.tar.bz2
|
|
$ cd abstract_X.X.X/
|
|
$ sudo ruby setup.rb
|
|
$ cd ..
|
|
$ tar xjf erubis_X.X.X.tar.bz2
|
|
$ cd erubis_X.X.X/
|
|
$ sudo ruby setup.rb
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
<ul type="disc">
|
|
<li>(Optional) 'contrib/inline-require' enables you to merge 'lib/**/*.rb' into 'bin/erubis'.
|
|
<pre class="terminal">$ tar xjf erubis_X.X.X.tar.bz2
|
|
$ cd erubis_X.X.X/
|
|
$ unset RUBYLIB
|
|
$ contrib/inline-require -I lib bin/erubis > contrib/erubis
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
|
|
|
|
<a name="tutorial"></a>
|
|
<h2 class="section1">Tutorial</h2>
|
|
<a name="tut-basic"></a>
|
|
<h3 class="section2">Basic Example</h3>
|
|
<p>Here is a basic example of Erubis.
|
|
</p>
|
|
<a name="example1.eruby"></a>
|
|
<div class="program_caption">
|
|
example1.eruby</div>
|
|
<pre class="program"><ul>
|
|
<strong><% for item in list %></strong>
|
|
<li><strong><%= item %></strong></li>
|
|
<strong><% end %></strong>
|
|
<strong><%# here is ignored because starting with '#' %></strong>
|
|
</ul>
|
|
</pre>
|
|
<a name="example1.rb"></a>
|
|
<div class="program_caption">
|
|
example1.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example1.eruby')
|
|
eruby = <strong>Erubis::Eruby.new(input)</strong> # create Eruby object
|
|
|
|
puts "---------- script source ---"
|
|
puts <strong>eruby.src</strong> # print script source
|
|
|
|
puts "---------- result ----------"
|
|
list = ['aaa', 'bbb', 'ccc']
|
|
puts <strong>eruby.result(binding())</strong> # get result
|
|
## or puts eruby.result(<strong>:list=>list</strong>) # or pass Hash instead of Binding
|
|
|
|
## # or
|
|
## eruby = Erubis::Eruby.new
|
|
## input = File.read('example1.eruby')
|
|
## src = eruby.convert(input)
|
|
## eval src
|
|
</pre>
|
|
<a name="example1.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example1.rb
|
|
---------- script source ---
|
|
_buf = ''; _buf << '<ul>
|
|
'; for item in list
|
|
_buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
|
|
'; end
|
|
|
|
_buf << '</ul>
|
|
';
|
|
_buf.to_s
|
|
---------- result ----------
|
|
<ul>
|
|
<li>aaa</li>
|
|
<li>bbb</li>
|
|
<li>ccc</li>
|
|
</ul>
|
|
</pre>
|
|
<p>Erubis has command 'erubis'. Command-line option '-x' shows the compiled source code of eRuby script.
|
|
</p>
|
|
<a name="example1_x.result"></a>
|
|
<div class="terminal_caption">
|
|
example of command-line option '-x'</div>
|
|
<pre class="terminal">$ erubis <strong>-x</strong> example1.eruby
|
|
_buf = ''; _buf << '<ul>
|
|
'; for item in list
|
|
_buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
|
|
'; end
|
|
|
|
_buf << '</ul>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="tut-trim"></a>
|
|
<h3 class="section2">Trimming Spaces</h3>
|
|
<p>Erubis deletes spaces around '<% %>' automatically, while it leaves spaces around '<%= %>'.
|
|
</p>
|
|
<a name="example2.eruby.comment_filter"></a>
|
|
<div class="program_caption">
|
|
example2.eruby</div>
|
|
<pre class="program"><ul>
|
|
<% for item in list %> # trimmed
|
|
<li>
|
|
<%= item %> # not trimmed
|
|
</li>
|
|
<% end %> # trimmed
|
|
</ul>
|
|
</pre>
|
|
<a name="example2_x.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -x example2.eruby
|
|
_buf = ''; _buf << '<ul>
|
|
'; for item in list
|
|
_buf << ' <li>
|
|
'; _buf << ( item ).to_s; _buf << '
|
|
'; _buf << ' </li>
|
|
'; end
|
|
_buf << '</ul>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>If you want leave spaces around '<% %>', add command-line property '--trim=false'.
|
|
</p>
|
|
<a name="example2_trim.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code with command-line property '--trim=false'</div>
|
|
<pre class="terminal">$ erubis -x <strong>--trim=false</strong> example2.eruby
|
|
_buf = ''; _buf << '<ul>
|
|
'; _buf << ' '; for item in list ; _buf << '
|
|
'; _buf << ' <li>
|
|
'; _buf << ( item ).to_s; _buf << '
|
|
'; _buf << ' </li>
|
|
'; _buf << ' '; end ; _buf << '
|
|
'; _buf << '</ul>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Or add option <code>:trim=>false</code> to Erubis::Eruby.new().
|
|
</p>
|
|
<a name="example2.rb"></a>
|
|
<div class="program_caption">
|
|
example2.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example2.eruby')
|
|
eruby = Erubis::Eruby.new(input<strong>, :trim=>false</strong>)
|
|
|
|
puts "----- script source ---"
|
|
puts eruby.src # print script source
|
|
|
|
puts "----- result ----------"
|
|
list = ['aaa', 'bbb', 'ccc']
|
|
puts eruby.result(binding()) # get result
|
|
</pre>
|
|
<a name="example2.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example2.rb
|
|
----- script source ---
|
|
_buf = ''; _buf << '<ul>
|
|
'; <strong>_buf << ' ';</strong> for item in list ; _buf << '
|
|
'; _buf << ' <li>
|
|
'; _buf << ( item ).to_s; _buf << '
|
|
'; _buf << ' </li>
|
|
'; <strong>_buf << ' ';</strong> end ; _buf << '
|
|
'; _buf << '</ul>
|
|
';
|
|
_buf.to_s
|
|
----- result ----------
|
|
<ul>
|
|
|
|
<li>
|
|
aaa
|
|
</li>
|
|
|
|
<li>
|
|
bbb
|
|
</li>
|
|
|
|
<li>
|
|
ccc
|
|
</li>
|
|
|
|
</ul>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="tut-escape"></a>
|
|
<h3 class="section2">Escape</h3>
|
|
<p>Erubis has ability to escape (sanitize) expression.
|
|
Erubis::Eruby class act as the following:
|
|
</p>
|
|
<ul type="disc">
|
|
<li><code><%= <em>expr</em> %></code> - not escaped.
|
|
</li>
|
|
<li><code><%== <em>expr</em> %></code> - escaped.
|
|
</li>
|
|
<li><code><%=== <em>expr</em> %></code> - out to $stderr.
|
|
</li>
|
|
<li><code><%==== <em>expr</em> %></code> - ignored.
|
|
</li>
|
|
</ul>
|
|
<p>Erubis::EscapedEruby<sup>(<a href="#fnref:1" name="fnlink:1">*1</a>)</sup> class handle '<%= %>' as escaped and '<%== %>' as not escaped.
|
|
It means that using Erubis::EscapedEruby you can escape expression by default.
|
|
Also Erubis::XmlEruby class (which is equivalent to Erubis::EscapedEruby) is provided for compatibility with Erubis 1.1.
|
|
</p>
|
|
<a name="example3.eruby"></a>
|
|
<div class="program_caption">
|
|
example3.eruby</div>
|
|
<pre class="program"><% for item in list %>
|
|
<p><strong><%=</strong> item <strong>%></strong></p>
|
|
<p><strong><%==</strong> item <strong>%></strong></p>
|
|
<p><strong><%===</strong> item <strong>%></strong></p>
|
|
|
|
<% end %>
|
|
</pre>
|
|
<a name="example3.rb"></a>
|
|
<div class="program_caption">
|
|
example3.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example3.eruby')
|
|
eruby = Erubis::<strong>EscapedEruby</strong>.new(input) # or Erubis::XmlEruby
|
|
|
|
puts "----- script source ---"
|
|
puts eruby.src # print script source
|
|
|
|
puts "----- result ----------"
|
|
<strong>list = ['<aaa>', 'b&b', '"ccc"']</strong>
|
|
puts eruby.result(binding()) # get result
|
|
</pre>
|
|
<a name="example3.result.split_filter"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example3.rb 2> stderr.log
|
|
----- script source ---
|
|
_buf = ''; for item in list
|
|
_buf << ' <p>'; <strong>_buf << Erubis::XmlHelper.escape_xml( item )</strong>; _buf << '</p>
|
|
<p>'; <strong>_buf << ( item ).to_s</strong>; _buf << '</p>
|
|
<p>'; <strong>$stderr.puts("*** debug: item=#{(item).inspect}")</strong>; _buf << '</p>
|
|
|
|
'; end
|
|
_buf.to_s
|
|
----- result ----------
|
|
<p><strong>&lt;aaa&gt;</strong></p>
|
|
<p><aaa></p>
|
|
<p></p>
|
|
|
|
<p><strong>b&amp;b</strong></p>
|
|
<p>b&b</p>
|
|
<p></p>
|
|
|
|
<p><strong>&quot;ccc&quot;</strong></p>
|
|
<p>"ccc"</p>
|
|
<p></p>
|
|
|
|
$ cat stderr.log
|
|
*** debug: item="<aaa>"
|
|
*** debug: item="b&b"
|
|
*** debug: item="\"ccc\""
|
|
</pre>
|
|
<p>The command-line option '-e' will do the same action as Erubis::EscapedEruby.
|
|
This option is available for any language.
|
|
</p>
|
|
<a name="example3_e.result"></a>
|
|
<pre class="terminal">$ erubis -l ruby <strong>-e</strong> example3.eruby
|
|
_buf = ''; for item in list
|
|
_buf << ' <p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
<p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; $stderr.puts("*** debug: item=#{(item).inspect}"); _buf << '</p>
|
|
|
|
'; end
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Escaping function (default 'Erubis::XmlHelper.escape_xml()') can be changed by command-line property '--escapefunc=xxx' or by overriding Erubis::Eruby#escaped_expr() in subclass.
|
|
</p>
|
|
<div class="program_caption">
|
|
example to override Erubis::Eruby#escaped_expr()</div>
|
|
<pre class="program">class CGIEruby < Erubis::Eruby
|
|
def <strong>escaped_expr(code)</strong>
|
|
return "CGI.escapeHTML((#{code.strip}).to_s)"
|
|
#return "h(#{code.strip})"
|
|
end
|
|
end
|
|
|
|
class LatexEruby < Erubi::Eruby
|
|
def <strong>escaped_expr(code)</strong>
|
|
return "(#{code}).gsub(/[%\\]/,'\\\\\&')"
|
|
end
|
|
end
|
|
</pre>
|
|
<div class="footnote">
|
|
<dl compact>
|
|
<dt>(<a name="fnref:1" href="#fnlink:1">*1</a>)</dt>
|
|
<dd>Erubis::EscapedEruby class includes Erubis::EscapeEnhancer which swtches the action of '<%= %>' and '<%== %>'.</dd>
|
|
</dl>
|
|
</div>
|
|
<br>
|
|
|
|
|
|
<a name="tut-pattern"></a>
|
|
<h3 class="section2">Embedded Pattern</h3>
|
|
<p>You can change embedded pattern '<code><% %></code>' to another by command-line option '-p' or option '<code>:pattern=>...</code>' of Erubis::Eruby.new().
|
|
</p>
|
|
<a name="example4.eruby"></a>
|
|
<div class="program_caption">
|
|
example4.eruby</div>
|
|
<pre class="program"><strong><!--%</strong> for item in list <strong>%--></strong>
|
|
<p><strong><!--%=</strong> item <strong>%--></strong></p>
|
|
<strong><!--%</strong> end <strong>%--></strong>
|
|
</pre>
|
|
<a name="example4_x.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code with command-line option '-p'</div>
|
|
<pre class="terminal">$ erubis -x <strong>-p '<!--% %-->'</strong> example4.eruby
|
|
_buf = ''; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
'; end
|
|
_buf.to_s
|
|
</pre>
|
|
<a name="example4.rb"></a>
|
|
<div class="program_caption">
|
|
example4.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example4.eruby')
|
|
eruby = Erubis::Eruby.new(input<strong>, :pattern=>'<!--% %-->'</strong>)
|
|
# or '<(?:!--)?% %(?:--)?>'
|
|
|
|
puts "---------- script source ---"
|
|
puts eruby.src # print script source
|
|
|
|
puts "---------- result ----------"
|
|
list = ['aaa', 'bbb', 'ccc']
|
|
puts eruby.result(binding()) # get result
|
|
</pre>
|
|
<a name="example4.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example4.rb
|
|
---------- script source ---
|
|
_buf = ''; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
'; end
|
|
_buf.to_s
|
|
---------- result ----------
|
|
<p>aaa</p>
|
|
<p>bbb</p>
|
|
<p>ccc</p>
|
|
</pre>
|
|
<p>It is able to specify regular expression with :pattern option.
|
|
Notice that you must use '<code>(?: )</code>' instead of '<code>( )</code>' for grouping.
|
|
For example, '<code><(!--)?% %(--)?></code>' will not work while '<code><(?:!--)?% %(?:--)?></code>' will work.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="tut-context"></a>
|
|
<h3 class="section2">Context Object</h3>
|
|
<p>Context object is a set of data which are used in eRuby script.
|
|
Using context object makes clear which data to be used.
|
|
In Erubis, Hash object and Erubis::Context object are available as context object.
|
|
</p>
|
|
<p>Context data can be accessible via instance variables in eRuby script.
|
|
</p>
|
|
<a name="example5.eruby"></a>
|
|
<div class="program_caption">
|
|
example5.eruby</div>
|
|
<pre class="program"><span><%= <strong>@val</strong> %></span>
|
|
<ul>
|
|
<% for item in <strong>@list</strong> %>
|
|
<li><%= item %></li>
|
|
<% end %>
|
|
</ul>
|
|
</pre>
|
|
<a name="example5.rb"></a>
|
|
<div class="program_caption">
|
|
example5.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example5.eruby')
|
|
eruby = Erubis::Eruby.new(input) # create Eruby object
|
|
|
|
## create context object
|
|
## (key means var name, which may be string or symbol.)
|
|
<strong>context = {
|
|
:val => 'Erubis Example',
|
|
'list' => ['aaa', 'bbb', 'ccc'],
|
|
}</strong>
|
|
## or
|
|
# context = Erubis::Context.new()
|
|
# context['val'] = 'Erubis Example'
|
|
# context[:list] = ['aaa', 'bbb', 'ccc'],
|
|
|
|
puts <strong>eruby.evaluate(context)</strong> # get result
|
|
</pre>
|
|
<a name="example5.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example5.rb
|
|
<span>Erubis Example</span>
|
|
<ul>
|
|
<li>aaa</li>
|
|
<li>bbb</li>
|
|
<li>ccc</li>
|
|
</ul>
|
|
</pre>
|
|
<p>The difference between Erubis#result(binding) and Erubis#evaluate(context) is that the former invokes 'eval @src, binding' and the latter invokes 'context.instance_eval @src'.
|
|
This means that data is passed into eRuby script via local variables when Eruby::binding() is called, or passed via instance variables when Eruby::evaluate() is called.
|
|
</p>
|
|
<p>Here is the definition of Erubis#result() and Erubis#evaluate().
|
|
</p>
|
|
<div class="program_caption">
|
|
definition of result(binding) and evaluate(context)</div>
|
|
<pre class="program">def result(_binding=TOPLEVEL_BINDING)
|
|
if _binding.is_a?(Hash)
|
|
# load hash data as local variable
|
|
_h = _binding
|
|
_binding = binding()
|
|
eval _h.collect{|k,v| "#{k} = _h[#{k.inspect}];"}.join, _binding
|
|
end
|
|
return <strong>eval(@src, _binding)</strong>
|
|
end
|
|
|
|
def evaluate(_context=Erubis::Context.new)
|
|
if _context.is_a?(Hash)
|
|
# convert hash object to Context object
|
|
_hash = _context
|
|
_context = Erubis::Context.new
|
|
_hash.each {|k, v| _context[k] = v }
|
|
end
|
|
return <strong>_context.instance_eval(@src)</strong>
|
|
end
|
|
</pre>
|
|
<p>instance_eval() is defined at Object class so it is able to use any object as a context object as well as Hash or Erubis::Context.
|
|
</p>
|
|
<a name="example6.rb"></a>
|
|
<div class="program_caption">
|
|
example6.rb</div>
|
|
<pre class="program">class MyData
|
|
attr_accessor :val, :list
|
|
end
|
|
|
|
## any object can be a context object
|
|
<strong>mydata = MyData.new</strong>
|
|
<strong>mydata.val = 'Erubis Example'</strong>
|
|
<strong>mydata.list = ['aaa', 'bbb', 'ccc']</strong>
|
|
|
|
require 'erubis'
|
|
eruby = Erubis::Eruby.new(File.read('example5.eruby'))
|
|
puts eruby.evaluate(<strong>mydata</strong>)
|
|
</pre>
|
|
<a name="example6.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example6.rb
|
|
<span>Erubis Example</span>
|
|
<ul>
|
|
<li>aaa</li>
|
|
<li>bbb</li>
|
|
<li>ccc</li>
|
|
</ul>
|
|
</pre>
|
|
<p>It is recommended to use 'Erubis::Eruby#evaluate(context)' rather than 'Erubis::Eruby#result(binding())' because the latter has some problems.
|
|
See <a href="#topics-context-vs-binding">evaluate(context) v.s. result(binding)</a> section for details.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="tut-datafile"></a>
|
|
<h3 class="section2">Context Data File</h3>
|
|
<p>Command-line option '-f' specifies context data file.
|
|
Erubis load context data file and use it as context data.
|
|
Context data file can be YAML file ('*.yaml' or '*.yml') or Ruby script ('*.rb').
|
|
</p>
|
|
<a name="example7.eruby"></a>
|
|
<div class="program_caption">
|
|
example7.eruby</div>
|
|
<pre class="program"><h1><%= <strong>@title</strong> %></h1>
|
|
<ul>
|
|
<% for user in <strong>@users</strong> %>
|
|
<li>
|
|
<a href="mailto:<%= user['mail']%>"><%= user['name'] %></a>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
</pre>
|
|
<a name="context.yaml"></a>
|
|
<div class="program_caption">
|
|
context.yaml</div>
|
|
<pre class="program"><strong>title:</strong> Users List
|
|
<strong>users:</strong>
|
|
- name: foo
|
|
mail: foo@mail.com
|
|
- name: bar
|
|
mail: bar@mail.net
|
|
- name: baz
|
|
mail: baz@mail.org
|
|
</pre>
|
|
<a name="context.rb"></a>
|
|
<div class="program_caption">
|
|
context.rb</div>
|
|
<pre class="program">@title = 'Users List'
|
|
@users = [
|
|
{ 'name'=>'foo', 'mail'=>'foo@mail.com' },
|
|
{ 'name'=>'bar', 'mail'=>'bar@mail.net' },
|
|
{ 'name'=>'baz', 'mail'=>'baz@mail.org' },
|
|
]
|
|
</pre>
|
|
<a name="example7.result.split_filter"></a>
|
|
<div class="terminal_caption">
|
|
example of command-line option '-f'</div>
|
|
<pre class="terminal">$ erubis <strong>-f context.yaml</strong> example7.eruby
|
|
<h1>Users List</h1>
|
|
<ul>
|
|
<li>
|
|
<a href="mailto:foo@mail.com">foo</a>
|
|
</li>
|
|
<li>
|
|
<a href="mailto:bar@mail.net">bar</a>
|
|
</li>
|
|
<li>
|
|
<a href="mailto:baz@mail.org">baz</a>
|
|
</li>
|
|
</ul>
|
|
$ erubis <strong>-f context.rb</strong> example7.eruby
|
|
<h1>Users List</h1>
|
|
<ul>
|
|
<li>
|
|
<a href="mailto:foo@mail.com">foo</a>
|
|
</li>
|
|
<li>
|
|
<a href="mailto:bar@mail.net">bar</a>
|
|
</li>
|
|
<li>
|
|
<a href="mailto:baz@mail.org">baz</a>
|
|
</li>
|
|
</ul>
|
|
</pre>
|
|
<p>Command-line option '-S' converts keys of mapping in YAML data file from string into symbol.
|
|
Command-line option '-B' invokes 'Erubis::Eruby#result(binding())' instead of 'Erubis::Eruby#evaluate(context)'.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="tut-datastr"></a>
|
|
<h3 class="section2">Context Data String</h3>
|
|
<p>Command-line option '-c <em>str</em>' enables you to specify context data in command-line.
|
|
<em>str</em> can be YAML flow-style or Ruby code.
|
|
</p>
|
|
<a name="example8.eruby"></a>
|
|
<div class="program_caption">
|
|
example8.eruby</div>
|
|
<pre class="program"><h1><%= @title %></h1>
|
|
<ul>
|
|
<% for item in @list %>
|
|
<li><%= item %></li>
|
|
<% end %>
|
|
</ul>
|
|
</pre>
|
|
<a name="example8_yaml.result"></a>
|
|
<div class="terminal_caption">
|
|
example of YAML flow style</div>
|
|
<pre class="terminal">$ erubis <strong>-c '{title: Example, list: [AAA, BBB, CCC]}'</strong> example8.eruby
|
|
<h1>Example</h1>
|
|
<ul>
|
|
<li>AAA</li>
|
|
<li>BBB</li>
|
|
<li>CCC</li>
|
|
</ul>
|
|
</pre>
|
|
<a name="example8_ruby.result"></a>
|
|
<div class="terminal_caption">
|
|
example of Ruby code</div>
|
|
<pre class="terminal">$ erubis <strong>-c '@title="Example"; @list=%w[AAA BBB CCC]'</strong> example8.eruby
|
|
<h1>Example</h1>
|
|
<ul>
|
|
<li>AAA</li>
|
|
<li>BBB</li>
|
|
<li>CCC</li>
|
|
</ul>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="tut-preamble"></a>
|
|
<h3 class="section2">Preamble and Postamble</h3>
|
|
<p>The first line ('_buf = '';') in the compiled source code is called preamble
|
|
and the last line ('_buf.to_s') is called postamble.
|
|
</p>
|
|
<p>Command-line option '-b' skips the output of preamble and postamble.
|
|
</p>
|
|
<a name="example9.eruby"></a>
|
|
<div class="program_caption">
|
|
example9.eruby</div>
|
|
<pre class="program"><% for item in @list %>
|
|
<b><%= item %></b>
|
|
<% end %>
|
|
</pre>
|
|
<a name="example9.result.split_filter"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code with and without command-line option '-b'</div>
|
|
<pre class="terminal">$ erubis -x example9.eruby
|
|
<strong>_buf = '';</strong> for item in @list
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; end
|
|
<strong>_buf.to_s</strong>
|
|
$ erubis -x <strong>-b</strong> example9.eruby
|
|
for item in @list
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; end
|
|
</pre>
|
|
<p>Erubis::Eruby.new option '<code>:preamble=>false</code>' and '<code>:postamble=>false</code>' also suppress output of preamble or postamle.
|
|
</p>
|
|
<a name="example9.rb"></a>
|
|
<div class="program_caption">
|
|
example9.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example9.eruby')
|
|
eruby1 = Erubis::Eruby.new(input)
|
|
eruby2 = Erubis::Eruby.new(input, <strong>:preamble=>false, :postamble=>false</strong>)
|
|
|
|
puts eruby1.src # print preamble and postamble
|
|
puts "--------------"
|
|
puts eruby2.src # don't print preamble and postamble
|
|
</pre>
|
|
<a name="example9.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example9.rb
|
|
_buf = ''; for item in @list
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; end
|
|
_buf.to_s
|
|
--------------
|
|
for item in @list
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; end
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="tut-pi"></a>
|
|
<h3 class="section2">Processing Instruction (PI) Converter</h3>
|
|
<p>Erubis can parse Processing Instructions (PI) as embedded pattern.
|
|
</p>
|
|
<ul type="disc">
|
|
<li>'<code><?rb <em>...</em> ?></code>' represents Ruby statement.
|
|
</li>
|
|
<li>'<code>@{<em>...</em>}@</code>' represents escaped expression value.
|
|
</li>
|
|
<li>'<code>@!{<em>...</em>}@</code>' represents normal expression value.
|
|
</li>
|
|
<li>'<code>@!!{<em>...</em>}@</code>' prints expression value to standard output.
|
|
</li>
|
|
<li>(experimental) '<code><%= <em>...</em> %></code>' is also available to print expression value.
|
|
</li>
|
|
</ul>
|
|
<p>This is more useful than basic embedded pattern ('<code><% ... ></code>') because PI doesn't break XML or HTML at all.
|
|
For example the following XHTML file is well-formed and HTML validator got no errors on this example.
|
|
</p>
|
|
<a name="example10.xhtml"></a>
|
|
<div class="program_caption">
|
|
example10.xhtml</div>
|
|
<pre class="program"><?xml version="1.0" ?>
|
|
<strong><?rb
|
|
lang = 'en'
|
|
list = ['<aaa>', 'b&b', '"ccc"']
|
|
?></strong>
|
|
<html lang="<strong>@!{lang}@</strong>">
|
|
<body>
|
|
<ul>
|
|
<strong><?rb for item in list ?></strong>
|
|
<li><strong>@{item}@</strong></li>
|
|
<strong><?rb end ?></strong>
|
|
</ul>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<p>If the command-line property '--pi=<em>name</em>' is specified, erubis command parses input with PI converter.
|
|
If <em>name</em> is omitted then the following name is used according to '-l <em>lang</em>'.
|
|
</p>
|
|
<div align="center">
|
|
<table class="table1" border="1" cellspacing="0">
|
|
<tr class="tr1">
|
|
<th class="th1">'-l' option</th>
|
|
<th class="th1">PI name</th>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l ruby</td>
|
|
<td class="td1"><?rb ... ?></td>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l php</td>
|
|
<td class="td1"><?php ... ?></td>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l perl</td>
|
|
<td class="td1"><?perl ... ?></td>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l java</td>
|
|
<td class="td1"><?java ... ?></td>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l javascript</td>
|
|
<td class="td1"><?js ... ?></td>
|
|
</tr>
|
|
<tr class="tr1">
|
|
<td class="td1">-l scheme</td>
|
|
<td class="td1"><?scheme ... ?></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<a name="example10_x.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ erubis -x <strong>--pi</strong> example10.xhtml
|
|
_buf = ''; _buf << '<?xml version="1.0" ?>
|
|
';
|
|
lang = 'en'
|
|
list = ['<aaa>', 'b&b', '"ccc"']
|
|
|
|
_buf << '<html lang="'; _buf << (lang).to_s; _buf << '">
|
|
<body>
|
|
<ul>
|
|
'; for item in list
|
|
_buf << ' <li>'; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '</li>
|
|
'; end
|
|
_buf << ' </ul>
|
|
</body>
|
|
</html>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Expression character can be changeable by command-line property '--embchar=<em>char</em>. Default is '<code>@</code>'.
|
|
</p>
|
|
<p>Use Erubis::PI::Eruby instead of Erubis::Eruby if you want to use PI as embedded pattern.
|
|
</p>
|
|
<a name="example10.rb"></a>
|
|
<div class="program_caption">
|
|
example10.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('example10.xhtml')
|
|
eruby = Erubis::PI::Eruby.new(input)
|
|
print eruby.src
|
|
</pre>
|
|
<a name="example10.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby example10.rb
|
|
_buf = ''; _buf << '<?xml version="1.0" ?>
|
|
';
|
|
lang = 'en'
|
|
list = ['<aaa>', 'b&b', '"ccc"']
|
|
|
|
_buf << '<html lang="'; _buf << (lang).to_s; _buf << '">
|
|
<body>
|
|
<ul>
|
|
'; for item in list
|
|
_buf << ' <li>'; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '</li>
|
|
'; end
|
|
_buf << ' </ul>
|
|
</body>
|
|
</html>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p><strong>(experimental)</strong> Erubis supports '<%= ... %>' pattern with PI pattern.
|
|
</p>
|
|
<div class="program_caption">
|
|
example of Rails view template</div>
|
|
<pre class="program"><table>
|
|
<tr>
|
|
<?rb for item in @list ?>
|
|
<td>@{item.id}@</td>
|
|
<td>@{item.name}@</td>
|
|
<td>
|
|
<strong><%=</strong> link_to 'Destroy', {:action=>'destroy', :id=>item.id},
|
|
:confirm=>'Are you OK?' <strong>%></strong>
|
|
</td>
|
|
<?rb end ?>
|
|
</tr>
|
|
</table>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="tut-notext"></a>
|
|
<h3 class="section2">Retrieve Ruby Code</h3>
|
|
<p>Similar to '-x', ommand-line option '-X' shows converted Ruby source code.
|
|
The difference between '-x' and 'X' is that the former converts text part but the latter ignores it.
|
|
It means that you can retrieve Ruby code from eRuby script by '-X' option.
|
|
</p>
|
|
<p>For example, see the following eRuby script.
|
|
This is some complex, so it is difficult to grasp the program code.
|
|
</p>
|
|
<a name="example11.rhtml"></a>
|
|
<div class="program_caption">
|
|
example11.rhtml</div>
|
|
<pre class="program"><?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<body>
|
|
<h3>List</h3>
|
|
<% if @list.nil? || @list.empty? %>
|
|
<p>not found.</p>
|
|
<% else %>
|
|
<table>
|
|
<tbody>
|
|
<% @list.each_with_index do |item, i| %>
|
|
<tr bgcolor="<%= i % 2 == 0 ? '#FCC' : '#CCF' %>">
|
|
<td><%= item %></td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
<% end %>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<p>Command-line option '-X' extracts only the ruby code from eRuby script.
|
|
</p>
|
|
<a name="example11.result"></a>
|
|
<div class="terminal_caption">
|
|
result</div>
|
|
<pre class="terminal">$ erubis <strong>-X</strong> example11.rhtml
|
|
_buf = '';
|
|
|
|
|
|
|
|
|
|
|
|
if @list.nil? || @list.empty?
|
|
|
|
else
|
|
|
|
|
|
@list.each_with_index do |item, i|
|
|
_buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s;
|
|
_buf << ( item ).to_s;
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Command-line option '-C' (<strong>c</strong>mpact) deletes empty lines.
|
|
</p>
|
|
<a name="example11_C.result"></a>
|
|
<div class="terminal_caption">
|
|
result</div>
|
|
<pre class="terminal">$ erubis <strong>-XC</strong> example11.rhtml
|
|
_buf = '';
|
|
if @list.nil? || @list.empty?
|
|
else
|
|
@list.each_with_index do |item, i|
|
|
_buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s;
|
|
_buf << ( item ).to_s;
|
|
end
|
|
end
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Option '-U' (<strong>u</strong>nique) converts empty lines into a line.
|
|
</p>
|
|
<a name="example11_U.result"></a>
|
|
<div class="terminal_caption">
|
|
result</div>
|
|
<pre class="terminal">$ erubis <strong>-XU</strong> example11.rhtml
|
|
_buf = '';
|
|
|
|
if @list.nil? || @list.empty?
|
|
|
|
else
|
|
|
|
@list.each_with_index do |item, i|
|
|
_buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s;
|
|
_buf << ( item ).to_s;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Option '-N' (<strong>n</strong>umber) adds line number.
|
|
It is available with '-C' or '-U'.
|
|
</p>
|
|
<a name="example11_N.result"></a>
|
|
<div class="terminal_caption">
|
|
result</div>
|
|
<pre class="terminal">$ erubis <strong>-XNU</strong> example11.rhtml
|
|
1: _buf = '';
|
|
|
|
7: if @list.nil? || @list.empty?
|
|
|
|
9: else
|
|
|
|
12: @list.each_with_index do |item, i|
|
|
13: _buf << ( i % 2 == 0 ? '#FCC' : '#CCF' ).to_s;
|
|
14: _buf << ( item ).to_s;
|
|
|
|
16: end
|
|
|
|
19: end
|
|
|
|
22: _buf.to_s
|
|
</pre>
|
|
<p>Command-line option '-X' is available with PHP script.
|
|
</p>
|
|
<a name="example11.php"></a>
|
|
<div class="program_caption">
|
|
example11.php</div>
|
|
<pre class="program"><?xml version="1.0"?>
|
|
<html>
|
|
<body>
|
|
<h3>List</h3>
|
|
<?php if (!$list) { ?>
|
|
<p>not found.</p>
|
|
<?php } else { ?>
|
|
<table>
|
|
<tbody>
|
|
<?php $i = 0; ?>
|
|
<?php foreach ($list as $item) { ?>
|
|
<tr bgcolor="<?php echo ++$i % 2 == 1 ? '#FCC' : '#CCF'; ?>">
|
|
<td><?php echo $item; ?></td>
|
|
</tr>
|
|
<?php } ?>
|
|
</tbody>
|
|
</table>
|
|
<?php } ?>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="example11_php.result"></a>
|
|
<div class="terminal_caption">
|
|
result</div>
|
|
<pre class="terminal">$ erubis -XNU <strong>-l php</strong> <strong>--pi=php</strong> --trim=false example11.php
|
|
|
|
5: <?php if (!$list) { ?>
|
|
|
|
7: <?php } else { ?>
|
|
|
|
10: <?php $i = 0; ?>
|
|
11: <?php foreach ($list as $item) { ?>
|
|
12: <?php echo ++$i % 2 == 1 ? '#FCC' : '#CCF'; ?>
|
|
13: <?php echo $item; ?>
|
|
|
|
15: <?php } ?>
|
|
|
|
18: <?php } ?>
|
|
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="enhancer"></a>
|
|
<h2 class="section1">Enhancer</h2>
|
|
<p>Enhancer is a module to add a certain feature into Erubis::Eruby class.
|
|
Enhancer may be language-independent or only for Erubis::Eruby class.
|
|
</p>
|
|
<p>To use enhancers, define subclass and include them.
|
|
The folloing is an example to use <a href="#escape-enhancer">EscapeEnhancer</a>, <a href="#percentline-enhancer">PercentLineEnhancer</a>, and <a href="#bipattern-enhancer">BiPatternEnhancer</a>.
|
|
</p>
|
|
<pre class="program">class MyEruby < Erubis::Eruby
|
|
include EscapeEnhancer
|
|
include PercentLineEnhancer
|
|
include BiPatternEnhancer
|
|
end
|
|
</pre>
|
|
<p>You can specify enhancers in command-line with option '-E'.
|
|
The following is an example to use some enhancers in command-line.
|
|
</p>
|
|
<pre class="terminal">$ erubis -xE Escape,PercentLine,BiPattern example.eruby
|
|
</pre>
|
|
<p>The following is the list of enhancers.
|
|
</p>
|
|
<dl class="dl1">
|
|
<dt class="dt1">
|
|
<a href="#escape-enhancer">EscapeEnhander</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
Switch '<%= %>' to escaped and '<%== %>' to unescaped.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#stdout-enhancer">StdoutEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Use $stdout instead of array buffer.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#printout-enhancer">PrintOutEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Use "print(...)" statement insead of "_buf << ...".
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#printenabled-enhancer">PrintEnabledEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Enable to use print() in '<% ... %>'.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#array-enhancer">ArrayEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Return array of string instead of returning string.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#arraybuffer-enhancer">ArrayBufferEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Use array buffer. It is a little slower than StringBufferEnhancer.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#stringbuffer-enhancer">StringBufferEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Use string buffer. This is included in Erubis::Eruby by default.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#erbout-enhancer">ErboutEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
Set '_erbout = _buf = "";' to be compatible with ERB.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#notext-enhancer">NoTextEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
Print embedded code only and ignore normal text.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#nocode-enhancer">NoCodeEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
Print normal text only and ignore code.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#simplify-enhancer">SimplifyEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
Make compile faster but don't trim spaces around '<% %>'.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#bipattern-enhancer">BiPatternEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
[experimental] Enable to use another embedded pattern with '<% %>'.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#percentline-enhancer">PercentLineEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
Regard lines starting with '%' as Ruby code. This is for compatibility with eruby and ERB.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#headerfooter-enhancer">HeaderFooterEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
[experimental] Enable you to add header and footer in eRuby script.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#interpolation-enhancer">InterpolationEnhancer</a> (only for Eruby)</dt>
|
|
<dd class="dd1">
|
|
[experimental] convert '<p><%= text %></p>' into '_buf << %Q`<p>#{text}</p>`'.
|
|
</dd>
|
|
<dt class="dt1">
|
|
<a href="#deleteindent-enhancer">DeleteIndentEnhancer</a> (language-independent)</dt>
|
|
<dd class="dd1">
|
|
[experimental] delete indentation of HTML file and eliminate page size.
|
|
</dd>
|
|
</dl>
|
|
<p>If you required 'erubis/engine/enhanced', Eruby subclasses which include each enhancers are defined.
|
|
For example, class BiPatternEruby includes BiPatternEnhancer.
|
|
</p>
|
|
<a name="escape-enhancer"></a>
|
|
<h3 class="section2">EscapeEnhancer</h3>
|
|
<p>EscapeEnhancer switches '<%= ... %>' to escaped and '<%== ... %>' to unescaped.
|
|
</p>
|
|
<a name="example.eruby"></a>
|
|
<div class="program_caption">
|
|
example.eruby</div>
|
|
<pre class="program"><div>
|
|
<% for item in list %>
|
|
<p><%= item %></p>
|
|
<p><%== item %></p>
|
|
<% end %>
|
|
</div>
|
|
</pre>
|
|
<a name="escape_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Escape example.eruby
|
|
_buf = ''; _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; <strong>_buf << Erubis::XmlHelper.escape_xml( item );</strong> _buf << '</p>
|
|
<p>'; <strong>_buf << ( item ).to_s;</strong> _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>EscapeEnhancer is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="stdout-enhancer"></a>
|
|
<h3 class="section2">StdoutEnhancer</h3>
|
|
<p>StdoutEnhancer use $sdtdout instead of array buffer.
|
|
Therefore, you can use 'print' statement in embedded ruby code.
|
|
</p>
|
|
<a name="stdout_exmple.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Stdout example.eruby
|
|
<strong>_buf = $stdout;</strong> _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
<strong>''</strong>
|
|
</pre>
|
|
<p>StdoutEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="printout-enhancer"></a>
|
|
<h3 class="section2">PrintOutEnhancer</h3>
|
|
<p>PrintOutEnhancer makes compiled source code to use 'print(...)' instead of '_buf << ...'.
|
|
</p>
|
|
<a name="printstatement_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE PrintOut example.eruby
|
|
<strong>print</strong> '<div>
|
|
'; for item in list
|
|
<strong>print</strong> ' <p>'; <strong>print</strong>(( item ).to_s); <strong>print</strong> '</p>
|
|
<p>'; <strong>print</strong> Erubis::XmlHelper.escape_xml( item ); <strong>print</strong> '</p>
|
|
'; end
|
|
<strong>print</strong> '</div>
|
|
';
|
|
</pre>
|
|
<p>PrintOutEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="printenabled-enhancer"></a>
|
|
<h3 class="section2">PrintEnabledEnhancer</h3>
|
|
<p>PrintEnabledEnhancer enables you to use print() method in '<% ... %>'.
|
|
</p>
|
|
<a name="printenabled-example.eruby"></a>
|
|
<div class="program_caption">
|
|
printenabled-example.eruby</div>
|
|
<pre class="program"><% for item in @list %>
|
|
<b><strong><% print item %></strong></b>
|
|
<% end %>
|
|
</pre>
|
|
<a name="printenabled-example.rb"></a>
|
|
<div class="program_caption">
|
|
printenabled-example.rb</div>
|
|
<pre class="program">require 'erubis'
|
|
class PrintEnabledEruby < Erubis::Eruby
|
|
include Erubis::PrintEnabledEnhancer
|
|
end
|
|
input = File.read('printenabled-example.eruby')
|
|
eruby = PrintEnabledEruby.new(input)
|
|
list = ['aaa', 'bbb', 'ccc']
|
|
print eruby.evaluate(:list=>list)
|
|
</pre>
|
|
<a name="printenable_example.result"></a>
|
|
<div class="terminal_caption">
|
|
output result</div>
|
|
<pre class="terminal">$ ruby printenabled-example.rb
|
|
<b>aaa</b>
|
|
<b>bbb</b>
|
|
<b>ccc</b>
|
|
</pre>
|
|
<p>Notice to use Eruby#evaluate() and not to use Eruby#result(),
|
|
because print() method in '<% ... %>' invokes not Kernel#print() but PrintEnabledEnhancer#print().
|
|
</p>
|
|
<p>PrintEnabledEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="array-enhancer"></a>
|
|
<h3 class="section2">ArrayEnhancer</h3>
|
|
<p>ArrayEnhancer makes Eruby to return an array of strings.
|
|
</p>
|
|
<a name="array_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Array example.eruby
|
|
<strong>_buf = [];</strong> _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
<strong>_buf</strong>
|
|
</pre>
|
|
<p>ArrayEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="arraybuffer-enhancer"></a>
|
|
<h3 class="section2">ArrayBufferEnhancer</h3>
|
|
<p>ArrayBufferEnhancer makes Eruby to use array buffer.
|
|
Array buffer is a litte slower than String buffer.
|
|
</p>
|
|
<p>ArrayBufferEnhancer is only for Eruby.
|
|
</p>
|
|
<a name="arraybuffer_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE ArrayBuffer example.eruby
|
|
<strong>_buf = [];</strong> _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
<strong>_buf.join</strong>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="stringbuffer-enhancer"></a>
|
|
<h3 class="section2">StringBufferEnhancer</h3>
|
|
<p>StringBufferEnhancer makes Eruby to use string buffer.
|
|
String buffer is a little faster than array buffer.
|
|
Erubis::Eruby includes this enhancer by default.
|
|
</p>
|
|
<a name="stringbuffer_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE StringBuffer example.eruby
|
|
<strong>_buf = '';</strong> _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
<strong>_buf.to_s</strong>
|
|
</pre>
|
|
<p>StringBufferEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="erbout-enhancer"></a>
|
|
<h3 class="section2">ErboutEnhancer</h3>
|
|
<p>ErboutEnhancer makes Eruby to be compatible with ERB.
|
|
This is useful especially for Ruby on Rails.
|
|
</p>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Erbout example.eruby
|
|
<strong>_erbout = _buf = '';</strong> _buf << '<div>
|
|
'; for item in list
|
|
_buf << ' <p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>ErboutEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="notext-enhancer"></a>
|
|
<h3 class="section2">NoTextEnhancer</h3>
|
|
<p>NoTextEnhancer suppress output of text and prints only embedded code.
|
|
This is useful especially when debugging a complex eRuby script.
|
|
</p>
|
|
<a name="notext-example.eruby"></a>
|
|
<div class="program_caption">
|
|
notext-example.eruby</div>
|
|
<pre class="program"><h3>List</h3>
|
|
<% if !@list || @list.empty? %>
|
|
<p>not found.</p>
|
|
<% else %>
|
|
<table>
|
|
<tbody>
|
|
<% @list.each_with_index do |item, i| %>
|
|
<tr bgcolor="<%= i%2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
|
|
<td><%= item %></td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
<% end %>
|
|
</pre>
|
|
<a name="notext_example.result"></a>
|
|
<div class="terminal_caption">
|
|
output example of NoTextEnhancer</div>
|
|
<pre class="terminal">$ erubis -xE NoText notext-example.eruby
|
|
_buf = '';
|
|
if !@list || @list.empty?
|
|
|
|
else
|
|
|
|
|
|
@list.each_with_index do |item, i|
|
|
_buf << ( i%2 == 0 ? '#FFCCCC' : '#CCCCFF' ).to_s;
|
|
_buf << ( item ).to_s;
|
|
|
|
end
|
|
|
|
|
|
end
|
|
_buf.to_s
|
|
</pre>
|
|
<p>NoTextEnhancer is language-independent. It is useful even if you are PHP user, see <a href="#topics-php">this section</a>.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="nocode-enhancer"></a>
|
|
<h3 class="section2">NoCodeEnhancer</h3>
|
|
<p>NoCodeEnhancer suppress output of embedded code and prints only normal text.
|
|
This is useful especially when validating HTML tags.
|
|
</p>
|
|
<a name="nocode-example.eruby"></a>
|
|
<div class="program_caption">
|
|
nocode-example.eruby</div>
|
|
<pre class="program"><h3>List</h3>
|
|
<% if !@list || @list.empty? %>
|
|
<p>not found.</p>
|
|
<% else %>
|
|
<table>
|
|
<tbody>
|
|
<% @list.each_with_index do |item, i| %>
|
|
<tr bgcolor="<%= i%2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
|
|
<td><%= item %></td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
<% end %>
|
|
</pre>
|
|
<a name="nocode_example.result"></a>
|
|
<div class="terminal_caption">
|
|
output example of NoCodeEnhancer</div>
|
|
<pre class="terminal">$ erubis -xE NoCode notext-example.eruby
|
|
<h3>List</h3>
|
|
|
|
<p>not found.</p>
|
|
|
|
<table>
|
|
<tbody>
|
|
|
|
<tr bgcolor="">
|
|
<td></td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
</pre>
|
|
<p>NoCodeEnhancer is language-independent. It is useful even if you are PHP user, see <a href="#topics-php">this section</a>.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="simplify-enhancer"></a>
|
|
<h3 class="section2">SimplifyEnhancer</h3>
|
|
<p>SimplifyEnhancer makes compiling a little faster but don't trim spaces around '<% %>'.
|
|
</p>
|
|
<a name="simplify_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Simplify example.eruby
|
|
_buf = ''; _buf << '<div>
|
|
'; for item in list ; _buf << '
|
|
<p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end ; _buf << '
|
|
</div>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>SimplifyEnhancer is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="bipattern-enhancer"></a>
|
|
<h3 class="section2">BiPatternEnhancer</h3>
|
|
<p>BiPatternEnhancer enables to use another embedded pattern with '<% %>'.
|
|
By Default, '[= ... =]' is available for expression.
|
|
You can specify pattern by :bipattern property.
|
|
</p>
|
|
<a name="bipattern-example.rhtml"></a>
|
|
<div class="program_caption">
|
|
bipattern-example.rhtml</div>
|
|
<pre class="program"><% for item in list %>
|
|
<b><strong>[= item =]</strong></b>
|
|
<b><strong>[== item =]</strong></b>
|
|
<% end %>
|
|
</pre>
|
|
<a name="bipattern_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE BiPattern bipattern-example.rhtml
|
|
_buf = ''; for item in list
|
|
_buf << ' <b>'; <strong>_buf << ( item ).to_s;</strong> _buf << '</b>
|
|
<b>'; <strong>_buf << Erubis::XmlHelper.escape_xml( item );</strong> _buf << '</b>
|
|
'; end
|
|
_buf.to_s
|
|
</pre>
|
|
<p>BiPatternEnhancer is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="percentline-enhancer"></a>
|
|
<h3 class="section2">PercentLineEnhancer</h3>
|
|
<p>PercentLineEnhancer regards lines starting with '%' as Ruby code.
|
|
This is for compatibility with eruby and ERB.
|
|
</p>
|
|
<a name="percentline-example.rhtml"></a>
|
|
<div class="program_caption">
|
|
percentline-example.rhtml</div>
|
|
<pre class="program"><strong>% for item in list</strong>
|
|
<b><%= item %></b>
|
|
<strong>% end</strong>
|
|
%% lines with '%%'
|
|
</pre>
|
|
<a name="percentline_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE PercentLine percentline-example.rhtml
|
|
_buf = ''; <strong>for item in list</strong>
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; <strong>end</strong>
|
|
_buf << '% lines with \'%%\'
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>PercentLineEnhancer is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="headerfooter-enhancer"></a>
|
|
<h3 class="section2">HeaderFooterEnhancer</h3>
|
|
<p>[experimental]
|
|
</p>
|
|
<p>HeaderFooterEnhancer enables you to add header and footer in eRuby script.
|
|
</p>
|
|
<a name="headerfooter-example.eruby"></a>
|
|
<div class="program_caption">
|
|
headerfooter-example.eruby</div>
|
|
<pre class="program"><strong><!--#header:</strong>
|
|
<strong>def list_items(items)</strong>
|
|
<strong>#--></strong>
|
|
<% for item in items %>
|
|
<b><%= item %></b>
|
|
<% end %>
|
|
<strong><!--#footer:</strong>
|
|
<strong>end</strong>
|
|
<strong>#--></strong>
|
|
</pre>
|
|
<a name="headerfooter_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE HeaderFooter headerfooter-example.eruby
|
|
|
|
<strong>def list_items(items)</strong>
|
|
|
|
_buf = ''; for item in items
|
|
_buf << ' <b>'; _buf << ( item ).to_s; _buf << '</b>
|
|
'; end
|
|
_buf.to_s
|
|
|
|
<strong>end</strong>
|
|
|
|
</pre>
|
|
<p>Compare to the following:
|
|
</p>
|
|
<a name="normal-eruby-test.eruby"></a>
|
|
<div class="program_caption">
|
|
normal-eruby-test.eruby</div>
|
|
<pre class="program"><strong><%</strong>
|
|
<strong>def list_items(items)</strong>
|
|
<strong>%></strong>
|
|
<% for item in items %>
|
|
<li><%= item %></li>
|
|
<% end %>
|
|
<strong><%</strong>
|
|
<strong>end</strong>
|
|
<strong>%></strong>
|
|
</pre>
|
|
<a name="normal_eruby_test.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -x normal-eruby-test.eruby
|
|
_buf = '';
|
|
<strong>def list_items(items)</strong>
|
|
|
|
for item in items
|
|
_buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
|
|
'; end
|
|
|
|
<strong>end</strong>
|
|
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Header and footer can be in any position in eRuby script,
|
|
that is, header is no need to be in the head of eRuby script.
|
|
</p>
|
|
<a name="headerfooter-example2.rhtml"></a>
|
|
<div class="program_caption">
|
|
headerfooter-example2.rhtml</div>
|
|
<pre class="program"><?xml version="1.0"?>
|
|
<html>
|
|
<strong><!--#header:</strong>
|
|
<strong>def page(list)</strong>
|
|
<strong>#--></strong>
|
|
:
|
|
<strong><!--#footer:</strong>
|
|
<strong>end</strong>
|
|
<strong>#--></strong>
|
|
</html>
|
|
</pre>
|
|
<a name="headerfooter_example2.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE HeaderFooter headerfooter-example2.rhtml
|
|
|
|
<strong>def page(list)</strong>
|
|
|
|
_buf = ''; _buf << '<?xml version="1.0"?>
|
|
<html>
|
|
'; _buf << ' :
|
|
'; _buf << '</html>
|
|
';
|
|
_buf.to_s
|
|
|
|
<strong>end</strong>
|
|
|
|
</pre>
|
|
<p>HeaderFooterEnhancer is experimental and is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="interpolation-enhancer"></a>
|
|
<h3 class="section2">InterpolationEnhancer</h3>
|
|
<p>[experimental]
|
|
</p>
|
|
<p>InterpolationEnhancer converts "<h1><%= title %></h1>" into
|
|
"_buf << %Q`<h1>#{ title }</h1>`".
|
|
This makes Eruby a litter faster because method call of String#<< are eliminated
|
|
by expression interpolations.
|
|
</p>
|
|
<div class="program_caption">
|
|
InterpolationEnhancer elmininates method call of String#<<.</div>
|
|
<pre class="program">## Assume that input is '<a href="<%=url%>"><%=name%></a>'.
|
|
## Eruby convert input into the following code. String#<< is called 5 times.
|
|
_buf << '<a href="'; _buf << (url).to_s; _buf << '">'; _buf << (name).to_s; _buf << '</a>';
|
|
|
|
## If InterpolationEnhancer is used, String#<< is called only once.
|
|
_buf << %Q`<a href="#{url}">#{name}</a>`;
|
|
</pre>
|
|
<a name="interpolation_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE Interpolation example.eruby
|
|
_buf = ''; _buf << <strong>%Q`</strong><div>\n<strong>`</strong>
|
|
for item in list
|
|
_buf << <strong>%Q`</strong> <p><strong>#{ item }</strong></p>
|
|
<p><strong>#{Erubis::XmlHelper.escape_xml( item )}</strong></p>\n<strong>`</strong>
|
|
end
|
|
_buf << <strong>%Q`</strong></div>\n<strong>`</strong>
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Erubis provides Erubis::FastEruby class which includes InterpolationEnhancer.
|
|
You can use Erubis::FastEruby class instead of Erubis::Eruby class.
|
|
</p>
|
|
<p>InterpolationEnhancer is only for Eruby.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="deleteindent-enhancer"></a>
|
|
<h3 class="section2">DeleteIndentEnhancer</h3>
|
|
<p>[experimental]
|
|
DeleteIndentEnhancer deletes indentation of HTML file.
|
|
</p>
|
|
<a name="interpolation_example.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -xE DeleteIndent example.eruby
|
|
_buf = ''; _buf << '<div>
|
|
'; for item in list
|
|
_buf << '<p>'; _buf << ( item ).to_s; _buf << '</p>
|
|
<p>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</p>
|
|
'; end
|
|
_buf << '</div>
|
|
';
|
|
_buf.to_s
|
|
</pre>
|
|
<p>Notice that DeleteIndentEnhancer isn't intelligent.
|
|
It deletes indentations even if they are in <PRE></PRE>.
|
|
</p>
|
|
<p>DeleteIndentEnhancer is language-independent.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="lang"></a>
|
|
<h2 class="section1">Multi-Language Support</h2>
|
|
<p>Erubis supports the following languages<sup>(<a href="#fnref:2" name="fnlink:2">*2</a>)</sup>:
|
|
</p>
|
|
<ul type="disc">
|
|
<li>Ruby
|
|
</li>
|
|
<li><a href="#lang-php">PHP</a>
|
|
</li>
|
|
<li><a href="#lang-c">C</a>
|
|
</li>
|
|
<li><a href="#lang-java">Java</a>
|
|
</li>
|
|
<li><a href="#lang-scheme">Scheme</a>
|
|
</li>
|
|
<li><a href="#lang-perl">Perl</a>
|
|
</li>
|
|
<li><a href="#lang-javascript">JavaScript</a>
|
|
</li>
|
|
</ul>
|
|
<div class="footnote">
|
|
<dl compact>
|
|
<dt>(<a name="fnref:2" href="#fnlink:2">*2</a>)</dt>
|
|
<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>
|
|
</dl>
|
|
</div>
|
|
<a name="lang-php"></a>
|
|
<h3 class="section2">PHP</h3>
|
|
<a name="example.ephp"></a>
|
|
<div class="program_caption">
|
|
example.ephp</div>
|
|
<pre class="program"><?xml version="1.0"?>
|
|
<html>
|
|
<body>
|
|
<p>Hello <strong><%= $user %></strong>!</p>
|
|
<table>
|
|
<tbody>
|
|
<strong><% $i = 0; %></strong>
|
|
<strong><% foreach ($list as $item) { %></strong>
|
|
<strong><% $i++; %></strong>
|
|
<tr bgcolor=<strong>"<%= $i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %>"</strong>>
|
|
<td><strong><%= $i %></strong></td>
|
|
<td><strong><%== $item %></strong></td>
|
|
</tr>
|
|
<strong><% } %></strong>
|
|
</tbody>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="example_php.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -l php example.ephp
|
|
<<?php ?>?xml version="1.0"?>
|
|
<html>
|
|
<body>
|
|
<p>Hello <?php echo $user; ?>!</p>
|
|
<table>
|
|
<tbody>
|
|
<?php $i = 0; ?>
|
|
<?php foreach ($list as $item) { ?>
|
|
<?php $i++; ?>
|
|
<tr bgcolor="<?php echo $i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; ?>">
|
|
<td><?php echo $i; ?></td>
|
|
<td><?php echo htmlspecialchars($item); ?></td>
|
|
</tr>
|
|
<?php } ?>
|
|
</tbody>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="lang-c"></a>
|
|
<h3 class="section2">C</h3>
|
|
<a name="example.ec"></a>
|
|
<div class="program_caption">
|
|
example.ec</div>
|
|
<pre class="program"><strong><%
|
|
#include <stdio.h>
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int i;
|
|
|
|
%></strong>
|
|
<html>
|
|
<body>
|
|
<p>Hello <strong><%= "%s", argv[0] %></strong>!</p>
|
|
<table>
|
|
<tbody>
|
|
<strong><% for (i = 1; i < argc; i++) { %></strong>
|
|
<tr bgcolor="<strong><%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %></strong>">
|
|
<td><strong><%= "%d", i %></strong></td>
|
|
<td><strong><%= "%s", argv[i] %></strong></td>
|
|
</tr>
|
|
<strong><% } %></strong>
|
|
</tbody>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
<strong><%
|
|
return 0;
|
|
}
|
|
%></strong>
|
|
</pre>
|
|
<a name="example_c.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -l c example.ec
|
|
#line 1 "example.ec"
|
|
|
|
#include <stdio.h>
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int i;
|
|
|
|
|
|
fputs("<html>\n"
|
|
" <body>\n"
|
|
" <p>Hello ", stdout); fprintf(stdout, "%s", argv[0]); fputs("!</p>\n"
|
|
" <table>\n"
|
|
" <tbody>\n", stdout);
|
|
for (i = 1; i < argc; i++) {
|
|
fputs(" <tr bgcolor=\"", stdout); fprintf(stdout, i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"); fputs("\">\n"
|
|
" <td>", stdout); fprintf(stdout, "%d", i); fputs("</td>\n"
|
|
" <td>", stdout); fprintf(stdout, "%s", argv[i]); fputs("</td>\n"
|
|
" </tr>\n", stdout);
|
|
}
|
|
fputs(" </tbody>\n"
|
|
" </table>\n"
|
|
" </body>\n"
|
|
"</html>\n", stdout);
|
|
|
|
return 0;
|
|
}
|
|
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="lang-java"></a>
|
|
<h3 class="section2">Java</h3>
|
|
<a name="Example.ejava"></a>
|
|
<div class="program_caption">
|
|
Example.ejava</div>
|
|
<pre class="program"><strong><%
|
|
import java.util.*;
|
|
|
|
public class Example {
|
|
private String user;
|
|
private String[] list;
|
|
public example(String user, String[] list) {
|
|
this.user = user;
|
|
this.list = list;
|
|
}
|
|
|
|
public String view() {
|
|
StringBuffer _buf = new StringBuffer();
|
|
%></strong>
|
|
<html>
|
|
<body>
|
|
<p>Hello <strong><%= user %></strong>!</p>
|
|
<table>
|
|
<tbody>
|
|
<strong><% for (int i = 0; i < list.length; i++) { %></strong>
|
|
<tr bgcolor=<strong>"<%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>"</strong>>
|
|
<td><strong><%= i + 1 %></strong></td>
|
|
<td><strong><%== list[i] %></strong></td>
|
|
</tr>
|
|
<strong><% } %></strong>
|
|
</tbody>
|
|
</table>
|
|
<body>
|
|
</html>
|
|
<strong><%
|
|
return _buf.toString();
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
String[] list = { "<aaa>", "b&b", "\"ccc\"" };
|
|
Example ex = Example.new("Erubis", list);
|
|
System.out.print(ex.view());
|
|
}
|
|
|
|
public static String escape(String s) {
|
|
StringBuffer sb = new StringBuffer();
|
|
for (int i = 0; i < s.length(); i++) {
|
|
char ch = s.charAt(i);
|
|
switch (ch) {
|
|
case '<': sb.append("&lt;"); break;
|
|
case '>': sb.append("&gt;"); break;
|
|
case '&': sb.append("&amp;"); break;
|
|
case '"': sb.append("&quot;"); break;
|
|
default: sb.append(ch);
|
|
}
|
|
}
|
|
return sb.toString();
|
|
}
|
|
}
|
|
%></strong>
|
|
</pre>
|
|
<a name="example_java.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -b -l java example.ejava
|
|
|
|
import java.util.*;
|
|
|
|
public class Example {
|
|
private String user;
|
|
private String[] list;
|
|
public example(String user, String[] list) {
|
|
this.user = user;
|
|
this.list = list;
|
|
}
|
|
|
|
public String view() {
|
|
StringBuffer _buf = new StringBuffer();
|
|
|
|
_buf.append("<html>\n"
|
|
+ " <body>\n"
|
|
+ " <p>Hello "); _buf.append(user); _buf.append("!</p>\n"
|
|
+ " <table>\n"
|
|
+ " <tbody>\n");
|
|
for (int i = 0; i < list.length; i++) {
|
|
_buf.append(" <tr bgcolor=\""); _buf.append(i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"); _buf.append("\">\n"
|
|
+ " <td>"); _buf.append(i + 1); _buf.append("</td>\n"
|
|
+ " <td>"); _buf.append(escape(list[i])); _buf.append("</td>\n"
|
|
+ " </tr>\n");
|
|
}
|
|
_buf.append(" </tbody>\n"
|
|
+ " </table>\n"
|
|
+ " <body>\n"
|
|
+ "</html>\n");
|
|
|
|
return _buf.toString();
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
String[] list = { "<aaa>", "b&b", "\"ccc\"" };
|
|
Example ex = Example.new("Erubis", list);
|
|
System.out.print(ex.view());
|
|
}
|
|
|
|
public static String escape(String s) {
|
|
StringBuffer sb = new StringBuffer();
|
|
for (int i = 0; i < s.length(); i++) {
|
|
char ch = s.charAt(i);
|
|
switch (ch) {
|
|
case '<': sb.append("&lt;"); break;
|
|
case '>': sb.append("&gt;"); break;
|
|
case '&': sb.append("&amp;"); break;
|
|
case '"': sb.append("&quot;"); break;
|
|
default: sb.append(ch);
|
|
}
|
|
}
|
|
return sb.toString();
|
|
}
|
|
}
|
|
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="lang-scheme"></a>
|
|
<h3 class="section2">Scheme</h3>
|
|
<a name="example.escheme"></a>
|
|
<div class="program_caption">
|
|
example.escheme</div>
|
|
<pre class="program"><html>
|
|
<body>
|
|
<strong><%
|
|
(let ((user "Erubis")
|
|
(items '("<aaa>" "b&b" "\"ccc\""))
|
|
(i 0))
|
|
%></strong>
|
|
<p>Hello <strong><%= user %></strong>!</p>
|
|
<table>
|
|
<strong><%
|
|
(for-each
|
|
(lambda (item)
|
|
(set! i (+ i 1))
|
|
%></strong>
|
|
<tr bgcolor="<strong><%= (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF") %></strong>">
|
|
<td><strong><%= i %></strong></td>
|
|
<td><strong><%= item %></strong></td>
|
|
</tr>
|
|
<strong><%
|
|
) ; lambda end
|
|
items) ; for-each end
|
|
%></strong>
|
|
</table>
|
|
<strong><%
|
|
) ; let end
|
|
%></strong>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="example_scheme.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -l scheme example.escheme
|
|
(let ((_buf '())) (define (_add x) (set! _buf (cons x _buf))) (_add "<html>
|
|
<body>\n")
|
|
|
|
(let ((user "Erubis")
|
|
(items '("<aaa>" "b&b" "\"ccc\""))
|
|
(i 0))
|
|
|
|
(_add " <p>Hello ")(_add user)(_add "!</p>
|
|
<table>\n")
|
|
|
|
(for-each
|
|
(lambda (item)
|
|
(set! i (+ i 1))
|
|
|
|
(_add " <tr bgcolor=\"")(_add (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF"))(_add "\">
|
|
<td>")(_add i)(_add "</td>
|
|
<td>")(_add item)(_add "</td>
|
|
</tr>\n")
|
|
|
|
) ; lambda end
|
|
items) ; for-each end
|
|
|
|
(_add " </table>\n")
|
|
|
|
) ; let end
|
|
|
|
(_add " </body>
|
|
</html>\n")
|
|
(reverse _buf))
|
|
</pre>
|
|
<a name="example_scheme_display.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code (with <code>--func=display</code> property)</div>
|
|
<pre class="terminal">$ erubis -l scheme --func=display example.escheme
|
|
(display "<html>
|
|
<body>\n")
|
|
|
|
(let ((user "Erubis")
|
|
(items '("<aaa>" "b&b" "\"ccc\""))
|
|
(i 0))
|
|
|
|
(display " <p>Hello ")(display user)(display "!</p>
|
|
<table>\n")
|
|
|
|
(for-each
|
|
(lambda (item)
|
|
(set! i (+ i 1))
|
|
|
|
(display " <tr bgcolor=\"")(display (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF"))(display "\">
|
|
<td>")(display i)(display "</td>
|
|
<td>")(display item)(display "</td>
|
|
</tr>\n")
|
|
|
|
) ; lambda end
|
|
items) ; for-each end
|
|
|
|
(display " </table>\n")
|
|
|
|
) ; let end
|
|
|
|
(display " </body>
|
|
</html>\n")
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="lang-perl"></a>
|
|
<h3 class="section2">Perl</h3>
|
|
<a name="example.eperl"></a>
|
|
<div class="program_caption">
|
|
example.eprl</div>
|
|
<pre class="program"><strong><%
|
|
my $user = 'Erubis';
|
|
my @list = ('<aaa>', 'b&b', '"ccc"');
|
|
%></strong>
|
|
<html>
|
|
<body>
|
|
<p>Hello <strong><%= $user %></strong>!</p>
|
|
<table>
|
|
<strong><% $i = 0; %></strong>
|
|
<strong><% for $item (@list) { %></strong>
|
|
<tr bgcolor=<strong><%= ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %></strong>">
|
|
<td><strong><%= $i %></strong></td>
|
|
<td><strong><%= $item %></strong></td>
|
|
</tr>
|
|
<strong><% } %></strong>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="example_perl.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -l perl example.eperl
|
|
use HTML::Entities;
|
|
my $user = 'Erubis';
|
|
my @list = ('<aaa>', 'b&b', '"ccc"');
|
|
|
|
print('<html>
|
|
<body>
|
|
<p>Hello '); print($user); print('!</p>
|
|
<table>
|
|
'); $i = 0;
|
|
for $item (@list) {
|
|
print(' <tr bgcolor='); print(++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'); print('">
|
|
<td>'); print($i); print('</td>
|
|
<td>'); print($item); print('</td>
|
|
</tr>
|
|
'); }
|
|
print(' </table>
|
|
</body>
|
|
</html>
|
|
');
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="lang-javascript"></a>
|
|
<h3 class="section2">JavaScript</h3>
|
|
<a name="example.ejs"></a>
|
|
<div class="program_caption">
|
|
example.ejs</div>
|
|
<pre class="program"><strong><%
|
|
var user = 'Erubis';
|
|
var list = ['<aaa>', 'b&b', '"ccc"'];
|
|
%></strong>
|
|
<html>
|
|
<body>
|
|
<p>Hello <strong><%= user %></strong>!</p>
|
|
<table>
|
|
<tbody>
|
|
<strong><% var i; %></strong>
|
|
<strong><% for (i = 0; i < list.length; i++) { %></strong>
|
|
<tr bgcolor="<strong><%= i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %></strong>">
|
|
<td><strong><%= i + 1 %></strong></td>
|
|
<td><strong><%= list[i] %></strong></td>
|
|
</tr>
|
|
<strong><% } %></strong>
|
|
</tbody>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="example_js.result"></a>
|
|
<div class="terminal_caption">
|
|
compiled source code</div>
|
|
<pre class="terminal">$ erubis -l js example.ejs
|
|
var _buf = [];
|
|
var user = 'Erubis';
|
|
var list = ['<aaa>', 'b&b', '"ccc"'];
|
|
|
|
_buf.push("<html>\n\
|
|
<body>\n\
|
|
<p>Hello "); _buf.push(user); _buf.push("!</p>\n\
|
|
<table>\n\
|
|
<tbody>\n");
|
|
var i;
|
|
for (i = 0; i < list.length; i++) {
|
|
_buf.push(" <tr bgcolor=\""); _buf.push(i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'); _buf.push("\">\n\
|
|
<td>"); _buf.push(i + 1); _buf.push("</td>\n\
|
|
<td>"); _buf.push(list[i]); _buf.push("</td>\n\
|
|
</tr>\n");
|
|
}
|
|
_buf.push(" </tbody>\n\
|
|
</table>\n\
|
|
</body>\n\
|
|
</html>\n");
|
|
document.write(_buf.join(""));
|
|
</pre>
|
|
<p>If command-line option '<code>--docwrite=false</code>' is specified,
|
|
'<code>_buf.join("");</code>' is used instead of '<code>document.write(_buf.join(""));</code>'.
|
|
This is useful when passing converted source code to eval() function in JavaScript.
|
|
</p>
|
|
<p>You can pass <code>:docwrite=>false</code> to Erubis::Ejavascript.new() in your Ruby script.
|
|
</p>
|
|
<pre class="program">s = File.read('example.jshtml')
|
|
engine = Erubis::Ejavascript.new(s, <code>:docwrite=>false</code>)
|
|
</pre>
|
|
<p>If you want to specify any JavaScript code, use '--postamble=...'.
|
|
</p>
|
|
<p>Notice that default value of 'docwrite' property will be false in the future release.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="rails"></a>
|
|
<h2 class="section1">Ruby on Rails Support</h2>
|
|
<p>Erubis supports Ruby on Rails.
|
|
This section describes how to use Erubis with Ruby on Rails.
|
|
</p>
|
|
<a name="rails-settings"></a>
|
|
<h3 class="section2">Settings</h3>
|
|
<p>Add the following code to your 'config/environment.rb' and restart web server.
|
|
This replaces ERB in Rails by Erubis entirely.
|
|
</p>
|
|
<div class="program_caption">
|
|
config/environment.rb</div>
|
|
<pre class="program">require 'erubis/helpers/rails_helper'
|
|
#Erubis::Helpers::RailsHelper.engine_class = Erubis::Eruby # or Erubis::FastEruby
|
|
#Erubis::Helpers::RailsHelper.init_properties = {}
|
|
#Erubis::Helpers::RailsHelper.show_src = nil
|
|
#Erubis::Helpers::RailsHelper.preprocessing = false
|
|
</pre>
|
|
<p>Options:
|
|
</p>
|
|
<dl class="dl2">
|
|
<dt class="dt2">
|
|
Erubis::Helpers::RailsHelper.engine_class (=Erubis::Eruby)</dt>
|
|
<dd class="dd2">
|
|
<p> Erubis engine class (default Erubis::Eruby).
|
|
</p>
|
|
</dd>
|
|
<dt class="dt2">
|
|
Erubis::Helpers::RailsHelper.init_properties (={})</dt>
|
|
<dd class="dd2">
|
|
<p> Optional arguments for Erubis::Eruby#initialize() method (default {}).
|
|
</p>
|
|
</dd>
|
|
<dt class="dt2">
|
|
Erubis::Helpers::RailsHelper.show_src (=nil)</dt>
|
|
<dd class="dd2">
|
|
<p> Whether to print converted Ruby code into log file.
|
|
If true, Erubis prints coverted code into log file.
|
|
If false, Erubis doesn't.
|
|
If nil, Erubis prints when ENV['RAILS_ENV'] == 'development'.
|
|
Default is nil.
|
|
</p>
|
|
</dd>
|
|
<dt class="dt2">
|
|
Erubis::Helpers::RailsHelper.preprocessing (=false)</dt>
|
|
<dd class="dd2">
|
|
<p> Enable preprocessing if true (default false).
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
<br>
|
|
|
|
|
|
<a name="rails-preprocessing"></a>
|
|
<h3 class="section2">Preprosessing</h3>
|
|
<p>Erubis supports preprocessing of template files.
|
|
Preprocessing make your Ruby on Rails application about 20-40 percent faster.
|
|
To enable preprocessing, set Erubis::Helpers::RailsHelper.preprocessing to true in your 'environment.rb' file.
|
|
</p>
|
|
<p>For example, assume the following template.
|
|
This is slow because link_to() method is called every time when template is rendered.
|
|
</p>
|
|
<pre class="program"><%= link_to 'Create', :action=>'create' %>
|
|
</pre>
|
|
<p>The following is faster than the above, but not flexible because url is fixed.
|
|
</p>
|
|
<pre class="program"><a href="/users/create">Create</a>
|
|
</pre>
|
|
<p>Preprocessing solves this problem.
|
|
If you use '[%= %]' instead of '<%= %>', preprocessor evaluate it only once when template is loaded.
|
|
</p>
|
|
<pre class="program"><strong>[%= link_to 'Create', :action=>'create'%]</strong>
|
|
</pre>
|
|
<p>The above is evaluated by preprocessor and replaced to the following code automatically.
|
|
</p>
|
|
<pre class="program"><a href="/users/create">Create</a>
|
|
</pre>
|
|
<p>Notice that this is done only once when template file is loaded.
|
|
It means that link_to() method is not called when template is rendered.
|
|
</p>
|
|
<p>If link_to() method have variable arguments, use <code>_?()</code> helper method.
|
|
</p>
|
|
<pre class="program"><% for user in @users %>
|
|
[%= link_to <strong>_?('user.name')</strong>, :action=>'show', :id=><strong>_?('user.id')</strong> %]
|
|
<% end %>
|
|
</pre>
|
|
<p>The above is evaluated by preprocessor when template is loaded and expanded into the following code.
|
|
This will be much faster because link_to() method is not called when rendering.
|
|
</p>
|
|
<pre class="program"><% for user in @users %>
|
|
<a href="/users/show/<strong><%=user.id%></strong>"><strong><%=user.name%></strong></a>
|
|
<% end %>
|
|
</pre>
|
|
<p>Preprocessing statement (<code>[% %]</code>) is also available as well as preprocessing expression (<code>[%= %]</code>).
|
|
</p>
|
|
<pre class="program"><select name="state">
|
|
<option value="">-</option>
|
|
<strong>[% for code in states.keys.sort %]</strong>
|
|
<option value="<strong>[%= code %]</strong>"><strong>[%= states[code] %]</strong></option>
|
|
<strong>[% end %]</strong>
|
|
</select>
|
|
</pre>
|
|
<p>The above will be evaluated by preprocessor and expanded into the following when template is loaded.
|
|
In the result, rendering speed will be much faster because for-loop is not executed when rendering.
|
|
</p>
|
|
<pre class="program"><select name="state">
|
|
<option value="">-</option>
|
|
<option value="AK">Alaska</option>
|
|
<option value="AL">Alabama</option>
|
|
<option value="AR">Arkansas</option>
|
|
<option value="AS">American Samoa</option>
|
|
<option value="AZ">Arizona</option>
|
|
<option value="CA">California</option>
|
|
<option value="CO">Colorado</option>
|
|
....
|
|
</select>
|
|
</pre>
|
|
<p>Notice that it is not recommended to use preprocessing with tag helpers,
|
|
because tag helpers generate different html code when form parameter has errors or not.
|
|
</p>
|
|
<p>Helper methods of Ruby on Rails are divided into two groups.
|
|
</p>
|
|
<ul type="disc">
|
|
<li>link_to() or _() (method of gettext package) are not need to call for every time
|
|
as template is rendered because it returns same value when same arguments are passed.
|
|
These methods can be got faster by preprocessing.
|
|
</li>
|
|
<li>Tag helper methods should be called for every time as template is rendered
|
|
because it may return differrent value even if the same arguments are passed.
|
|
Preprocessing is not available with these methods.
|
|
</li>
|
|
</ul>
|
|
<p>In Ruby on Rails 2.0, <code>_?('user_id')</code> is OK but <code>_?('user.id')</code> is NG
|
|
because the latter contains period ('.') character.
|
|
</p>
|
|
<pre class="program"><!-- NG in Rails 2.0, because _?('') contains period -->
|
|
[%= link_to 'Edit', edit_user_path(<strong>_?('@user.id')</strong>) %]
|
|
[%= link_to 'Show', <strong>@user</strong> %]
|
|
[%= link_to 'Delete', <strong>@user</strong>, :confirm=>'OK?', :method=>:delete %]
|
|
|
|
<!-- OK in Rails 2.0 -->
|
|
<strong><%= user_id = @user.id %></strong>
|
|
[%= link_to 'Edit', edit_user_path(<strong>_?('user_id')</strong>) %]
|
|
[%= link_to 'Show', <strong>:action=>'show', :id=>_?('user_id')</strong> %]
|
|
[%= link_to 'Delete', <strong>{:action=>'destroy', :id=>_?('user_id')}</strong>,
|
|
{:confirm=>'OK?', :method=>:delete} %]
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="rails-formhelpers"></a>
|
|
<h3 class="section2">Form Helpers for Preprocessing</h3>
|
|
<p><strong>(Experimental)</strong>
|
|
</p>
|
|
<p>Erubis provides form helper methods for preprocessing.
|
|
These are defined in 'erubis/helpers/rails_form_helper.rb'.
|
|
If you want to use it, require it and include Erubis::Helpers::RailsFormHelper in 'app/helpers/applition_helper.rb'
|
|
</p>
|
|
<div class="program_caption">
|
|
app/helpers/xxx_helper.rb</div>
|
|
<pre class="program">require 'erubis/helpers/rails_form_helper'
|
|
module ApplicationHelper
|
|
include Erubis::Helpers::RailsFormHelper
|
|
end
|
|
</pre>
|
|
<p>Form helper methods defined in Erubis::Helpers::RailsFormHelper are named as 'pp_xxxx'
|
|
('pp' represents preprocessing).
|
|
</p>
|
|
<p>Assume the following view template:
|
|
</p>
|
|
<div class="program_caption">
|
|
_form.rhtml</div>
|
|
<pre class="program"> <p>
|
|
Name: <%= text_field :user, :name %>
|
|
</p>
|
|
<p>
|
|
Name: <strong>[%= pp_text_field :user, :name %]</strong>
|
|
</p>
|
|
</pre>
|
|
<p>Erubis preprocessor converts it to the following eRuby string:
|
|
</p>
|
|
<div class="program_caption">
|
|
preprocessed</div>
|
|
<pre class="program"> <p>
|
|
Name: <%= text_field :user, :name %>
|
|
</p>
|
|
<p>
|
|
Name: <strong><input id="stock_name" name="stock[name]" size="30" type="text" value="<%=h @stock.name%>" /></strong>
|
|
</p>
|
|
</pre>
|
|
<p>Erubis converts it to the following Ruby code:
|
|
</p>
|
|
<div class="program_caption">
|
|
Ruby code</div>
|
|
<pre class="program"> _buf << ' <p>
|
|
Name: '; _buf << ( text_field :stock, :name ).to_s; _buf << '
|
|
'; _buf << ' </p>
|
|
<p>
|
|
Name: <input id="stock_name" name="stock[name]" size="30" type="text" value="'; _buf << (h @stock.name).to_s; _buf << '" />
|
|
</p>
|
|
';
|
|
</pre>
|
|
<p>The above Ruby code shows that text_field() is called everytime when rendering,
|
|
but pp_text_field() is called only once when template is loaded.
|
|
This means that pp_text_field() with preprocessing makes view layer very fast.
|
|
</p>
|
|
<p>Module Erubis::Helpers::RailsFormHelper defines the following form helper methods.
|
|
</p>
|
|
<ul type="disc">
|
|
<li>pp_render_partial(basename)
|
|
</li>
|
|
<li>pp_form_tag(url_for_options={}, options={}, *parameters_for_url, &block)
|
|
</li>
|
|
<li>pp_text_field(object_name, method, options={})
|
|
</li>
|
|
<li>pp_password_field(object_name, method, options={})
|
|
</li>
|
|
<li>pp_hidden_field(object_name, method, options={})
|
|
</li>
|
|
<li>pp_file_field(object_name, method, options={})
|
|
</li>
|
|
<li>pp_text_area(object_name, method, options={})
|
|
</li>
|
|
<li>pp_check_box(object_name, method, options={}, checked_value="1", unchecked_value="0")
|
|
</li>
|
|
<li>pp_radio_button(object_name, method, tag_value, options={})
|
|
</li>
|
|
<li>pp_select(object, method, collection, options={}, html_options={})
|
|
</li>
|
|
<li>pp_collection_select(object, method, collection, value_method, text_method, options={}, html_options={})
|
|
</li>
|
|
<li>pp_country_select(object, method, priority_countries=nil, options={}, html_options={})
|
|
</li>
|
|
<li>pp_time_zone_select(object, method, priority_zones=nil, options={}, html_options={})
|
|
</li>
|
|
<li>pp_submit_tag(value="Save changes", options={})
|
|
</li>
|
|
<li>pp_image_submit_tag(source, options={})
|
|
</li>
|
|
</ul>
|
|
<p>Notice that pp_form_for() is not provided.
|
|
</p>
|
|
<p><span style="color:#FF0000">CAUTION:</span> These are experimental and may not work in Ruby on Rails 2.0.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="rails-others"></a>
|
|
<h3 class="section2">Others</h3>
|
|
<ul type="disc">
|
|
<li>ActionView::Helpers::CaptureHelper#capture() and ActionView::Helpers::Texthelper#concat() are available.
|
|
</li>
|
|
</ul>
|
|
<ul type="disc">
|
|
<li>Form helper methods are not tested in Ruby on Rails 2.0.
|
|
</li>
|
|
</ul>
|
|
<ul type="disc">
|
|
<li>ERB::Util.h() is redefined if you require 'erubis/helpers/rails_helper.rb'.
|
|
Original definition of ERB::Util.h() is the following and it is slow
|
|
because it scans string four times.
|
|
<pre class="program"> def html_escape(s)
|
|
s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
|
|
end
|
|
alias h html_escape
|
|
</pre>
|
|
<p> New definition in 'erubis/helpers/rails_helper.rb' is faster than the above
|
|
because it scans string only once.
|
|
</p>
|
|
<pre class="program"> ESCAPE_TABLE = { '&'=>'&amp;', '<'=>'&lt;', '>'=>'&gt;', '"'=>'&quot;', "'"=>'&#039;', }
|
|
def h(value)
|
|
value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] }
|
|
end
|
|
</pre>
|
|
<p> Notice that the new definition may be slow if string contains
|
|
many '< > & "' characters because block is call many time.
|
|
You should use ERB::Util.html_hscape() if string contains a lot of '< > & "'
|
|
characters.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="topics"></a>
|
|
<h2 class="section1">Other Topics</h2>
|
|
<a name="'<%= =%>' and '<%= -%>'"></a>
|
|
<h3 class="section2">'<%= =%>' and '<%= -%>'</h3>
|
|
<p>Since 2.6.0, '<%= -%>' remove tail spaces and newline.
|
|
This is for compatibiliy with ERB when trim mode is '-'.
|
|
'<%= =%>' also removes tail spaces and newlines, and this is
|
|
Erubis-original enhancement (cooler than '<%= -%>', isn't it?).
|
|
</p>
|
|
<a name="tailnewline.rhtml.comment_filter"></a>
|
|
<div class="program_caption">
|
|
tailnewline.rhtml</div>
|
|
<pre class="program"><div>
|
|
<%= @var -%> # or <%= @var =%>
|
|
</div>
|
|
</pre>
|
|
<div class="terminal_caption">
|
|
result (version 2.5.0):</div>
|
|
<pre class="terminal">$ erubis -c '{var: "AAA\n"}' tailnewline.rhtml
|
|
<div>
|
|
AAA
|
|
|
|
</div>
|
|
</pre>
|
|
<a name="tail_260.result"></a>
|
|
<div class="terminal_caption">
|
|
result (version 2.6.0):</div>
|
|
<pre class="terminal">$ erubis -c '{var: "AAA\n"}' tailnewline.rhtml
|
|
<div>
|
|
AAA
|
|
</div>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="'<%% %>' and '<%%= %>'"></a>
|
|
<h3 class="section2">'<%% %>' and '<%%= %>'</h3>
|
|
<p>Since 2.6.0, '<%% %>' and '<%%= %>' are converted into '<% %>' and '<%= %>' respectively.
|
|
This is for compatibility with ERB.
|
|
</p>
|
|
<div class="program_caption">
|
|
doublepercent.rhtml:</div>
|
|
<pre class="program"><ul>
|
|
<%% for item in @list %>
|
|
<li><%%= item %></li>
|
|
<%% end %>
|
|
</ul>
|
|
</pre>
|
|
<div class="terminal_caption">
|
|
result:</div>
|
|
<pre class="terminal">$ erubis doublepercent.rhtml
|
|
<ul>
|
|
<% for item in @list %>
|
|
<li><%= item %></li>
|
|
<% end %>
|
|
</ul>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topics-context-vs-binding"></a>
|
|
<h3 class="section2">evaluate(context) v.s. result(binding)</h3>
|
|
<p>It is recommended to use 'Erubis::Eruby#evaluate(context)' instead of 'Erubis::Eruby#result(binding)' because Ruby's Binding object has some problems.
|
|
</p>
|
|
<ul type="disc">
|
|
<li>It is not able to specify variables to use.
|
|
Using binding() method, all of local variables are passed to templates.
|
|
</li>
|
|
<li>Changing local variables in templates may affect to varialbes in main program.
|
|
If you assign '10' to local variable 'x' in templates, it may change variable 'x' in main program unintendedly.
|
|
</li>
|
|
</ul>
|
|
<p>The following example shows that assignment of some values into variable 'x' in templates affect to local variable 'x' in main program unintendedly.
|
|
</p>
|
|
<a name="template1.rhtml"></a>
|
|
<div class="program_caption">
|
|
template1.rhtml (intended to be passed 'items' from main program)</div>
|
|
<pre class="program"><% for <strong>x</strong> in <strong>items</strong> %>
|
|
item = <%= x %>
|
|
<% end %>
|
|
** debug: local variables=<%= local_variables().inspect() %>
|
|
</pre>
|
|
<a name="main_program1.rb"></a>
|
|
<div class="program_caption">
|
|
main_program1.rb (intended to pass 'items' to template)</div>
|
|
<pre class="program">require 'erubis'
|
|
eruby = Erubis::Eruby.new(File.read('template1.rhtml'))
|
|
items = ['foo', 'bar', 'baz']
|
|
x = 1
|
|
## local variable 'x' and 'eruby' are passed to template as well as 'items'!
|
|
print <strong>eruby.result(binding())</strong>
|
|
## local variable 'x' is changed unintendedly because it is changed in template!
|
|
puts "** debug: x=#{x.inspect}" #=> "baz"
|
|
</pre>
|
|
<a name="main_program1.result"></a>
|
|
<div class="terminal_caption">
|
|
Result:</div>
|
|
<pre class="terminal">$ ruby main_program1.rb
|
|
item = foo
|
|
item = bar
|
|
item = baz
|
|
** debug: local variables=["eruby", "items", "x", "_buf"]
|
|
** debug: x="baz"
|
|
</pre>
|
|
<p>This problem is caused because Ruby's Binding class is poor to use in template engine.
|
|
Binding class should support the following features.
|
|
</p>
|
|
<pre class="program">b = Binding.new # create empty Binding object
|
|
b['x'] = 1 # set local variables using binding object
|
|
</pre>
|
|
<p>But the above features are not implemented in Ruby.
|
|
</p>
|
|
<p>A pragmatic solution is to use 'Erubis::Eruby#evaluate(context)' instead of 'Erubis::Eruby#result(binding)'.
|
|
'evaluate(context)' uses Erubis::Context object and instance variables instead of Binding object and local variables.
|
|
</p>
|
|
<a name="template2.rhtml"></a>
|
|
<div class="program_caption">
|
|
template2.rhtml (intended to be passed '@items' from main program)</div>
|
|
<pre class="program"><% for <strong>x</strong> in <strong>@items</strong> %>
|
|
item = <%= x %>
|
|
<% end %>
|
|
** debug: local variables=<%= local_variables().inspect() %>
|
|
</pre>
|
|
<a name="main_program2.rb"></a>
|
|
<div class="program_caption">
|
|
main_program2.rb (intended to pass '@items' to template)</div>
|
|
<pre class="program">require 'erubis'
|
|
eruby = Erubis::Eruby.new(File.read('template2.rhtml'))
|
|
items = ['foo', 'bar', 'baz']
|
|
x = 1
|
|
## only 'items' are passed to template
|
|
print <strong>eruby.evaluate(:items=>items)</strong>
|
|
## local variable 'x' is not changed!
|
|
puts "** debug: x=#{x.inspect}" #=> 1
|
|
</pre>
|
|
<a name="main_program2.result"></a>
|
|
<div class="terminal_caption">
|
|
Result:</div>
|
|
<pre class="terminal">$ ruby main_program2.rb
|
|
item = foo
|
|
item = bar
|
|
item = baz
|
|
** debug: local variables=["_context", "x", "_buf"]
|
|
** debug: x=1
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topics-fasteruby"></a>
|
|
<h3 class="section2">Class Erubis::FastEruby</h3>
|
|
<p>[experimental]
|
|
</p>
|
|
<p>Erubis provides Erubis::FastEruby class which includes <a href="#interpolation-enhancer">InterpolationEnhancer</a> and <a href="#topics-benchmark">works faster than Erubis::Eruby class</a>.
|
|
If you desire more speed, try Erubis::FastEruby class.
|
|
</p>
|
|
<a name="fasteruby.rhtml"></a>
|
|
<div class="program_caption">
|
|
File 'fasteruby.rhtml':</div>
|
|
<pre class="program"><html>
|
|
<body>
|
|
<h1><%== @title %></h1>
|
|
<table>
|
|
<% i = 0 %>
|
|
<% for item in @list %>
|
|
<% i += 1 %>
|
|
<tr>
|
|
<td><%= i %></td>
|
|
<td><%== item %></td>
|
|
</tr>
|
|
<% end %>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<a name="fasteruby.rb"></a>
|
|
<div class="program_caption">
|
|
File 'fasteruby.rb':</div>
|
|
<pre class="program">require 'erubis'
|
|
input = File.read('fasteruby.rhtml')
|
|
eruby = <strong>Erubis::FastEruby.new(input)</strong> # create Eruby object
|
|
|
|
puts "---------- script source ---"
|
|
puts eruby.src
|
|
|
|
puts "---------- result ----------"
|
|
context = { :title=>'Example', :list=>['aaa', 'bbb', 'ccc'] }
|
|
output = eruby.evaluate(context)
|
|
print output
|
|
</pre>
|
|
<a name="fasteruby.result"></a>
|
|
<div class="terminal_caption">
|
|
output</div>
|
|
<pre class="terminal">$ ruby fasteruby.rb
|
|
---------- script source ---
|
|
_buf = ''; _buf << <strong>%Q`</strong><html>
|
|
<body>
|
|
<h1><strong>#{Erubis::XmlHelper.escape_xml( @title )}</strong></h1>
|
|
<table>\n<strong>`</strong>
|
|
i = 0
|
|
for item in @list
|
|
i += 1
|
|
_buf << <strong>%Q`</strong> <tr>
|
|
<td><strong>#{ i }</strong></td>
|
|
<td><strong>#{Erubis::XmlHelper.escape_xml( item )}</strong></td>
|
|
</tr>\n<strong>`</strong>
|
|
end
|
|
_buf << <strong>%Q`</strong> </table>
|
|
</body>
|
|
</html>\n<strong>`</strong>
|
|
_buf.to_s
|
|
---------- result ----------
|
|
<html>
|
|
<body>
|
|
<h1>Example</h1>
|
|
<table>
|
|
<tr>
|
|
<td>1</td>
|
|
<td>aaa</td>
|
|
</tr>
|
|
<tr>
|
|
<td>2</td>
|
|
<td>bbb</td>
|
|
</tr>
|
|
<tr>
|
|
<td>3</td>
|
|
<td>ccc</td>
|
|
</tr>
|
|
</table>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topics-syntax"></a>
|
|
<h3 class="section2">Syntax Checking</h3>
|
|
<p>Command-line option '-z' checks syntax. It is similar to 'erubis -x file.rhtml | ruby -wc', but it can take several file names.
|
|
</p>
|
|
<div class="terminal_caption">
|
|
example of command-line option '-z'</div>
|
|
<pre class="terminal">$ erubis <strong>-z</strong> app/views/*/*.rhtml
|
|
Syntax OK
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topics-caching"></a>
|
|
<h3 class="section2">File Caching</h3>
|
|
<p>Erubis::Eruby.load_file(filename) convert file into Ruby script and return Eruby object.
|
|
In addition, it caches converted Ruby script into cache file (filename + '.cache') if cache file is old or not exist.
|
|
If cache file exists and is newer than eruby file, Erubis::Eruby.load_file() loads cache file.
|
|
</p>
|
|
<div class="program_caption">
|
|
example of Erubis::Eruby.load_file()</div>
|
|
<pre class="program">require 'erubis'
|
|
filename = 'example.rhtml'
|
|
eruby = <strong>Erubis::Eruby.load_file(filename)</strong>
|
|
cachename = filename + '.cache'
|
|
if test(?f, cachename)
|
|
puts "*** cache file '#{cachename}' created."
|
|
end
|
|
</pre>
|
|
<p>Since 2.6.0, it is able to specify cache filename.
|
|
</p>
|
|
<div class="program_caption">
|
|
specify cache filename.</div>
|
|
<pre class="program">filename = 'example.rhtml'
|
|
eruby = Erubis::Eruby.load_file(filename, :cachename=>filename+'.cache')
|
|
</pre>
|
|
<p>Caching makes Erubis about 40-50 percent faster than no-caching.
|
|
See <a href="#topics-benchmark">benchmark</a> for details.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="topics-tinyeruby"></a>
|
|
<h3 class="section2">Erubis::TinyEruby class</h3>
|
|
<p>Erubis::TinyEruby class in 'erubis/tiny.rb' is the smallest implementation of eRuby.
|
|
If you don't need any enhancements of Erubis and only require simple eRuby implementation,
|
|
try Erubis::TinyEruby class.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="topics-php"></a>
|
|
<h3 class="section2">NoTextEnhancer and NoCodeEnhancer in PHP</h3>
|
|
<p>NoTextEnhancer and NoCodEnahncer are quite useful not only for eRuby but also for PHP.
|
|
The former "drops" HTML text and show up embedded Ruby/PHP code
|
|
and the latter drops embedded Ruby/PHP code and leave HTML text.
|
|
</p>
|
|
<p>For example, see the following PHP script.
|
|
</p>
|
|
<a name="notext-example.php"></a>
|
|
<div class="program_caption">
|
|
notext-example.php</div>
|
|
<pre class="program"><html>
|
|
<body>
|
|
<h3>List</h3>
|
|
<?php if (!$list || count($list) == 0) { ?>
|
|
<p>not found.</p>
|
|
<?php } else { ?>
|
|
<table>
|
|
<tbody>
|
|
<?php $i = 0; ?>
|
|
<?php foreach ($list as $item) { ?>
|
|
<tr bgcolor="<?php echo ++$i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'; ?>">
|
|
<td><?php echo $item; ?></td>
|
|
</tr>
|
|
<?php } ?>
|
|
</tbody>
|
|
</table>
|
|
<?php } ?>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
<p>This is complex because PHP code and HTML document are mixed.
|
|
NoTextEnhancer can separate PHP code from HTML document.
|
|
</p>
|
|
<a name="notext-php.result"></a>
|
|
<div class="terminal_caption">
|
|
example of using NoTextEnhancer with PHP file</div>
|
|
<pre class="terminal">$ erubis -l php --pi=php -N -E NoText --trim=false notext-example.php
|
|
1:
|
|
2:
|
|
3:
|
|
4: <?php if (!$list || count($list) == 0) { ?>
|
|
5:
|
|
6: <?php } else { ?>
|
|
7:
|
|
8:
|
|
9: <?php $i = 0; ?>
|
|
10: <?php foreach ($list as $item) { ?>
|
|
11: <?php echo ++$i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'; ?>
|
|
12: <?php echo $item; ?>
|
|
13:
|
|
14: <?php } ?>
|
|
15:
|
|
16:
|
|
17: <?php } ?>
|
|
18:
|
|
19:
|
|
</pre>
|
|
<p>In the same way, NoCodeEnhancer can extract HTML tags.
|
|
</p>
|
|
<a name="nocode-php.result"></a>
|
|
<div class="terminal_caption">
|
|
example of using NoCodeEnhancer with PHP file</div>
|
|
<pre class="terminal">$ erubis -l php --pi=php -N -E NoCode --trim=false notext-example.php
|
|
1: <html>
|
|
2: <body>
|
|
3: <h3>List</h3>
|
|
4:
|
|
5: <p>not found.</p>
|
|
6:
|
|
7: <table>
|
|
8: <tbody>
|
|
9:
|
|
10:
|
|
11: <tr bgcolor="">
|
|
12: <td></td>
|
|
13: </tr>
|
|
14:
|
|
15: </tbody>
|
|
16: </table>
|
|
17:
|
|
18: </body>
|
|
19: </html>
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topcs-modruby"></a>
|
|
<h3 class="section2">Helper Class for mod_ruby</h3>
|
|
<p>Thanks Andrew R Jackson, he developed 'erubis-run.rb' which enables you to use Erubis with mod_ruby.
|
|
</p>
|
|
<ol type="1">
|
|
<li>Copy 'erubis-2.6.5/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.
|
|
<pre class="terminal">$ cd erubis-2.6.5/
|
|
$ sudo copy contrib/erubis-run.rb /usr/local/lib/ruby/1.8/apache/
|
|
</pre>
|
|
</li>
|
|
<li>Add the following example to your 'httpd.conf' (for example '/usr/local/apache2/conf/httpd.conf')
|
|
<pre class="program">LoadModule ruby_module modules/mod_ruby.so
|
|
<IfModule mod_ruby.c>
|
|
RubyRequire apache/ruby-run
|
|
RubyRequire apache/eruby-run
|
|
RubyRequire apache/erubis-run
|
|
<Location /erubis>
|
|
SetHandler ruby-object
|
|
RubyHandler Apache::ErubisRun.instance
|
|
</Location>
|
|
<Files *.rhtml>
|
|
SetHandler ruby-object
|
|
RubyHandler Apache::ErubisRun.instance
|
|
</Files>
|
|
</IfModule>
|
|
</pre>
|
|
</li>
|
|
<li>Restart Apache web server.
|
|
<pre class="terminal">$ sudo /usr/local/apache2/bin/apachectl stop
|
|
$ sudo /usr/local/apache2/bin/apachectl start
|
|
</pre>
|
|
</li>
|
|
<li>Create *.rhtml file, for example:
|
|
<pre class="program"><html>
|
|
<body>
|
|
Now is <%= Time.now %>
|
|
Erubis version is <%= Erubis::VERSION %>
|
|
</body>
|
|
</html>
|
|
</pre>
|
|
</li>
|
|
<li>Change mode of your directory to be writable by web server process.
|
|
<pre class="terminal">$ cd /usr/local/apache2/htdocs/erubis
|
|
$ sudo chgrp daemon .
|
|
$ sudo chmod 775 .
|
|
</pre>
|
|
</li>
|
|
<li>Access the *.rhtml file and you'll get the web page.
|
|
</li>
|
|
</ol>
|
|
<p>You must set your directories to be writable by web server process, because
|
|
Apache::ErubisRun calls Erubis::Eruby.load_file() internally which creates cache files
|
|
in the same directory in which '*.rhtml' file exists.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="topics-defmethod"></a>
|
|
<h3 class="section2">Define method</h3>
|
|
<p>Erubis::Eruby#def_method() defines instance method or singleton method.
|
|
</p>
|
|
<a name="def_method.rb"></a>
|
|
<pre class="program">require 'erubis'
|
|
s = "hello <%= name %>"
|
|
eruby = Erubis::Eruby.new(s)
|
|
filename = 'hello.rhtml'
|
|
|
|
## define instance method to Dummy class (or module)
|
|
class Dummy; end
|
|
<strong>eruby.def_method(Dummy, 'render(name)', filename)</strong> # filename is optional
|
|
p Dummy.new.render('world') #=> "hello world"
|
|
|
|
## define singleton method to dummy object
|
|
obj = Object.new
|
|
<strong>eruby.def_method(obj, 'render(name)', filename)</strong> # filename is optional
|
|
p obj.render('world') #=> "hello world"
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<a name="topics-benchmark"></a>
|
|
<h3 class="section2">Benchmark</h3>
|
|
<p>A benchmark script is included in Erubis package at 'erubis-2.6.5/benchark/' directory.
|
|
Here is an example result of benchmark.
|
|
</p>
|
|
<div class="terminal_caption">
|
|
MacOS X 10.4 Tiger, Intel CoreDuo 1.83GHz, Ruby1.8.6, eruby1.0.5, gcc4.0.1</div>
|
|
<pre class="terminal">$ cd erubis-2.6.5/benchmark/
|
|
$ ruby bench.rb -n 10000 -m execute
|
|
*** ntimes=10000, testmode=execute
|
|
user system total real
|
|
eruby 12.720000 0.240000 <strong>12.960000</strong> ( 12.971888)
|
|
ERB 36.760000 0.350000 <strong>37.110000</strong> ( 37.112019)
|
|
ERB(cached) 11.990000 0.440000 <strong>12.430000</strong> ( 12.430375)
|
|
Erubis::Eruby 10.840000 0.300000 <strong>11.140000</strong> ( 11.144426)
|
|
Erubis::Eruby(cached) 7.540000 0.410000 <strong>7.950000</strong> ( 7.969305)
|
|
Erubis::FastEruby 10.440000 0.300000 <strong>10.740000</strong> ( 10.737808)
|
|
Erubis::FastEruby(cached) 6.940000 0.410000 <strong>7.350000</strong> ( 7.353666)
|
|
Erubis::TinyEruby 9.550000 0.290000 9.840000 ( 9.851729)
|
|
Erubis::ArrayBufferEruby 11.010000 0.300000 11.310000 ( 11.314339)
|
|
Erubis::PrintOutEruby 11.640000 0.290000 11.930000 ( 11.942141)
|
|
Erubis::StdoutEruby 11.590000 0.300000 11.890000 ( 11.886512)
|
|
</pre>
|
|
<p>This shows that...
|
|
</p>
|
|
<ul type="disc">
|
|
<li>Erubis::Eruby runs more than 10 percent faster than eruby.
|
|
</li>
|
|
<li>Erubis::Eruby runs about 3 times faster than ERB.
|
|
</li>
|
|
<li>Caching (by Erubis::Eruby.load_file()) makes Erubis about 40-50 percent faster.
|
|
</li>
|
|
<li>Erubis::FastEruby is a litte faster than Erubis::Eruby.
|
|
</li>
|
|
<li>Array buffer (ArrayBufferEnhancer) is a little slower than string buffer (StringBufferEnhancer which Erubis::Eruby includes)
|
|
</li>
|
|
<li>$stdout and print() make Erubis a little slower.
|
|
</li>
|
|
<li>Erubis::TinyEruby (at 'erubis/tiny.rb') is the fastest in all eRuby implementations when no caching.
|
|
</li>
|
|
</ul>
|
|
<p>Escaping HTML characters (such as '< > & "') makes Erubis more faster than eruby and ERB,
|
|
because Erubis::XmlHelper#escape_xml() works faster than CGI.escapeHTML() and ERB::Util#h().
|
|
The following shows that Erubis runs more than 40 percent (when no-cached) or 90 percent (when cached) faster than eruby if HTML characters are escaped.
|
|
</p>
|
|
<div class="terminal_caption">
|
|
When escaping HTML characters with option '-e'</div>
|
|
<pre class="terminal">$ ruby bench.rb -n 10000 -m execute -ep
|
|
*** ntimes=10000, testmode=execute
|
|
user system total real
|
|
eruby 21.700000 0.290000 <strong>21.990000</strong> ( 22.050687)
|
|
ERB 45.140000 0.390000 <strong>45.530000</strong> ( 45.536976)
|
|
ERB(cached) 20.340000 0.470000 <strong>20.810000</strong> ( 20.822653)
|
|
Erubis::Eruby 14.830000 0.310000 <strong>15.140000</strong> ( 15.147930)
|
|
Erubis::Eruby(cached) 11.090000 0.420000 <strong>11.510000</strong> ( 11.514954)
|
|
Erubis::FastEruby 14.850000 0.310000 <strong>15.160000</strong> ( 15.172499)
|
|
Erubis::FastEruby(cached) 10.970000 0.430000 <strong>11.400000</strong> ( 11.399605)
|
|
Erubis::ArrayBufferEruby 14.970000 0.300000 15.270000 ( 15.281061)
|
|
Erubis::PrintOutEruby 15.780000 0.300000 16.080000 ( 16.088289)
|
|
Erubis::StdoutEruby 15.840000 0.310000 16.150000 ( 16.235338)
|
|
</pre>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<a name="command"></a>
|
|
<h2 class="section1">Command Reference</h2>
|
|
<a name="command-usage"></a>
|
|
<h3 class="section2">Usage</h3>
|
|
<p>erubis [..options..] [<em>file</em> ...]
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<a name="command-options"></a>
|
|
<h3 class="section2">Options</h3>
|
|
<dl class="dl3" compact>
|
|
<dt class="dt3"><b>
|
|
-h, --help </b></dt>
|
|
<dd class="dd3">
|
|
Help.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-v </b></dt>
|
|
<dd class="dd3">
|
|
Release version.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-x </b></dt>
|
|
<dd class="dd3">
|
|
Show compiled source.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-X </b></dt>
|
|
<dd class="dd3">
|
|
Show compiled source but only Ruby code.
|
|
This is equivarent to '-E NoText'.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-N </b></dt>
|
|
<dd class="dd3">
|
|
Numbering: add line numbers. (for '-x/-X')
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-U </b></dt>
|
|
<dd class="dd3">
|
|
Unique mode: zip empty lines into a line. (for '-x/-X')
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-C </b></dt>
|
|
<dd class="dd3">
|
|
Compact: remove empty lines. (for '-x/-X')
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-b </b></dt>
|
|
<dd class="dd3">
|
|
Body only: no preamble nor postamble. (for '-x/-X')
|
|
This is equivarent to '--preamble=false --postamble=false'.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-z </b></dt>
|
|
<dd class="dd3">
|
|
Syntax checking.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-e </b></dt>
|
|
<dd class="dd3">
|
|
Escape. This is equivarent to '-E Escape'.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-p pattern </b></dt>
|
|
<dd class="dd3">
|
|
Embedded pattern (default '<% %>').
|
|
This is equivarent to '--pattern=<em>pattern</em>'.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-l lang </b></dt>
|
|
<dd class="dd3">
|
|
Language name.
|
|
This option makes erubis command to compile script but no execute.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-E enhacers </b></dt>
|
|
<dd class="dd3">
|
|
Enhancer name (Escape, PercentLine, ...).
|
|
It is able to specify several enhancer name separating with ','
|
|
(ex. -f Escape,PercentLine,HeaderFooter).
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-I path </b></dt>
|
|
<dd class="dd3">
|
|
Require library path ($:).
|
|
It is able to specify several paths separating with ','
|
|
(ex. -f path1,path2,path3).
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-K kanji </b></dt>
|
|
<dd class="dd3">
|
|
Kanji code (euc, sjis, utf8, or none) (default none).
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-f datafile </b></dt>
|
|
<dd class="dd3">
|
|
Context data file in YAML format ('*.yaml', '*.yml') or
|
|
Ruby script ('*.rb').
|
|
It is able to specify several filenames separating with ','
|
|
(ex. -f file1,file2,file3).
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-c context </b></dt>
|
|
<dd class="dd3">
|
|
Context data string in YAML inline style or Ruby code.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-T </b></dt>
|
|
<dd class="dd3">
|
|
Don't expand tab characters in YAML file.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-S </b></dt>
|
|
<dd class="dd3">
|
|
Convert mapping key from string to symbol in YAML file.
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
-B </b></dt>
|
|
<dd class="dd3">
|
|
invoke Eruby#result() instead of Eruby#evaluate()
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
--pi[=name] </b></dt>
|
|
<dd class="dd3">
|
|
parse '<?name ... ?>' instead of '<% ... %>'
|
|
</dd>
|
|
<dt class="dt3"><b>
|
|
--trim=false </b></dt>
|
|
<dd class="dd3">
|
|
No trimming spaces around '<% %>'.
|
|
</dd>
|
|
</dl>
|
|
<br>
|
|
|
|
|
|
<a name="command-props"></a>
|
|
<h3 class="section2">Properties</h3>
|
|
<p>Some Eruby classes can take optional properties to change it's compile option.
|
|
For example, property '--indent=" "' may change indentation of compiled source code.
|
|
Try 'erubis -h' for details.
|
|
</p>
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
</div>
|
|
</blockquote>
|
|
|
|
</body>
|
|
</html>
|