BabyErubis.rb
$Release: 2.0.0 $
BabyErubis is an yet another eRuby implementation, based on Erubis.
- Small and fast
- Easy to customize
- Supports HTML as well as plain text
- Accepts both template file and template string
- Supports Ruby on Rails template
BabyErubis supports Ruby >= 1.8 and Rubinius >= 2.0.
Examples
Render template string:
require 'baby_erubis'
template = BabyErubis::Html.new.from_str <<'END', __FILE__, __LINE__+1
<h1><%= @title %></h1>
<% for item in @items %>
<p><%= item %></p>
<% end %>
END
context = {:title=>'Example', :items=>['A', 'B', 'C']}
output = template.render(context)
print output
Render template file:
require 'baby_erubis'
templat = BabyErubis::Html.new.from_file('example.html.erb', 'utf-8')
context = {:title=>'Example', :items=>['A', 'B', 'C']}
output = template.render(context)
print output
(Use BabyErubis::Text
instead of BabyErubis::Html
when rendering plain text.)
Command-line examples (see baby_erubis.rb --help
for details):
## convert eRuby file into Ruby code
$ baby_erubis -x file.erb # text
$ baby_erubis -xH file.erb # html
$ baby_erubis -X file.erb # embedded code only
## render eRuby file with context data
$ baby_erubis -c '{items: [A, B, C]}' file.erb # YAML
$ baby_erubis -c '@items=["A","B","C"]' file.erb # Ruby
$ baby_erubis -f data.yaml file.erb # or -f *.json, *.rb
## debug eRuby file
$ baby_erubis -xH file.erb | ruby -wc # check syntax error
$ baby_erubis -XHNU file.erb # show embedded ruby code
Template Syntax
<% ... %>
: Ruby statement<%= ... %>
: Ruby expression with escaping<%== ... %>
: Ruby expression without escaping
Expression in <%= ... %>
is escaped according to template class.
BabyErubis::Text
doesn't escape anything. It justs converts expression into a string.BabyErubis::Html
escapes html special characters. It converts< > & " '
into< > & " '
respectively.
(Experimental) <%- ... -%>
and <%-= ... -%>
are handled same as
<% ... %>
and <%= ... %>
respectively.
(Experimental) Block argument expression supported since version 2.0. Example:
## template
<%== form_for(:article) do |f| %>
...
<% end %>
## compiled ruby code
_buf << form_for(:article) do |f| _buf << '
...
'; end;
Advanced Topics
Template Context
When rendering template, you can pass not only Hash object but also any object
as context values. Internally, rendering method converts Hash object into
BabyErubis::TemplateContext
object automatically.
Example:
require 'baby_erubis'
class MyApp
include BabyErubis::HtmlEscaper # necessary to define escape()
TEMPLATE = BabyErubis::Html.new.from_str <<-'END', __FILE__, __LINE__+1
<html>
<body>
<p>Hello <%= @name %>!</p>
</body>
</html>
END
def initialize(name)
@name = name
end
def render()
return TEMPLATE.render(self) # use self as context object
end
end
if __FILE__ == $0
print MyApp.new('World').render()
end
String#freeze()
BabyErubis supports String#freeze() automatically when on Ruby version >= 2.1. And you can control whether to use freeze() or not.
template_str = <<'END'
<div>
<b><%= message %></b>
</div>
END
## don't use freeze()
t = BabyErubis::Text.new(:freeze=>false).from_str(template_str)
print t.src
# --- result ---
# _buf = ''; _buf << '<div>
# <b>'; _buf << (message).to_s; _buf << '</b>
# </div>
# '; _buf.to_s
## use freeze() forcedly
t = BabyErubis::Text.new(:freeze=>true).from_str(template_str)
print t.src
# --- result ---
# _buf = ''; _buf << '<div>
# <b>'.freeze; _buf << (message).to_s; _buf << '</b>
# </div>
# '.freeze; _buf.to_s
Ruby on Rails Template
BabyErubis::RailsTemplate
class generates Rails-style ruby code.
require 'baby_erubis'
require 'baby_erubis/rails'
t = BabyErubis::RailsTemplate.new.from_str <<'END'
<div>
<%= form_for :article do |f| %>
...
<% end %>
</div>
END
print t.src
Result:
@output_buffer = output_buffer || ActionView::OutputBuffer.new;@output_buffer.safe_append='<div>
';@output_buffer.append= form_for :article do |f| ;@output_buffer.safe_append='
...
'.freeze; end;
@output_buffer.safe_append='</div>
';@output_buffer.to_s
You can check syntax of Rails template in command-line:
$ baby_erubis -Rx app/views/articles/index.html.erb | ruby -wc
(TODO: How to use BabyErubis in Ruby on Rails instead of Erubis)
Customizing
Change Embed Pattern from '<% %>' to '%'
Sample code:
require 'baby_erubis'
class MyTemplate < BabyErubis::Html
rexp = BabyErubis::Template::PATTERN
PATTERN = Regexp.compile(rexp.to_s.sub(/<%/, '\{%').sub(/%>/, '%\}'))
def pattern
PATTERN
end
end
template = MyTemplate.new <<-'END'
{% for item in @items %}
- {%= item %}
{% end %}
END
print template.render(:items=>['A', 'B', 'C'])
Output:
- A
- B
- C
Strip Spaces in HTML Template
Sample code:
require 'baby_erubis'
class MyTemplate < BabyErubis::Html
def parse(input, *args)
stripped = input.gsub(/^[ \t]+</, '<')
return super(stripped, *args)
end
end
template = MyTemplate.new <<-'END'
<html>
<body>
<p>Hello <%= @name %>!</p>
</body>
</html>
END
print template.render(:name=>"Hello")
Output:
<html>
<body>
<p>Hello Hello!</p>
</body>
</html>
Layout Template
Sample code:
require 'baby_erubis'
class MyApp
include BabyErubis::HtmlEscaper # necessary to define escape()
LAYOUT = BabyErubis::Html.new.from_str <<-'END', __FILE__, __LINE__+1
<html>
<body>
<% _buf << @_content %> # or <%== @_content %>
</body>
</html>
END
TEMPLATE = BabyErubis::Html.new.from_str <<-'END', __FILE__, __LINE__+1
<p>Hello <%= @name %>!</p>
END
def initialize(name)
@name = name
end
def render()
@_content = TEMPLATE.render(self)
return LAYOUT.render(self)
end
end
if __FILE__ == $0
print MyApp.new('World').render()
end
Output:
<html>
<body>
<p>Hello World!</p>
</body>
</html>
Template Cache File
Sample code:
require 'baby_erubis'
require 'logger'
$logger = Logger.new(STDERR)
class MyTemplate < BabyErubis::Html
def from_file(filename, encoding='utf-8')
cachefile = "#{filename}.cache"
= File.mtime(filename)
has_cache = File.file?(cachefile) && File.mtime(cachefile) ==
if has_cache
$logger.info("loading template from cache file: #{cachefile}")
ruby_code = File.open(cachefile, "rb:#{encoding}") {|f| f.read }
compile(ruby_code, filename, 1)
else
super(filename, encoding)
$logger.info("creating template cache file: #{cachefile}")
ruby_code = self.src
tmpname = "#{cachefile}.#{rand().to_s[2,5]}"
File.open(tmpname, "wb:#{encoding}") {|f| f.write(ruby_code) }
File.utime(, , tmpname)
File.rename(tmpname, cachefile)
end
return self
end
end
p File.exist?('example.html.erb.cache') #=> false
t = MyTemplate.new.from_file('example.html.erb')
p File.exist?('example.html.erb.cache') #=> true
Todo
- [Done] Support Rails syntax (=
<%= form_for do |f| %>
)
Changes
Release 2.0.0 (2014-12-09)
- [enhance] Ruby on Rails template support
- [enhance] Block argument expression support
- [enhance] New command-line option '-R' and '--format=rails'
Release 1.0.0 (2014-05-17)
- [enhance] Provides script file
bin/baby_erubis
. - [enhance] Supports Ruby 1.8 and Rubinius 2.x.
- [change] Define 'BabyErubis::RELEASE'.
- [bugfix] 'Template#render()' creates context object when nil passed.
Release 0.1.0 (2014-05-06)
- Public release
License
$License: MIT License $
Copyright
$Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $