/External.LCA_RESTRICTED/Languages/Ruby/ruby19/lib/ruby/gems/1.9.1/gems/erubis-2.6.6/doc/users-guide.html
HTML | 3286 lines | 3057 code | 229 blank | 0 comment | 0 complexity | 82a50bbe1552bf9bf0ed09a0ea043ad5 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
- <!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">
- release: 2.6.6<br>
- last update: $Date$<br>
- </div>
- <p>release: 2.6.6
- </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.6/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.6/
- $ 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.6/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.6/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>