Using Template Spec

Why and When

Amrita2 needs a Template Spec to compile a HTML template to Ruby modules. If it was not given, TO will generate a default Spec and use it for compiling.

When the default Spec is not enough under situations below, you can give a manually made Spec to TO.

And I'm planing to solve performance problems by using Specs later.

How to use Template Spec

--- ../sample/spec/spec.rb ---
require "amrita2/template"
include Amrita2

class PO
  def title
    "hello world"
  end

  def body
    "Amrita2 is a html template libraly for Ruby"
  end
end

TEMPLATE_TEXT = <<END
<html>
   <body>
      <h1 id='title'>title will be inserted here</h1>
      <p>body text will be inserted here</p>
   </body>
</html>
END


tmpl = TemplateText.new(TEMPLATE_TEXT) do
  Amrita2::define_template_spec do 
    dynamic_element(:title)
    dynamic_element(:body, :matcher=>HtmlTag::P)
  end
end
tmpl.expand(STDOUT, PO.new)

__END__
<html>
   <body>
      <h1 id='title'>hello world</h1>
      <p>Amrita2 is a html template libraly for Ruby</p>
   </body>
</html>

Replacing Attribute of Elements in Template

--- ../sample/spec/attr.rb ---
require "amrita2/template"
include Amrita2


TEMPLATE_TEXT = <<END
<html>
   <body>
     <h1><a id='a1'>replacing attributes</a></h1>
     <p>See <a id='a2' href='http://www.ruby-lang.org/'>Ruby homepage</a> for detail</p>
     <a id='rubytalk' href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/$1">[ruby-talk:$1]</a>
     <a id='raa' href="http://raa.ruby-lang.org/list.rhtml?name=$1">[$2]</a>
   </body>
</html>
END

# You need to use template spec for replacing attribute values
# There are three ways for it.
tmpl = TemplateText.new(TEMPLATE_TEXT) do
  Amrita2::define_template_spec do 
    dynamic_element(:a1, :replace_attr=>true)
    dynamic_element(:a2, :use_original_element=>true)
    dynamic_element(:rubytalk, :use_args=>true)
    dynamic_element(:raa, :use_args=>true)
  end
end
class PO
  def a1(m)
    # replace_attr: optional Hash will be merged to attributes
    m.a1('replaced', :href=>'http://amrita2.rubyforge.org/')
  end

  def a2(m)
    # use_original_element: REXML::Element object for the spec
    # will be passed. Edit it and return it or make a new
    # Element object and return it.
    m.a2 do |e|
      e.text += "(Japanese)"
      e.attributes['href'] += 'ja/'
      e
    end
  end

  def rubytalk(m)
    # use_args: the value passed will be replaced $1, $2.....
    m.rubytalk(132204)
  end

  def raa(m)
    m.raa('amrita', 'amrita: HTML template library')
  end
end

tmpl.expand(STDOUT, PO.new)

__END__
# The result is
<html>
   <body>
     <h1><a href='http://amrita2.rubyforge.org/' id='a1'>replaced</a></h1>
     <p>See <a href='http://www.ruby-lang.org/ja/' id='a2'>Ruby homepage(Japanese)</a> for detail</p>
     <a href='http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/132204'>[ruby-talk:132204]</a>
     <a href='http://raa.ruby-lang.org/list.rhtml?name=amrita'>[amrita: HTML template library]</a>
   </body>
</html>

Using Amrita2 with Template without id attributes

--- ../sample/spec/matcher.rb ---
require "amrita2/template"
include Amrita2
include Amrita2::Core

class PO
  def title
    "hello world"
  end

  def body
    "Amrita2 is a html template libraly for Ruby"
  end

  def ulist
    { 
      :item1=>1,
      :item2=>2,
      :item3=>3
    }
  end
end

# Amrita2 can use template without id attributes
TEMPLATE_TEXT = <<END
<html>
   <body>
      <h1 class='title'>title will be inserted here</h1>
      <p>body text will be inserted here</p>
      <ul>
        <li></li>
        <li></li>
        <li>line3</li>
      </ul>
   </body>
</html>
END

# user defined matcher
class TextMatcher < Matcher
  def initialize(text)
    @text = text
  end

  def match(e)
    e.text == @text
  end
end

tmpl = TemplateText.new(TEMPLATE_TEXT) do
  Amrita2::define_template_spec do 
    # match with element with attribute class='title'
    dynamic_element(:title, :matcher=>AttrMatcher.new(:class, 'title'))
    # match with tag <p>
    dynamic_element(:body, :matcher=>HtmlTag::P)
    # match with tag <ul>
    dynamic_element(:ulist, :matcher=>TagMatcher.new(:ul)) do 
      # match with tag <li>
      dynamic_element(:item1, :matcher=>HtmlTag::LI)
      # match any element 
      dynamic_element(:item2, :matcher=>AnyMatcher.new)
      # match with element with text 'line3'
      dynamic_element(:item3, :matcher=>TextMatcher.new('line3'))
    end
  end
end
tmpl.expand(STDOUT, PO.new)

__END__
<html>
   <body>
      <h1 class='title'>hello world</h1>
      <p>Amrita2 is a html template libraly for Ruby</p>
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
      </ul>
   </body>
</html>

Using Expand by Member feature

--- ../sample/spec/member.rb ---
require "amrita2/template"
include Amrita2


TEMPLATE_TEXT = <<END
<html>
<body>
<table id='flist'>
  <tr>
    <th>name</th>
    <th>size</th>
    <th>ctime</th>
    <th>mtime</th>
  </tr>
  <tr id='item'>
    <td id='name' />
    <td align='right' id='size' />
    <td id='ctime' />
    <td id='mtime' />
  </tr>
</table>
</body>
</html>
END

# add an attr to standard class File::Stat 
class File
  class Stat
    attr_accessor :name
  end
end


class PO
  def flist(m)
    m.flist do |mf| 
      Dir['*'].each do |f|
        stat = File::stat(f)
        stat.name = f
        mf.item(stat)
      end
    end
  end
end

tmpl = TemplateText.new(TEMPLATE_TEXT) do
  Amrita2::define_template_spec do 
    dynamic_element(:flist) do
      dynamic_element(:item, :expand_by_member=>true) do 
        dynamic_element(:name)
        dynamic_element(:size)
        dynamic_element(:ctime)
        dynamic_element(:mtime)
      end
    end
  end
end

tmpl.expand(STDOUT, PO.new)
__END__


   name     size            ctime                        mtime
spec.rb      519 Wed Mar 02 17:04:31 JST 2005 Wed Mar 02 16:18:42 JST 2005
matcher.rb  1395 Wed Mar 02 17:04:31 JST 2005 Wed Mar 02 16:38:15 JST 2005
attr.rb     1890 Wed Mar 02 17:04:31 JST 2005 Wed Mar 02 17:02:55 JST 2005
member.rb   1804 Wed Mar 02 17:28:24 JST 2005 Wed Mar 02 17:28:24 JST 2005

Using Tables

Using <dl>