Class: Mustache::Template
- Inherits:
-
Object
- Object
- Mustache::Template
- Defined in:
- lib/mustache/template.rb
Overview
A Template is a compiled version of a Mustache template.
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.
Defined Under Namespace
Classes: UnclosedSection
Instance Method Summary collapse
-
#compile(src = @source) ⇒ Object
Does the dirty work of transforming a Mustache template into an interpolation-friendly Ruby string.
-
#compile_partial(name) ⇒ Object
Partials are basically a way to render views from inside other views.
-
#compile_sections(src) ⇒ Object
{{#sections}okay{/sections}.
-
#compile_tags(src) ⇒ Object
Find and replace all non-section tags.
-
#ctag ⇒ Object
}} - closing tag delimiter.
- #ctag=(tag) ⇒ Object
-
#etag(s) ⇒ Object
{} - an escaped tag.
-
#ev(s) ⇒ Object
An interpolation-friendly version of a string, for use within a Ruby string.
-
#initialize(source, template_path = '.', template_extension = 'mustache') ⇒ Template
constructor
Expects a Mustache template as a string along with a template path, which it uses to find partials.
-
#otag ⇒ Object
{{ - opening tag delimiter.
- #otag=(tag) ⇒ Object
-
#render(context) ⇒ Object
Renders the ‘@source` Mustache template using the given `context`, which should be a simple hash keyed with symbols.
-
#str(s) ⇒ Object
Get a (hopefully) literal version of an object, sans quotes.
-
#tmpid ⇒ Object
Generate a temporary id, used when compiling code.
-
#utag(s) ⇒ Object
{{}} - an unescaped tag.
Constructor Details
#initialize(source, template_path = '.', template_extension = 'mustache') ⇒ Template
Expects a Mustache template as a string along with a template path, which it uses to find partials.
35 36 37 38 39 40 |
# File 'lib/mustache/template.rb', line 35 def initialize(source, template_path = '.', template_extension = 'mustache') @source = source @template_path = template_path @template_extension = template_extension @tmpid = 0 end |
Instance Method Details
#compile(src = @source) ⇒ Object
Does the dirty work of transforming a Mustache template into an interpolation-friendly Ruby string.
59 60 61 |
# File 'lib/mustache/template.rb', line 59 def compile(src = @source) "\"#{compile_sections(src)}\"" end |
#compile_partial(name) ⇒ Object
Partials are basically a way to render views from inside other views.
121 122 123 124 |
# File 'lib/mustache/template.rb', line 121 def compile_partial(name) src = File.read("#{@template_path}/#{name}.#{@template_extension}") compile(src)[1..-2] end |
#compile_sections(src) ⇒ Object
Mustache::Template.{{#sections}okay{/sections}
Sections can return true, false, or an enumerable. If true, the section is displayed. If false, the section is not displayed. If enumerable, the return value is iterated over (a ‘for` loop).
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/mustache/template.rb', line 69 def compile_sections(src) res = "" while src =~ /#{otag}\#([^\}]*)#{ctag}\s*(.+?)#{otag}\/\1#{ctag}\s*/m # $` = The string to the left of the last successful match res << ($`) name = $1.strip.to_sym.inspect code = compile($2) ctxtmp = "ctx#{tmpid}" res << ev(<<-compiled) if v = ctx[#{name}] v = [v] unless v.is_a?(Array) # shortcut when passed non-array v.map { |h| ctx.push(h); c = #{code}; ctx.pop; c }.join end compiled # $' = The string to the right of the last successful match src = $' end res << (src) end |
#compile_tags(src) ⇒ Object
Find and replace all non-section tags. In particular we look for four types of tags:
-
Escaped variable tags - {var}
-
Unescaped variable tags - {{var}}
-
Comment variable tags - comment
-
Partial tags - partial_name }
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/mustache/template.rb', line 95 def (src) res = "" while src =~ /#{otag}(#|=|!|<|>|\{)?(.+?)\1?#{ctag}+/m res << str($`) case $1 when '#' # Unclosed section - raise an error and # report the line number raise UnclosedSection.new(@source, $&, $2) when '!' # ignore comments when '=' self.otag, self.ctag = $2.strip.split(' ', 2) when '>', '<' res << compile_partial($2.strip) when '{' res << utag($2.strip) else res << etag($2.strip) end src = $' end res << str(src) end |
#ctag ⇒ Object
}} - closing tag delimiter
146 147 148 |
# File 'lib/mustache/template.rb', line 146 def ctag @ctag ||= Regexp.escape('}}') end |
#ctag=(tag) ⇒ Object
150 151 152 |
# File 'lib/mustache/template.rb', line 150 def ctag=(tag) @ctag = Regexp.escape(tag) end |
#etag(s) ⇒ Object
{} - an escaped tag
155 156 157 |
# File 'lib/mustache/template.rb', line 155 def etag(s) ev("CGI.escapeHTML(ctx[#{s.strip.to_sym.inspect}].to_s)") end |
#ev(s) ⇒ Object
An interpolation-friendly version of a string, for use within a Ruby string.
166 167 168 |
# File 'lib/mustache/template.rb', line 166 def ev(s) "#\{#{s}}" end |
#otag ⇒ Object
{{ - opening tag delimiter
137 138 139 |
# File 'lib/mustache/template.rb', line 137 def otag @otag ||= Regexp.escape('{{') end |
#otag=(tag) ⇒ Object
141 142 143 |
# File 'lib/mustache/template.rb', line 141 def otag=(tag) @otag = Regexp.escape(tag) end |
#render(context) ⇒ Object
Renders the ‘@source` Mustache template using the given `context`, which should be a simple hash keyed with symbols.
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/mustache/template.rb', line 44 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 |
#str(s) ⇒ Object
Get a (hopefully) literal version of an object, sans quotes
132 133 134 |
# File 'lib/mustache/template.rb', line 132 def str(s) s.inspect[1..-2] end |
#tmpid ⇒ Object
Generate a temporary id, used when compiling code.
127 128 129 |
# File 'lib/mustache/template.rb', line 127 def tmpid @tmpid += 1 end |
#utag(s) ⇒ Object
{{}} - an unescaped tag
160 161 162 |
# File 'lib/mustache/template.rb', line 160 def utag(s) ev("ctx[#{s.strip.to_sym.inspect}]") end |