1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
require 'cgi'
require 'mustache/parser'
require 'mustache/generator'
class Mustache
# A Template represents a Mustache template. It compiles and caches
# a raw string template into something usable.
#
# The idea is this: when handed a Mustache template, convert it into
# a Ruby string by transforming Mustache tags into interpolated
# Ruby.
#
# You shouldn't use this class directly, instead:
#
# >> Mustache.render(template, hash)
class Template
attr_reader :source
# Expects a Mustache template as a string along with a template
# path, which it uses to find partials.
def initialize(source)
@source = source
end
# Renders the `@source` Mustache template using the given
# `context`, which should be a simple hash keyed with symbols.
#
# The first time a template is rendered, this method is overriden
# and from then on it is "compiled". Subsequent calls will skip
# the compilation step and run the Ruby version of the template
# directly.
def render(context)
# Compile our Mustache template into a Ruby string
compiled = "def render(ctx) #{compile} end"
# Here we rewrite ourself with the interpolated Ruby version of
# our Mustache template so subsequent calls are very fast and
# can skip the compilation stage.
instance_eval(compiled, __FILE__, __LINE__ - 1)
# Call the newly rewritten version of #render
render(context)
end
# Does the dirty work of transforming a Mustache template into an
# interpolation-friendly Ruby string.
def compile(src = @source)
Generator.new.compile(tokens(src))
end
alias_method :to_s, :compile
# Returns an array of tokens for a given template.
def tokens(src = @source)
Parser.new.compile(src)
end
end
end
|