Handlebars.js without the .js
FlavourSaver is a ruby-based implementation of the Handlebars.js templating language.
Please use it, break it, and send issues/PR's for improvement.
FlavourSaver is used in production by a lot of folks, none of whom are me. As I don't use FlavourSaver in my daily life I will not be responding to issues unless they have a corresponding PR. If you'd like to take over maintaining this project then get in contact.
FlavourSaver is Copyright (c) 2013 Resistor Limited and licensed under the terms of the MIT Public License (see the LICENSE file included with this distribution for more details).
Add this line to your application's Gemfile:
gem 'flavour_saver'
And then execute:
$ bundle
Or install it yourself as:
$ gem install flavour_saver
FlavourSaver is in its infancy, your pull requests are greatly appreciated.
Currently supported:
- Full support of Mustache and Handlebars templates.
- Expressions:
- with object-paths (
{{some.method.chain}}
) - containing object-literals (
{{object.['index'].method}}
): Ruby's:[](index)
method is called for literals, making FlavourSaver compatible withHash
and hashlike objects. - with list arguments (
{{method arg1 "arg2"}}
) - with hash arguments (
{{method foo=bar bar="baz"}}
) - with list and hash arguments (
{{method arg1 arg2 foo=bar bar="baz"}}
) provided that the hash is the last argument. - Comments (
{{! a comment}}
) - Expression output is HTML escaped
- with object-paths (
- Safe expressions
- Expressions wrapped in triple-stashes are not HTML escaped (
{{{an expression}}}
)
- Expressions wrapped in triple-stashes are not HTML escaped (
- Block expressions
- Simple API for adding block helpers.
- Block expressions with inverse blocks
- Inverse blocks
FlavourSaver implements the following helpers by default:
Yields its argument into the context of the block contents:
Takes a single collection argument and yields the block's contents once for each member of the collection:
Takes a single argument and yields the contents of the block if that argument is truthy.
It can also handle a special case {{else}}
expression:
Exactly the same is #if
but backwards.
In JavaScript this
is a native keyword, in Ruby not-so-much. FlavourSaver's this
helper
returns self
:
Writes log output. The destination can be changed by assigning a Logger
instance to
FlavourSaver.logger=
. On Rails FlavourSaver.logger
automatically points at
Rails.logger
.
Additional helpers can easy be added by calling FlavourSaver.register_helper
, eg:
FlavourSaver.register_helper(:whom) { 'world' }
Now if you were to render the following template:
You would receive the following output:
<h1>Hello world!</h1>
Creating a block helper works exactly like adding a regular helper, except that
the helper implementation can call yield.contents
one or more times, with an
optional argument setting the context of the block execution:
FlavourSaver.register_helper(:three_times) do
yield.contents
yield.contents
yield.contents
end
Which when called with the following template:
would result in the following output:
hello
hello
hello
Implementing a simple iterator is dead easy:
FlavourSaver.register_helper(:list_people) do |people|
people.each do |person|
yield.contents person
end
end
Which could be used like so:
Block helpers can also contain an {{else}}
statement, which, when used creates
a second set of block contents (called inverse
) which can be yielded to the output:
FlavourSaver.register_helper(:isFemale) do |person,&block|
if person.sex == 'female'
block.call.contents
else
block.call.inverse
end
end
You can also register an existing method:
def isFemale(person)
if person.sex == 'female'
yield.contents
else
yield.inverse
end
end
FlavourSaver.register_helper(method(:isFemale))
Which could be used like so:
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request