ember
- eRuby template processor
Ember (EMBEdded Ruby) is an eRuby template processor that allows debugging, reduces markup, and improves composability of eRuby templates.
Reports correct line numbers in error message stack traces.
Omits newlines trailing code-only <% ... %>
directives.
Can infer missing <% end %>
directives based on indentation.
Can unindent eRuby block bodies hierarchically.
Written in 335 lines of pure Ruby.
Prerequisites:
Installing:
gem install ember
Upgrading:
gem update ember
Removing:
gem uninstall ember
ember
[OPTIONS] [FILE]
Evaluates eRuby directives (see SYNTAX below) in the given FILE and writes the result to the standard output stream (STDOUT). If FILE is not given, then the standard input stream (STDIN) is evaluated instead.
-s
, --shorthand
Treat lines beginning with zero or more whitespace followed by the "%" character as eRuby directives.
-i
, --infer_end
Add missing <% end %>
directives based on indentation.
-u
, --unindent
Unindent the bodies of directives that define a Ruby block (do ... end) or scope (begin ... end).
-c
, --compile
Print underlying Ruby program compiled from the input eRuby template and exit.
-h
, --help
Print this message and exit.
-v
, --version
Print version number and exit.
This section explains eRuby template syntax and Ember extensions thereof.
eRuby templates are plain-text documents that contain special processing instructions known as directives. These instructions are evaluated in place, meaning that they are replaced by the result of their evaluation.
Directives are expressed in either standard or shorthand notation:
Notation Directive Head Operation Body Tail
-------- --------- ---- --------- ---- ----
Standard <%XY%> <% X Y %>
Shorthand %XY % X Y
In standard notation, the directive is composed of a head, an operation, a body, and a tail; and it may appear anywhere in the template.
In shorthand notation, the directive is composed of a head, an operation, and a body; and it may only appear in the template if it occupies an entire line (leading whitespace is permitted only in Ember; trailing whitespace is permitted in both Ember and eRuby).
Regardless of the notation used, directives are atomic constructs; they cannot be nested within one another.
The first character following the head of a directive is known as an operation. It determines how the directive is processed by Ember.
#
The entire directive is omitted from the output.
=
The body of the directive is evaluated as Ruby code, and the result of this evaluation is inserted into the output.
~
(only in Ember) The body of the directive is evaluated as an eRuby template, and the result of this evaluation is inserted into the output.
+
(only in Ember) The body of the directive is evaluated as Ruby code, and the result of this evaluation is assumed to be a string that specifies the path (either absolute or relative to the eRuby template file in which this directive is found) to a file containing an eRuby template. This file is read and its contents are evaluated as an eRuby template, and the result of this evaluation is inserted into the output.
<
(only in Ember) The body of the directive is evaluated as Ruby code, and the result of this evaluation is assumed to be a string that specifies the path (either absolute or relative to the eRuby template file in which this directive is found) to a file. This file is read and its contents are inserted into the output.
|
(only in Ember) The body of the directive is treated as the beginning of a
Ruby block. The do
keyword is automatically appended to the body of the
directive if missing.
%
One "%" character is omitted from the head of the directive and the entire directive is inserted into the output.
The body of the directive is evaluated as Ruby code, but the result of this evaluation is not inserted into the output.
Begin by loading Ember into Ruby:
require 'rubygems' # might not be necessary; see HACKING
require 'ember'
Instantiate an Ember template processor:
source = "your eRuby template here"
options = {} # see API documentation
template = Ember::Template.new(source, options)
Inspect the Ruby program that was compiled (and is used) by the Ember template processor to evaluate the eRuby template given as input:
puts template.program
View the result of evaluating the eRuby template:
puts template.render
See the API documentation for more information.
Begin with an empty template:
The above template compiles into:
(_erbout = []; _erbout << "\n"
; _erbout.join)
And renders as:
Add comment directives:
<%# this is a comment %>
%# this is also a comment
<%# this
is
a
multi-line comment %>
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
_erbout << "\n"
_erbout << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
Add escaped directives:
<%% this is an escaped directive %>
%% this is an escaped directive
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
_erbout << "<% this is an escaped directive %>\n"
_erbout << "% this is an escaped directive\n"
_erbout << " \n"
; _erbout.join)
And renders as:
<% this is an escaped directive %>
% this is an escaped directive
Add vocal directives, which produce output:
<%= "hello" %>
%= "world"
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
_erbout << ("hello") << "\n"
_erbout << ("world") << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
hello
world
Add silent directives, which do not produce output:
<% a = "hello" %>
% b = "world"
<%= a %>
%= b
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
a = "hello"
b = "world"
_erbout << "\n"
_erbout << (a) << "\n"
_erbout << (b) << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
hello
world
Add some Ruby blocks:
% words = %w[hello world]
<% words.each do |w| %>
<%= w %>
<% end %>
% words.each do |w|
%= w
% end
%|words.each |w|
%= w
% end
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
words = %w[hello world]
_erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end
_erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end
_erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
hello
world
hello
world
hello
world
Omit <% end %>
directives from the template:
% words = %w[hello world]
<% words.each do |w| %>
<%= w %>
% words.each do |w|
%= w
%|words.each |w|
%= w
With {:shorthand=>true, :infer_end=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
words = %w[hello world]
_erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end; _erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end; _erbout << "\n"
words.each do |w|
_erbout << " " << (w) << "\n"
end; _erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
hello
world
hello
world
hello
world
When doc/example.txt
contains:
This is a plain-text file. Notice that <%=
"eRuby directives" %> have no effect here!
And the eRuby template is:
<%< "doc/example.txt" %>
%< "doc/example.txt"
With {:shorthand=>true, :source_file=>"./EXAMPLES"}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
_erbout << (::Ember::Template.read_file(( "doc/example.txt" ), {:shorthand=>true, :source_file=>"./EXAMPLES"})) << "\n"
_erbout << "\n"
_erbout << (::Ember::Template.read_file(( "doc/example.txt"), {:shorthand=>true, :source_file=>"./EXAMPLES"})) << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
This is a plain-text file. Notice that <%=
"eRuby directives" %> have no effect here!
This is a plain-text file. Notice that <%=
"eRuby directives" %> have no effect here!
When doc/example.erb
contains:
This is an eRuby template. Notice that <%=
"eRuby directives" %> do take effect here!
And the eRuby template is:
<%+ "doc/example.erb" %>
%+ "doc/example.erb"
With {:shorthand=>true, :source_file=>"./EXAMPLES"}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
::Ember::Template.load_file(( "doc/example.erb" ), {:shorthand=>true, :source_file=>"./EXAMPLES"}.merge!(:continue_result => true)).render(nil, 79777922); _erbout << "\n"
_erbout << "\n"
::Ember::Template.load_file(( "doc/example.erb"), {:shorthand=>true, :source_file=>"./EXAMPLES"}.merge!(:continue_result => true)).render(nil, 79777922); _erbout << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
This is an eRuby template. Notice that eRuby directives do take effect here!
This is an eRuby template. Notice that eRuby directives do take effect here!
<%~ "%= 2 + 2" %>
%~ "%= 2 + 2"
With {:shorthand=>true}
options, the
above template compiles into:
(_erbout = []; _erbout << "\n"
::Ember::Template.new(( "%= 2 + 2" ), {:shorthand=>true}.merge!(:continue_result => true)).render(nil, 79408546); _erbout << "\n"
_erbout << "\n"
::Ember::Template.new(( "%= 2 + 2"), {:shorthand=>true}.merge!(:continue_result => true)).render(nil, 79408546); _erbout << "\n"
_erbout << "\n"
_erbout << " \n"
; _erbout.join)
And renders as:
4
4
This section is meant for people who want to develop Ember's source code.
Install Ruby libraries necessary for development:
gem install ember --development
Inochi serves as Ember's project infrastructure. It handles tasks such as building this manual and API documentation, and packaging, announcing, and publishing new releases. See its manual to get started:
inochi --help
Ensure that the lib/
directory is listed in Ruby's $LOAD_PATH
before you
use any libraries therein or run any executables in the bin/
directory.
This can be achieved by passing an option to Ruby:
ruby -Ilib
Or by setting the $RUBYLIB
environment variable:
export RUBYLIB=lib # bash, ksh, zsh
setenv RUBYLIB lib # csh
set -x RUBYLIB lib # fish
Or by installing the ruby-wrapper tool.
If you use Ruby 1.8 and RubyGems to manage your Ruby software, then ensure
that RubyGems is activated before you use any libraries in the lib/
directory or run any executables in the bin/
directory.
This can be achieved by passing an option to Ruby:
ruby -rubygems
Or by setting the $RUBYOPT
environment variable:
export RUBYOPT=-rubygems # bash, ksh, zsh
setenv RUBYOPT -rubygems # csh
set -x RUBYOPT -rubygems # fish
Simply execute the included test runner, which sets up Ruby's $LOAD_PATH
for
testing, loads the included test/test_helper.rb
file, and then evaluates all
test/**/*_test.rb
files:
test/runner
Its exit status will indicate whether all tests have passed. It may also
print additional pass/fail information depending on the testing library used
in the test/test_helper.rb
file.
Fork this project on GitHub (see Resources above) and send a pull request.
This section contains release notes of current and past releases.
This release fixes a nested rendering bug, updates the manual, and further beautifies the Ruby code that results from eRuby template compilation.
Bug fixes:
Ember::Template#render()
now creates isolated contexts by default to
prevent nested calls from clobbering each other's output!
For example, if template A calls method X which renders template B (thinking that template B's rendering is isolated and will not affect the rendering of template A) then you're in for a hell of a wild bug chase! >8-(
Housekeeping:
Upgrade to Inochi 2.0.0rc5. Convert manual from ERBook to Ember + Ronn.
Remove spaces around value insertions in template compilation output.
Remove logo images from source repository because they're no longer used.
This release improves the handling of eRuby comment directives, fixes a bug
in the <% end %>
inference logic, and performs some minor housekeeping.
New features:
Single-line comment directives are now ignored (treated like no-ops) in input templates. This allows us to surround eRuby block directives with section separators made from single-line comment directives:
%|some_block_directive
Inside some_block_directive.
%#---------------------------------------------------------------------
Still inside some_block_directive!
%#-------------------------------------------------------------------
%| nested_block_directive
%#-------------------------------------------------------------------
Inside nested_block_directive.
Bug fixes:
<% end %>
inference did not work for blocks
beginning with def
, class
, and module
keywords.Housekeeping:
This release improves Ruby 1.9 support and revises the user manual.
Bug fixes:
Housekeeping:
Use simpler Copyright reminder at the top of every file.
Rename internal Program
class' methods to be self-documenting.
Open source is for fun, so be nice and speak of "related works" instead of "competitors".
This is the first public release of Ember. Enjoy!
Suraj N. Kurapati
(the ISC license)
Copyright 2009 Suraj N. Kurapati sunaku@gmail.com
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.