SlideShare una empresa de Scribd logo
1 de 64
Descargar para leer sin conexión
RubyKaigi2009




 All about Erubis
 And the future of template system


makoto kuwata <kwa@kuwata-lab.com>
     http://www.kuwata-lab.com/




    copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                            1
I have something to say at first...

  ‣ Thank you for all staff of RubyKaigi!
  ‣ Thank you for all audience who join this
    session!




               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       2
Agenda

  ‣ Part 1.   Features of Erubis
  ‣ Part 2.Issues about eRuby and solutions
    by Erubis
  ‣ Part 3.   Future of template system




              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      3
Part 1. Features of Erubis



      copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                              4
Introduction to Erubis

   ‣ Pure Ruby implementation of eRuby
   ‣ Very fast
     • http://jp.rubyist.net/magazine/?0022-FasterThanC
   ‣ Highly functional
     • HTML escape in default
     • Changing embedded pattern
     • Support PHP, Java, JS, C, Perl, Scheme
     • and so on...
             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     5
Basically Usage
 Ruby program:
  require 'rubygems'        # if need
  require 'erubis'
  str = File.read('template.eruby')
  eruby = Erubis::Eruby.new(str)
  print eruby.result(binding())
 command-line:
  $ erubis template.eruby # execute
  $ erubis -x template.eruby # convert into Ruby
  $ erubis -z template.eruby # syntax check

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     6
HTML Escape in Default
  str =<<END           <%= %> ... WITH escaping,
  <%= var %>           <%== %> ... WITHOUT escaping
  <%== var %>
  END
  eruby = Erubis::Eruby.new(str, :escape=>true)
  puts eruby.result(:var=>"<B&B>")

 output:
  &lt;B&am;&gt;                  User can choose escape or not
  <B&B>                          escape in default (choosability)


             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     7
Changing Embedded Pattern

   ‣ ex : use '[% %]' instead of '<% %>'
  [% for x in @list %]
   <li>[%= x %]</li>
                                           You must escape regexp meta
  [% end %]
                                             characters by backslash!
  ## Ruby
  Erubis::Eruby.new(str, :pattern=>'[% %]')
  ## command-line
  $ erubis -p '[% %]' file.eruby

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                         8
Use Hash or Object instead of Binding
example of using Hash                      example of using Object
hash = {                                   @title = "Example"
  :title => "Example",                     @items = [1, 2, 3]
  :items => [1, 2, 3], }                   erubis =
erubis =                                     Erubis::Eruby.new(str)
  Erubis::Eruby.new(str)                   puts erubis.evaluate(self)
puts erubis.result(hash)

<h1><%= title%></h1>                        <h1><%= @title%></h1>
<% for x in items %>                        <% for x in @items %>
<% end %>                                   <% end %>
              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                        9
Enhancer
 ‣ Ruby modules which enhances Erubis features
   ## do HTML escape <%= %> in default
   module EscapeEnhancer
     def add_expr(src, code, indicator)
       if indicator == '='
          src << " _buf<<escapeXml(#{code})"
       elsif indicator == '=='
          src << " _buf<<(#{code}).to_s;"
       end
     end          It is easy to override Erubis features
                  because internal of Erubis is splitted into
   end            many small methods.
                copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                        10
Enhancer (cont')

  ### Enhance which prints into stdout
  ### (you can use print() in statements)
  module StdoutEnhancer              use _buf=$stdout
    def add_preamble(src)            instead of _buf=""
     src << "_buf = $stdout;"
    end
    def add_postamble(src)
     src << "n""n"
    end                      use "" (empty string)
  end                         instead of _buf.to_s

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      11
Usage of Enhancer

                          All you have to do is to include
  ### Ruby                or extend ehnacer modules
  class MyEruby < Erubis::Eruby
     include Erubis::EscapeEnhancer
     include Erubis::PercentLineEnhancer
  end
  puts MyEruby.new(str).result(:items=>[1,2,3])

                                                Specify names with ','
  ### command-line
  $ erubis -E Escape,Percent file.eruby

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                         12
Standard Enhancers

 ‣ EscapeEnhancer : escape html in default
 ‣ PercentLineEnhancer : recognize lines starting with '%' as
   embedded statements
 ‣ InterporationEnhancer : use _buf<<"#{expr}" for speed
 ‣ DeleteIndentEnhancer : delete HTML indentation
 ‣ StdoutEnhancer : use _buf=$stdout instead of _buf=""
 ‣ ... and so on (you can show list of all by erubis -h)

                copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                        13
Context Data

    ‣ You can specify data to pass into template
      file (context data) in command-line

### command-line
$ erubis -c '{arr: [A, B, C]}' template.eruby # YAML
$ erubis -c '@arr=%w[A B C]' template.eruby # Ruby

 <% for x in @arr %>                                 <li>A</li>
 <li><%= x %></li>                                   <li>B</li>
 <% end %>                                           <li>C</li>

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     14
Context Data File

    ‣ Load '*.yaml' or '*.rb' as context data file
  $ erubis -f data.yaml template.eruby # YAML
  $ erubis -f data.rb template.eruby # Ruby
  data.yaml                            data.rb
   title: Example                       @title = "Example"
   items:                               @items =
     - name: Foo                         [ {"name"=>"Foo"},
     - name: Bar                           {"name"=>"Bar"}, ]

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      15
Debug Print

   ‣ <%=== expr %> represents debug print

  <%=== @var %>                                    No need to write the
                                                  same expression twice
  ### Ruby code
  $stderr.puts("*** debug: @var=#{@var.inspect}")

  ### Result
  *** debug: @var=["A", "B", "C"]


             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                          16
Support Other Programming Langs

 ‣ PHP, Java, JS, C, Perl,Scheme (only for convertion)
  <% for (i=0; i<n; i++) { %>         (example of C)
  <li><%= "%d", i %>
  <% } %>                 same format as printf()


  #line 1 "file.ec"        (output of erubis -xl c file.ec)
   for (i=0; i<n; i++) {
  fputs("<li>", stdout); fprintf(stdout, "%d", i);
  fputs("n", stdout); }

               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       17
Conslution

   ‣ Erubis is very functional and extensible
     • HTML escape in default
     • Changing embedded pattern
     • Enhancer
     • Context data and file
     • Debug print
     • Support PHP, Java, JS, C, Perl, and Scheme

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     18
Part 2. Issues about eRuby
 and solutions by Erubis


      copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                              19
Issue : local variables can be changed

   ‣ When using binding(), local variables can be
     non-local
      • Difficult to find if exists

i=0                                                   ### file.erb
str = File.read('file.erb')                            <% for i in 1..3 %>
ERB.new(str).result(binding)                          <li><%= i %></li>
p i #=> 3                                             <% end %>
          Changed insidiously!

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                            20
Cause of the issue

   ‣ binding() passes all local variables into
     template file
     • It is impossible to pass only variables which you
       truly want to pass
     • It is hard to recognize what variables are passed

    b = Bingind.new                                           This is ideal
    b[:title] = "Example"                                   but impossible...
    b[:items] = [1, 2, 3]

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                21
Solution by ERB

   ‣ Nothing, but the author of ERB introduced a
    solution to define custom Struct
     • http://d.hatena.ne.jp/m_seki/20080528/1211909590

     Foo = Struct.new(:title, :items)
     class Foo
      def env; binding(); end
     end
     ctx = Foo.new("Example", [1,2,3])
     ERB.new(str).result(ctx.env)
            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                    22
Solution by Erubis

   ‣ Use Hash instead of Binding
                                                            It is very clear what
 erubis.result(:items=>[1, 2, 3])                              data are passed!

 def result(b=TOPLEVEL_BINDING)
   if b.is_a?(Hash)
      s = b.collect{|k,v| "#{k}=b[#{k.inspect}];"}.join
      b = binding()
      eval s, b            Set hash values as local vars
   end                      with creating new Binding
   return eval(@src, b)
 end
              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                    23
Solution by Erubis (cont')

   ‣ Use Object instead of Binding
    @items = [1, 2, 3];                 <% for x in @items %>
    erubis.evaluate(self)               <% end %>

    def evaluate(ctx)                              Convert Hash values into
      if ctx.is_a?(Hash)                                   instance variables
         hash = ctx; ctx = Object.new
         hash.each {|k,v|
           ctx.instance_variable_set("@#{k}", v) }
      end
      return ctx.instance_eval(@src)
    end       copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                24
Issue : cost of convertion and parsing
                  ERB
1. 8.6   Erubis::Eruby

                  ERB
1. 8.7   Erubis::Eruby

                  ERB
1.9.1    Erubis::Eruby
                           0                   10                   20     30
                                                                           (sec)
    Costs of parsing and                                   Execution
    convertion are higher                                  Parsing(by eval)
    than of execution                                      Convertion(eRuby to Ruby)
                copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                   25
Solution by ERB

   ‣ Convertion cost : nothing
   ‣ Parsing cost : helper to define method
      • Usage is much different from normal usage
   class Foo
      extend ERB::DefMethod
      def_erb_method('render', 'template.erb')
   end
   print Foo.new.render

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     26
Solution by Erubis

  ‣ Convertion cost : cache Ruby code into file
    • 1st time : save converted Ruby code into *.cache file
    • 2nd time : read ruby code from *.cache file


   eruby = Erubis::Eruby.load_file("file.eruby")
   print eruby.result()
                         Available even in CGI


              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      27
Solution by Erubis (cont')

   ‣ Parsing cost : keep ruby code as Proc object
      • The same way to use
      • Almost the same speed as defining method

                                                    instance_eval can take a
   def evaluate(ctx)                                Proc object as argument
     @proc ||= eval(@src)                           instead of string (ruby code)
     ctx.instance_eval(@proc)
   end

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                28
Issue: extra line breaks

    ‣ eRuby outpus extra line breaks
       • Big problem for non-HTML text

               Extra line break                      <ul>
 <ul>
 <% for x in @list %>                                   <li>AAA</li>
  <li><%= x %></li>
 <% end %>                                              <li>BBB</li>
 </ul>
            Extra line break
                                                     </ul>
               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       29
Solution by ERB
   ‣ Provides various trim mode
     • ">" : removes LF at the end of line
     • "<>" : removes LF if "<%" is at the beginning of line
             and "%>" is at the end of line
     • "-" : removes extra spaces and LF around
             "<%-" and "-%>"
     • "%" : regard lines starting with "%" as embedded
             statements
     • "%>", "%<>", "-" : combination of "%" and
                                  ">"/"<>"/"-"

      ERB.new(str, nil, "%<>")
             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     30
Solution by Erubis

   ‣ Change operation between embedded
     statement and expression
     • <% stmt %> : remove spaces around it
     • <%= expr %> : do nothing (leave as it is)
    <ul>     Remove!                                      <ul>
    <% for x in @list %>                                    AAA
      <%= x %>                                              BBB
    <% end %>                                               CCC
    </ul>         Leave as it is                          </ul>

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     31
Comparison of solutions

                                 ERB                                Erubis

   eRuby spec
   compatible
                              × spec)                       (compatible)
                        (extends
      Spec
    simplicity
                            × opts)                      (only one rule)
                      (too much
      Easy to
    implement
                             ×                               (very easy)
                         (complicated)

            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                             32
Hint to think

   ‣ "Extra line breaks" problem has been
     recognized since early times
      • [ruby-list:18894] extra LF in output of eRuby
   ‣ Nobody hit on the idea of changing
     operations between stmts and exprs
      • Everybody looks <% %> and <%= %> as same
      • It is important to recoginize two things which
       looks to be the same things as different things

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      33
Issue : Escape HTML in default

   ‣ <%= expr %> should be HTML escaped in
     default!
      • But eRuby is not only for HTML but also for all
       of text file
     • However security is the most important thing
   ‣ How to do when not to escape?


                copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                        34
Solution by ERB

  ‣ Nothing for officially
  ‣ Unofficial solution
    • Define a certain class which represents HTML string
      (not to escape) separately from String class
    • http://www2a.biglobe.ne.jp/~seki/ruby/erbquote.html




             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     35
Solution by Erubis

   ‣ Enhance embedded pattern and Erubis class
     • Fast, and easy to implement

   eruby = Erubis::Eruby.new(str, :escape=>true)
   # or eruby = Erubis::EscapedEruby.new(str)
   puts eruby.evaluate(ctx)


    Hi <%= @name %>! # with escape
    Hi <%== @name %>! # without escape

            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                    36
Issue : hard to find syntax error
   <% unless @items.blank? %>
   <table>
    <tbody>
      <% @items.each do |item| %>
      <tr class="item" id="item-<%=item.id%>">
        <td class="item-id"><%= item.id %></td>
        <td class="item-name">
          <% if item.url && !item.url.empty? %>
          <a href="<%= item.url %>"><%=item.name%></a>
          <% else %>
          <span><%=item.name%></span>
          <% end %>
        </td>
      </tr>                       •    HTML and Ruby code are mixed
      <% end %>                   •    It is hard to recognize corresponding
    </tbody>
   </table>
                                       'end' (because 'do' and 'end' can be
   <% end %>                           separated 100 lines for example)

                  copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                               37
Solution by ERB

   ‣ Nothing but '-x' option
   $ erb -x foo.eruby
   _erbout = ''; unless @items.blank? ;
   _erbout.concat "n"
   _erbout.concat "<table>n"
   _erbout.concat " <tr class="record">n"

   $ erb -x foo.eruby | ruby -wc
   Syntax OK
            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                    38
Solution by Erubis

   ‣ Provides a lot of command-line options
     • -x :   show Ruby script
     • -X :   suppress to print HTML
     • -N :   print line numbers
     • -U :   unify consecutive empty lines into a line
     • -C :   remove consecutive empty lines (compact)
     • -z :   check template syntax


               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       39
$ cat foo.eruby
<% unless @items.blank? %>
<table>
 <% @items.each_with_index do|x, i| %>
 <tr class="record">
   <td><%= i +1 %></td>
   <td><%=h x %></td>
 </tr>
 <% end %>
</table>
<% end %>


         copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                 40
-x : show Ruby script
$ erubis -x foo.eruby
_buf = ''; unless @items.blank?
 _buf << '<table>
'; @items.each_with_index do|x, i|
 _buf << ' <tr class="record">
    <td>'; _buf << ( i +1 ).to_s; _buf << '</td>
    <td>'; _buf << (h x ).to_s; _buf << '</td>
  </tr>
'; end
 _buf << '</table>
'; end
_buf.to_s

           copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                    41
-X : suppress to print HTML
$ erubis -X foo.eruby
_buf = ''; unless @items.blank?

 @items.each_with_index do|x, i|

       _buf << ( i +1 ).to_s;
       _buf << (h x ).to_s;

 end

 end
_buf.to_s

            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                          42
-N : print line numbers
$ erubis -XN foo.eruby
   1: _buf = ''; unless @items.blank?
   2:
   3: @items.each_with_index do|x, i|
   4:
   5:       _buf << ( i +1 ).to_s;
   6:       _buf << (h x ).to_s;
   7:
   8: end
   9:
  10: end
  11: _buf.to_s

          copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                        43
-U : unifiy consecutive empty
                                                 lines into a line
$ erubis -XNU foo.eruby
   1: _buf = ''; unless @items.blank?

  3:   @items.each_with_index do|x, i|

  5:         _buf << ( i +1 ).to_s;
  6:         _buf << (h x ).to_s;

  8:   end

 10: end
 11: _buf.to_s

          copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                           44
-C : remove empty lines
                                                   (compact)
$ erubis -XNC foo.eruby
   1: _buf = ''; unless @items.blank?
   3: @items.each_with_index do|x, i|
   5:       _buf << ( i +1 ).to_s;
   6:       _buf << (h x ).to_s;
   8: end
  10: end
  11: _buf.to_s




          copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       45
Issue : expr can contain statements

     embed return value of
   helper method by <%= %>
                                                        block contains
                                                          statements
   <%= form_for :user do %>
    <div>
     <%= text_field :name %>
    </div>
   <% end %>                 beyond of
                            eRuby spec!

           copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                         46
Cause of Issue

   <%= 10.times do %>
   Hello                                     <%= expr %> is expected
   <% end %>                                 to be completed by itself

             Convert
                                                         Syntax error!
   _buf = "";
   _buf << ( 10.times do ).to_s;
   _buf << " Hellon";
    end
             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                         47
Solution by ERB+Rails

   ‣ Change local variable (_erbout) on caller-
     size from callee-side                                                    agic!!
                                                                     b lack m

                                             Append to '_erbout' from
  Not use <%= %>                              internal of form_for()

<% form_for do %>                          _erbout = ""
Hello                                      form_for do
<% end %>                                   _erbout.concat("Hello")
                                           end

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                       48
Solution by Erubis+Merb

   ‣ Extend parser of Erubis
     Recognize blok in
      embedded expr

<%= form_for do %>                           @_buf << (form_for do;
Hello                                        @_buf << "Hellon"
<% end =%>                                   end);

    Introduce end-of-                                    Change _buf into
      block notation                                     instance variable
             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                             49
Discussion

   ‣ Extend spec of eRuby
   ‣ Not use black magic (kool!)
   ‣ Available only for helper method, in fact
     • It is required to manipulate @_buf from internal
       of helper method

   ‣ Difficult to provide general solution

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     50
Conslusion

   ‣ A lot of issues around eRuby!
     • Extra line breaks
     • Local variables are not local
     • Difficult to specify context variable
     • Large cost for convertion and parsing
     • HTML escape in default
     • Difficult to find syntax error
     • Can't embed return value of method with block

            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                    51
Part 3. Future of template
          system


      copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                              52
Template and Programming

    ‣ Template is also program code
<ul>                                            print "<ul>n"
<% for x in @a %>                               for x in @a
 <li><%=x%></li>             Equiv.             print "<li>#{x}</li>n"
<% end %>                                       end
</ul>                                           print "</u>n"


           Possible to apply programming techniques
           or concepts to template system
            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                          53
Template and Method

      Template is a kind of
       method definition

 <ul>                                 s = File.read('foo.eruby')
 <li><%=x%></li>                      e = Erubis::Eruby.new(s)
 </ul>                                puts e.evaluate(:x=>1)

                                                   Context data is actual
     Rendering template is a                       argument for method
    kind of method invokation

            copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                            54
Template and formal argument

   ‣ Formal arguments may be necessary for
     template

 <%#ARGS: items, name='guest' %>
 Hello <%= name %>!
 <% for x in items %>
 <li><%=x%></li>      • Clear context variables
 <% end %>            • Available default value


             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     55
Template and modularity
    ‣ Also HTML should be Small & Many, not
      Single & Large
       • Same as principle of method definition
 <html>                                            <html>              Be benefit for
                                                   <body>                designer!
 <body>                                            </body>
  <h1><%=@title%></h1>                             </html>
  <ul id="menulist">
                                    split
   <% for x in @items %>                           <h1><%=@title%></h1>
   <li><%=x%></li>                                 <ul id="menulist">
                                                   </ul>
   <% end %>
  </ul>                                            <% for x in @items %>
 </body>                                            <li><%= x %></li>
 </html>                                           <% end %>
               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                                       56
Template and Object-Oriented

    ‣ Template inheritance in Django
Parent template
 ....
                                                    Available to overwrite
 {% block pagetitle %}
                                                    or add contents
 <h1>{{title}}</h1>                                 before/after
 {% endblock %}                                     (method override)
 ....


              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                             57
Template and Aspect-Oriented

   ‣ Weave some code into other program
     • Similar to layer of Photoshop
 <table>
            "for x in @a"                            •Enable to split HTML
  <tr>                                                and presentation
   <td>     "print x"                                 logics
                                                     •Available to insert a
  </tr>                                               logic into several
            "end"                                     points (DRY)
 </table>

             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                              58
Template and Data Type

 ‣ End is coming to escape HTML in view layer
   • forget to escape, helper method argument, ...
 ‣ HTML should be different data type from String
  (http://www.oiwa.jp/~yutaka/tdiary/20051229.html)
   • No need to take care to escape or not
   • Prior art : str and unicode in Python
   • "HTML + String" should be String? or HTML?
   • Other escaping also should be considered (ex. SQL)

              copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                      59
Conslusion

   ‣ Template is also programming code
   ‣ Available to apply programming techniques
     and concepts into template system
      • Formal argument, Inheritance, AOP, and so on
   ‣ Template system is still on developing stage



             copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                     60
Bibliography

 ‣ Introduction to Template System (in Japanese)
    • http://jp.rubyist.net/magazine/?0024-TemplateSystem
    • http://jp.rubyist.net/magazine/?0024-TemplateSystem2
 ‣ Erubis
    • http://www.kuwata-lab.com/erubis/
 ‣ Benchmarks of many template systems
    • http://www.kuwata-lab.com/tenjin/

               copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                       61
one more thing

   copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                           62
Tenjin - template engine replacing eRuby

 ‣ Both ERB and Erubis are out of date
    • They are merely text-processor
    • Less features as template engine
 ‣ Tenjin : replacer of ERB/Erubis
    • Designed and implemented as template engine from the
     beginning
    • Provides a lot of features required for template engines
      - layout template, partial template, and so on
    • http://www.kuwata-lab.com/tenjin/
                 copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                                         63
thank you

 copyright(c) 2009 kuwata-lab.com all rights reserved.
                                                         64

Más contenido relacionado

La actualidad más candente

Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)Qiangning Hong
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
 
Advanced python
Advanced pythonAdvanced python
Advanced pythonEU Edge
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung Kim
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)Uri Laserson
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchinaguestcf9240
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaLin Yo-An
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPatrick Allaert
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Kris Wallsmith
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 

La actualidad más candente (20)

Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
 
Python高级编程(二)
Python高级编程(二)Python高级编程(二)
Python高级编程(二)
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
 
Ruby 2.0
Ruby 2.0Ruby 2.0
Ruby 2.0
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Perl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim PerlchinaPerl.Hacks.On.Vim Perlchina
Perl.Hacks.On.Vim Perlchina
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Ow2 webinar erocci
Ow2 webinar erocciOw2 webinar erocci
Ow2 webinar erocci
 

Similar a All about Erubis (English)

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyNick Sieger
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceJesse Vincent
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...Amazon Web Services
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkDaniel Spector
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails IntroductionThomas Fuchs
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbaiaadi Surve
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHiroshi SHIBATA
 
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Muhamad Al Imran
 
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Muhamad Al Imran
 

Similar a All about Erubis (English) (20)

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRuby
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
Gun make
Gun makeGun make
Gun make
 
New features in Ruby 2.5
New features in Ruby 2.5New features in Ruby 2.5
New features in Ruby 2.5
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...
Distributed, Incremental Dataflow Processing on AWS with GRAIL's Reflow (CMP3...
 
lab4_php
lab4_phplab4_php
lab4_php
 
lab4_php
lab4_phplab4_php
lab4_php
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbai
 
C++ Core Guidelines
C++ Core GuidelinesC++ Core Guidelines
C++ Core Guidelines
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby Core
 
Php i basic chapter 3
Php i basic chapter 3Php i basic chapter 3
Php i basic chapter 3
 
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
Php i basic chapter 3 (syahir chaer's conflicted copy 2013-04-22)
 
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
Php i basic chapter 3 (afifah rosli's conflicted copy 2013-04-23)
 

Más de kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方kwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するkwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapperkwatch
 

Más de kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapper
 

Último

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 

Último (20)

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

All about Erubis (English)

  • 1. RubyKaigi2009 All about Erubis And the future of template system makoto kuwata <kwa@kuwata-lab.com> http://www.kuwata-lab.com/ copyright(c) 2009 kuwata-lab.com all rights reserved. 1
  • 2. I have something to say at first... ‣ Thank you for all staff of RubyKaigi! ‣ Thank you for all audience who join this session! copyright(c) 2009 kuwata-lab.com all rights reserved. 2
  • 3. Agenda ‣ Part 1. Features of Erubis ‣ Part 2.Issues about eRuby and solutions by Erubis ‣ Part 3. Future of template system copyright(c) 2009 kuwata-lab.com all rights reserved. 3
  • 4. Part 1. Features of Erubis copyright(c) 2009 kuwata-lab.com all rights reserved. 4
  • 5. Introduction to Erubis ‣ Pure Ruby implementation of eRuby ‣ Very fast • http://jp.rubyist.net/magazine/?0022-FasterThanC ‣ Highly functional • HTML escape in default • Changing embedded pattern • Support PHP, Java, JS, C, Perl, Scheme • and so on... copyright(c) 2009 kuwata-lab.com all rights reserved. 5
  • 6. Basically Usage Ruby program: require 'rubygems' # if need require 'erubis' str = File.read('template.eruby') eruby = Erubis::Eruby.new(str) print eruby.result(binding()) command-line: $ erubis template.eruby # execute $ erubis -x template.eruby # convert into Ruby $ erubis -z template.eruby # syntax check copyright(c) 2009 kuwata-lab.com all rights reserved. 6
  • 7. HTML Escape in Default str =<<END <%= %> ... WITH escaping, <%= var %> <%== %> ... WITHOUT escaping <%== var %> END eruby = Erubis::Eruby.new(str, :escape=>true) puts eruby.result(:var=>"<B&B>") output: &lt;B&am;&gt; User can choose escape or not <B&B> escape in default (choosability) copyright(c) 2009 kuwata-lab.com all rights reserved. 7
  • 8. Changing Embedded Pattern ‣ ex : use '[% %]' instead of '<% %>' [% for x in @list %] <li>[%= x %]</li> You must escape regexp meta [% end %] characters by backslash! ## Ruby Erubis::Eruby.new(str, :pattern=>'[% %]') ## command-line $ erubis -p '[% %]' file.eruby copyright(c) 2009 kuwata-lab.com all rights reserved. 8
  • 9. Use Hash or Object instead of Binding example of using Hash example of using Object hash = { @title = "Example" :title => "Example", @items = [1, 2, 3] :items => [1, 2, 3], } erubis = erubis = Erubis::Eruby.new(str) Erubis::Eruby.new(str) puts erubis.evaluate(self) puts erubis.result(hash) <h1><%= title%></h1> <h1><%= @title%></h1> <% for x in items %> <% for x in @items %> <% end %> <% end %> copyright(c) 2009 kuwata-lab.com all rights reserved. 9
  • 10. Enhancer ‣ Ruby modules which enhances Erubis features ## do HTML escape <%= %> in default module EscapeEnhancer def add_expr(src, code, indicator) if indicator == '=' src << " _buf<<escapeXml(#{code})" elsif indicator == '==' src << " _buf<<(#{code}).to_s;" end end It is easy to override Erubis features because internal of Erubis is splitted into end many small methods. copyright(c) 2009 kuwata-lab.com all rights reserved. 10
  • 11. Enhancer (cont') ### Enhance which prints into stdout ### (you can use print() in statements) module StdoutEnhancer use _buf=$stdout def add_preamble(src) instead of _buf="" src << "_buf = $stdout;" end def add_postamble(src) src << "n""n" end use "" (empty string) end instead of _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 11
  • 12. Usage of Enhancer All you have to do is to include ### Ruby or extend ehnacer modules class MyEruby < Erubis::Eruby include Erubis::EscapeEnhancer include Erubis::PercentLineEnhancer end puts MyEruby.new(str).result(:items=>[1,2,3]) Specify names with ',' ### command-line $ erubis -E Escape,Percent file.eruby copyright(c) 2009 kuwata-lab.com all rights reserved. 12
  • 13. Standard Enhancers ‣ EscapeEnhancer : escape html in default ‣ PercentLineEnhancer : recognize lines starting with '%' as embedded statements ‣ InterporationEnhancer : use _buf<<"#{expr}" for speed ‣ DeleteIndentEnhancer : delete HTML indentation ‣ StdoutEnhancer : use _buf=$stdout instead of _buf="" ‣ ... and so on (you can show list of all by erubis -h) copyright(c) 2009 kuwata-lab.com all rights reserved. 13
  • 14. Context Data ‣ You can specify data to pass into template file (context data) in command-line ### command-line $ erubis -c '{arr: [A, B, C]}' template.eruby # YAML $ erubis -c '@arr=%w[A B C]' template.eruby # Ruby <% for x in @arr %> <li>A</li> <li><%= x %></li> <li>B</li> <% end %> <li>C</li> copyright(c) 2009 kuwata-lab.com all rights reserved. 14
  • 15. Context Data File ‣ Load '*.yaml' or '*.rb' as context data file $ erubis -f data.yaml template.eruby # YAML $ erubis -f data.rb template.eruby # Ruby data.yaml data.rb title: Example @title = "Example" items: @items = - name: Foo [ {"name"=>"Foo"}, - name: Bar {"name"=>"Bar"}, ] copyright(c) 2009 kuwata-lab.com all rights reserved. 15
  • 16. Debug Print ‣ <%=== expr %> represents debug print <%=== @var %> No need to write the same expression twice ### Ruby code $stderr.puts("*** debug: @var=#{@var.inspect}") ### Result *** debug: @var=["A", "B", "C"] copyright(c) 2009 kuwata-lab.com all rights reserved. 16
  • 17. Support Other Programming Langs ‣ PHP, Java, JS, C, Perl,Scheme (only for convertion) <% for (i=0; i<n; i++) { %> (example of C) <li><%= "%d", i %> <% } %> same format as printf() #line 1 "file.ec" (output of erubis -xl c file.ec) for (i=0; i<n; i++) { fputs("<li>", stdout); fprintf(stdout, "%d", i); fputs("n", stdout); } copyright(c) 2009 kuwata-lab.com all rights reserved. 17
  • 18. Conslution ‣ Erubis is very functional and extensible • HTML escape in default • Changing embedded pattern • Enhancer • Context data and file • Debug print • Support PHP, Java, JS, C, Perl, and Scheme copyright(c) 2009 kuwata-lab.com all rights reserved. 18
  • 19. Part 2. Issues about eRuby and solutions by Erubis copyright(c) 2009 kuwata-lab.com all rights reserved. 19
  • 20. Issue : local variables can be changed ‣ When using binding(), local variables can be non-local • Difficult to find if exists i=0 ### file.erb str = File.read('file.erb') <% for i in 1..3 %> ERB.new(str).result(binding) <li><%= i %></li> p i #=> 3 <% end %> Changed insidiously! copyright(c) 2009 kuwata-lab.com all rights reserved. 20
  • 21. Cause of the issue ‣ binding() passes all local variables into template file • It is impossible to pass only variables which you truly want to pass • It is hard to recognize what variables are passed b = Bingind.new This is ideal b[:title] = "Example" but impossible... b[:items] = [1, 2, 3] copyright(c) 2009 kuwata-lab.com all rights reserved. 21
  • 22. Solution by ERB ‣ Nothing, but the author of ERB introduced a solution to define custom Struct • http://d.hatena.ne.jp/m_seki/20080528/1211909590 Foo = Struct.new(:title, :items) class Foo def env; binding(); end end ctx = Foo.new("Example", [1,2,3]) ERB.new(str).result(ctx.env) copyright(c) 2009 kuwata-lab.com all rights reserved. 22
  • 23. Solution by Erubis ‣ Use Hash instead of Binding It is very clear what erubis.result(:items=>[1, 2, 3]) data are passed! def result(b=TOPLEVEL_BINDING) if b.is_a?(Hash) s = b.collect{|k,v| "#{k}=b[#{k.inspect}];"}.join b = binding() eval s, b Set hash values as local vars end with creating new Binding return eval(@src, b) end copyright(c) 2009 kuwata-lab.com all rights reserved. 23
  • 24. Solution by Erubis (cont') ‣ Use Object instead of Binding @items = [1, 2, 3]; <% for x in @items %> erubis.evaluate(self) <% end %> def evaluate(ctx) Convert Hash values into if ctx.is_a?(Hash) instance variables hash = ctx; ctx = Object.new hash.each {|k,v| ctx.instance_variable_set("@#{k}", v) } end return ctx.instance_eval(@src) end copyright(c) 2009 kuwata-lab.com all rights reserved. 24
  • 25. Issue : cost of convertion and parsing ERB 1. 8.6 Erubis::Eruby ERB 1. 8.7 Erubis::Eruby ERB 1.9.1 Erubis::Eruby 0 10 20 30 (sec) Costs of parsing and Execution convertion are higher Parsing(by eval) than of execution Convertion(eRuby to Ruby) copyright(c) 2009 kuwata-lab.com all rights reserved. 25
  • 26. Solution by ERB ‣ Convertion cost : nothing ‣ Parsing cost : helper to define method • Usage is much different from normal usage class Foo extend ERB::DefMethod def_erb_method('render', 'template.erb') end print Foo.new.render copyright(c) 2009 kuwata-lab.com all rights reserved. 26
  • 27. Solution by Erubis ‣ Convertion cost : cache Ruby code into file • 1st time : save converted Ruby code into *.cache file • 2nd time : read ruby code from *.cache file eruby = Erubis::Eruby.load_file("file.eruby") print eruby.result() Available even in CGI copyright(c) 2009 kuwata-lab.com all rights reserved. 27
  • 28. Solution by Erubis (cont') ‣ Parsing cost : keep ruby code as Proc object • The same way to use • Almost the same speed as defining method instance_eval can take a def evaluate(ctx) Proc object as argument @proc ||= eval(@src) instead of string (ruby code) ctx.instance_eval(@proc) end copyright(c) 2009 kuwata-lab.com all rights reserved. 28
  • 29. Issue: extra line breaks ‣ eRuby outpus extra line breaks • Big problem for non-HTML text Extra line break <ul> <ul> <% for x in @list %> <li>AAA</li> <li><%= x %></li> <% end %> <li>BBB</li> </ul> Extra line break </ul> copyright(c) 2009 kuwata-lab.com all rights reserved. 29
  • 30. Solution by ERB ‣ Provides various trim mode • ">" : removes LF at the end of line • "<>" : removes LF if "<%" is at the beginning of line and "%>" is at the end of line • "-" : removes extra spaces and LF around "<%-" and "-%>" • "%" : regard lines starting with "%" as embedded statements • "%>", "%<>", "-" : combination of "%" and ">"/"<>"/"-" ERB.new(str, nil, "%<>") copyright(c) 2009 kuwata-lab.com all rights reserved. 30
  • 31. Solution by Erubis ‣ Change operation between embedded statement and expression • <% stmt %> : remove spaces around it • <%= expr %> : do nothing (leave as it is) <ul> Remove! <ul> <% for x in @list %> AAA <%= x %> BBB <% end %> CCC </ul> Leave as it is </ul> copyright(c) 2009 kuwata-lab.com all rights reserved. 31
  • 32. Comparison of solutions ERB Erubis eRuby spec compatible × spec) (compatible) (extends Spec simplicity × opts) (only one rule) (too much Easy to implement × (very easy) (complicated) copyright(c) 2009 kuwata-lab.com all rights reserved. 32
  • 33. Hint to think ‣ "Extra line breaks" problem has been recognized since early times • [ruby-list:18894] extra LF in output of eRuby ‣ Nobody hit on the idea of changing operations between stmts and exprs • Everybody looks <% %> and <%= %> as same • It is important to recoginize two things which looks to be the same things as different things copyright(c) 2009 kuwata-lab.com all rights reserved. 33
  • 34. Issue : Escape HTML in default ‣ <%= expr %> should be HTML escaped in default! • But eRuby is not only for HTML but also for all of text file • However security is the most important thing ‣ How to do when not to escape? copyright(c) 2009 kuwata-lab.com all rights reserved. 34
  • 35. Solution by ERB ‣ Nothing for officially ‣ Unofficial solution • Define a certain class which represents HTML string (not to escape) separately from String class • http://www2a.biglobe.ne.jp/~seki/ruby/erbquote.html copyright(c) 2009 kuwata-lab.com all rights reserved. 35
  • 36. Solution by Erubis ‣ Enhance embedded pattern and Erubis class • Fast, and easy to implement eruby = Erubis::Eruby.new(str, :escape=>true) # or eruby = Erubis::EscapedEruby.new(str) puts eruby.evaluate(ctx) Hi <%= @name %>! # with escape Hi <%== @name %>! # without escape copyright(c) 2009 kuwata-lab.com all rights reserved. 36
  • 37. Issue : hard to find syntax error <% unless @items.blank? %> <table> <tbody> <% @items.each do |item| %> <tr class="item" id="item-<%=item.id%>"> <td class="item-id"><%= item.id %></td> <td class="item-name"> <% if item.url && !item.url.empty? %> <a href="<%= item.url %>"><%=item.name%></a> <% else %> <span><%=item.name%></span> <% end %> </td> </tr> • HTML and Ruby code are mixed <% end %> • It is hard to recognize corresponding </tbody> </table> 'end' (because 'do' and 'end' can be <% end %> separated 100 lines for example) copyright(c) 2009 kuwata-lab.com all rights reserved. 37
  • 38. Solution by ERB ‣ Nothing but '-x' option $ erb -x foo.eruby _erbout = ''; unless @items.blank? ; _erbout.concat "n" _erbout.concat "<table>n" _erbout.concat " <tr class="record">n" $ erb -x foo.eruby | ruby -wc Syntax OK copyright(c) 2009 kuwata-lab.com all rights reserved. 38
  • 39. Solution by Erubis ‣ Provides a lot of command-line options • -x : show Ruby script • -X : suppress to print HTML • -N : print line numbers • -U : unify consecutive empty lines into a line • -C : remove consecutive empty lines (compact) • -z : check template syntax copyright(c) 2009 kuwata-lab.com all rights reserved. 39
  • 40. $ cat foo.eruby <% unless @items.blank? %> <table> <% @items.each_with_index do|x, i| %> <tr class="record"> <td><%= i +1 %></td> <td><%=h x %></td> </tr> <% end %> </table> <% end %> copyright(c) 2009 kuwata-lab.com all rights reserved. 40
  • 41. -x : show Ruby script $ erubis -x foo.eruby _buf = ''; unless @items.blank? _buf << '<table> '; @items.each_with_index do|x, i| _buf << ' <tr class="record"> <td>'; _buf << ( i +1 ).to_s; _buf << '</td> <td>'; _buf << (h x ).to_s; _buf << '</td> </tr> '; end _buf << '</table> '; end _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 41
  • 42. -X : suppress to print HTML $ erubis -X foo.eruby _buf = ''; unless @items.blank? @items.each_with_index do|x, i| _buf << ( i +1 ).to_s; _buf << (h x ).to_s; end end _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 42
  • 43. -N : print line numbers $ erubis -XN foo.eruby 1: _buf = ''; unless @items.blank? 2: 3: @items.each_with_index do|x, i| 4: 5: _buf << ( i +1 ).to_s; 6: _buf << (h x ).to_s; 7: 8: end 9: 10: end 11: _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 43
  • 44. -U : unifiy consecutive empty lines into a line $ erubis -XNU foo.eruby 1: _buf = ''; unless @items.blank? 3: @items.each_with_index do|x, i| 5: _buf << ( i +1 ).to_s; 6: _buf << (h x ).to_s; 8: end 10: end 11: _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 44
  • 45. -C : remove empty lines (compact) $ erubis -XNC foo.eruby 1: _buf = ''; unless @items.blank? 3: @items.each_with_index do|x, i| 5: _buf << ( i +1 ).to_s; 6: _buf << (h x ).to_s; 8: end 10: end 11: _buf.to_s copyright(c) 2009 kuwata-lab.com all rights reserved. 45
  • 46. Issue : expr can contain statements embed return value of helper method by <%= %> block contains statements <%= form_for :user do %> <div> <%= text_field :name %> </div> <% end %> beyond of eRuby spec! copyright(c) 2009 kuwata-lab.com all rights reserved. 46
  • 47. Cause of Issue <%= 10.times do %> Hello <%= expr %> is expected <% end %> to be completed by itself Convert Syntax error! _buf = ""; _buf << ( 10.times do ).to_s; _buf << " Hellon"; end copyright(c) 2009 kuwata-lab.com all rights reserved. 47
  • 48. Solution by ERB+Rails ‣ Change local variable (_erbout) on caller- size from callee-side agic!! b lack m Append to '_erbout' from Not use <%= %> internal of form_for() <% form_for do %> _erbout = "" Hello form_for do <% end %> _erbout.concat("Hello") end copyright(c) 2009 kuwata-lab.com all rights reserved. 48
  • 49. Solution by Erubis+Merb ‣ Extend parser of Erubis Recognize blok in embedded expr <%= form_for do %> @_buf << (form_for do; Hello @_buf << "Hellon" <% end =%> end); Introduce end-of- Change _buf into block notation instance variable copyright(c) 2009 kuwata-lab.com all rights reserved. 49
  • 50. Discussion ‣ Extend spec of eRuby ‣ Not use black magic (kool!) ‣ Available only for helper method, in fact • It is required to manipulate @_buf from internal of helper method ‣ Difficult to provide general solution copyright(c) 2009 kuwata-lab.com all rights reserved. 50
  • 51. Conslusion ‣ A lot of issues around eRuby! • Extra line breaks • Local variables are not local • Difficult to specify context variable • Large cost for convertion and parsing • HTML escape in default • Difficult to find syntax error • Can't embed return value of method with block copyright(c) 2009 kuwata-lab.com all rights reserved. 51
  • 52. Part 3. Future of template system copyright(c) 2009 kuwata-lab.com all rights reserved. 52
  • 53. Template and Programming ‣ Template is also program code <ul> print "<ul>n" <% for x in @a %> for x in @a <li><%=x%></li> Equiv. print "<li>#{x}</li>n" <% end %> end </ul> print "</u>n" Possible to apply programming techniques or concepts to template system copyright(c) 2009 kuwata-lab.com all rights reserved. 53
  • 54. Template and Method Template is a kind of method definition <ul> s = File.read('foo.eruby') <li><%=x%></li> e = Erubis::Eruby.new(s) </ul> puts e.evaluate(:x=>1) Context data is actual Rendering template is a argument for method kind of method invokation copyright(c) 2009 kuwata-lab.com all rights reserved. 54
  • 55. Template and formal argument ‣ Formal arguments may be necessary for template <%#ARGS: items, name='guest' %> Hello <%= name %>! <% for x in items %> <li><%=x%></li> • Clear context variables <% end %> • Available default value copyright(c) 2009 kuwata-lab.com all rights reserved. 55
  • 56. Template and modularity ‣ Also HTML should be Small & Many, not Single & Large • Same as principle of method definition <html> <html> Be benefit for <body> designer! <body> </body> <h1><%=@title%></h1> </html> <ul id="menulist"> split <% for x in @items %> <h1><%=@title%></h1> <li><%=x%></li> <ul id="menulist"> </ul> <% end %> </ul> <% for x in @items %> </body> <li><%= x %></li> </html> <% end %> copyright(c) 2009 kuwata-lab.com all rights reserved. 56
  • 57. Template and Object-Oriented ‣ Template inheritance in Django Parent template .... Available to overwrite {% block pagetitle %} or add contents <h1>{{title}}</h1> before/after {% endblock %} (method override) .... copyright(c) 2009 kuwata-lab.com all rights reserved. 57
  • 58. Template and Aspect-Oriented ‣ Weave some code into other program • Similar to layer of Photoshop <table> "for x in @a" •Enable to split HTML <tr> and presentation <td> "print x" logics •Available to insert a </tr> logic into several "end" points (DRY) </table> copyright(c) 2009 kuwata-lab.com all rights reserved. 58
  • 59. Template and Data Type ‣ End is coming to escape HTML in view layer • forget to escape, helper method argument, ... ‣ HTML should be different data type from String (http://www.oiwa.jp/~yutaka/tdiary/20051229.html) • No need to take care to escape or not • Prior art : str and unicode in Python • "HTML + String" should be String? or HTML? • Other escaping also should be considered (ex. SQL) copyright(c) 2009 kuwata-lab.com all rights reserved. 59
  • 60. Conslusion ‣ Template is also programming code ‣ Available to apply programming techniques and concepts into template system • Formal argument, Inheritance, AOP, and so on ‣ Template system is still on developing stage copyright(c) 2009 kuwata-lab.com all rights reserved. 60
  • 61. Bibliography ‣ Introduction to Template System (in Japanese) • http://jp.rubyist.net/magazine/?0024-TemplateSystem • http://jp.rubyist.net/magazine/?0024-TemplateSystem2 ‣ Erubis • http://www.kuwata-lab.com/erubis/ ‣ Benchmarks of many template systems • http://www.kuwata-lab.com/tenjin/ copyright(c) 2009 kuwata-lab.com all rights reserved. 61
  • 62. one more thing copyright(c) 2009 kuwata-lab.com all rights reserved. 62
  • 63. Tenjin - template engine replacing eRuby ‣ Both ERB and Erubis are out of date • They are merely text-processor • Less features as template engine ‣ Tenjin : replacer of ERB/Erubis • Designed and implemented as template engine from the beginning • Provides a lot of features required for template engines - layout template, partial template, and so on • http://www.kuwata-lab.com/tenjin/ copyright(c) 2009 kuwata-lab.com all rights reserved. 63
  • 64. thank you copyright(c) 2009 kuwata-lab.com all rights reserved. 64