Module: Fifty
- Defined in:
- lib/fifty.rb
Defined Under Namespace
Modules: Helpers
Constant Summary collapse
- VERSION =
Version of the gem.
'0.1.1'
- JS_ESCAPE_MAP =
Helper map for JS escaping.
{ '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
Class Attribute Summary collapse
-
.compiled ⇒ Object
Boolean - have we compiled?.
-
.context ⇒ Object
Context of the calling script.
-
.hbs ⇒ Object
Handlebars runtime.
-
.helpers ⇒ Object
Hash of compiled helpers.
-
.logger ⇒ Object
Logger for debug info.
-
.partials ⇒ Object
Hash of compiled partials.
-
.shareds ⇒ Object
Hash of compiled shared data.
-
.views ⇒ Object
Glob-style paths to templates.
Class Method Summary collapse
-
.compile ⇒ Object
Compile static and inline HAML templates to HTML/HBS templates.
-
.compile_inline_template(name, info) ⇒ Object
Compile a single inline template into HTML/HBS.
-
.compile_inline_templates ⇒ Object
Iterate over inline templates and compile them.
-
.compile_template_file(file) ⇒ Object
Compile a single HAML template file to HTML with HBS.
-
.compile_template_files ⇒ Object
Iterate over all template files and compile each one to HBS.
-
.debug(text) ⇒ Object
Output a debug text to the logger.
-
.escape_hbs(partial) ⇒ Object
Escape double and triple-mustaches.
-
.escape_javascript(javascript) ⇒ Object
Escape text for inclusion into a quoted JS string.
-
.eval_js(code) ⇒ Object
Evaluate Javascript code within the context of the JS runtime and return the code as plaintext.
-
.find_template_file(name) ⇒ Object
Find a template file given it’s name.
-
.get_inline_templates ⇒ Object
Get the inline templates defined in Sinatra::Application, excluding templates containing the word “layout”.
-
.get_template(name) ⇒ Object
Find a template and get its contents.
-
.get_template_files ⇒ Object
Return a list of the template files, as defined in the list of view paths, excluding the templates containing the word “layout” (which are assumed to be static and part of the page that is always rendered server-side).
-
.haml2hbs(name, options = {}) ⇒ Object
Render a HAML template into HTML/HBS.
-
.hbs2html(html, data) ⇒ Object
Render HBS to HTML.
-
.header(type) ⇒ Object
Generate a header of a given type.
-
.headers ⇒ Object
Output the helpers, the partials, and the data inside script tags.
-
.helper(name, helper) ⇒ Object
Register a Handlebars helper with a name and a Javascript function.
-
.helper_registerer(name, fn) ⇒ Object
Generates JS code to register a Handlebars helper.
-
.included(base) ⇒ Object
When Fifty is included into an application, compile each of the helpers.
-
.partial_registerer(name, code) ⇒ Object
Generates JS code to register a Handlebars partial.
-
.path_to_name(path) ⇒ Object
Convert a file path to a template name.
-
.render_haml(name, options = {}, &block) ⇒ Object
Get the contents of a HAML template by name and render the template to HTML with nested HBS.
-
.render_layout(context, insert, options) ⇒ Object
If the :layout option is set to true, render the supplied template inside the layout.
-
.render_raw_haml(haml) ⇒ Object
Render actual HAML content.
-
.script_tag(id, code, type = 'text/javascript') ⇒ Object
Generates a Javascript script tag with inline code.
-
.shared(name, data) ⇒ Object
Make a piece of Ruby data available to the client as a JSON object.
-
.unescape_hbs(html) ⇒ Object
Unescape double and triple-mustaches.
Instance Method Summary collapse
-
#fifty(view, data, globals = {}) ⇒ Object
(also: #fy)
Main API for rendering templates with Fifty.
Class Attribute Details
.compiled ⇒ Object
Boolean - have we compiled?
23 24 25 |
# File 'lib/fifty.rb', line 23 def compiled @compiled end |
.context ⇒ Object
Context of the calling script.
25 26 27 |
# File 'lib/fifty.rb', line 25 def context @context end |
.hbs ⇒ Object
Handlebars runtime.
29 30 31 |
# File 'lib/fifty.rb', line 29 def hbs @hbs end |
.helpers ⇒ Object
Hash of compiled helpers.
17 18 19 |
# File 'lib/fifty.rb', line 17 def helpers @helpers end |
.logger ⇒ Object
Logger for debug info.
27 28 29 |
# File 'lib/fifty.rb', line 27 def logger @logger end |
.partials ⇒ Object
Hash of compiled partials
21 22 23 |
# File 'lib/fifty.rb', line 21 def partials @partials end |
.shareds ⇒ Object
Hash of compiled shared data.
19 20 21 |
# File 'lib/fifty.rb', line 19 def shareds @shareds end |
.views ⇒ Object
Glob-style paths to templates.
15 16 17 |
# File 'lib/fifty.rb', line 15 def views @views end |
Class Method Details
.compile ⇒ Object
Compile static and inline HAML templates to HTML/HBS templates.
95 96 97 98 99 |
# File 'lib/fifty.rb', line 95 def self.compile compile_template_files compile_inline_templates self.compiled = true end |
.compile_inline_template(name, info) ⇒ Object
Compile a single inline template into HTML/HBS.
153 154 155 156 157 158 159 160 161 |
# File 'lib/fifty.rb', line 153 def self.compile_inline_template(name, info) partial = render_raw_haml(info[0].strip) partials[name] = escape_hbs(partial) rescue debug "Couldn't compile inline #{name}" raise else debug "Compiled inline #{name}" end |
.compile_inline_templates ⇒ Object
Iterate over inline templates and compile them.
146 147 148 149 150 |
# File 'lib/fifty.rb', line 146 def self.compile_inline_templates get_inline_templates.each do |name, info| compile_inline_template(name, info) end end |
.compile_template_file(file) ⇒ Object
Compile a single HAML template file to HTML with HBS.
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/fifty.rb', line 122 def self.compile_template_file(file) contents = File.read(file) partial = render_raw_haml(contents) name = path_to_name(file) template = escape_hbs(partial) reg = partial_registerer(name, template) partials[name] = reg rescue debug "Couldn't compile #{file}" raise else debug "Compiled #{file}" end |
.compile_template_files ⇒ Object
Iterate over all template files and compile each one to HBS.
114 115 116 117 118 |
# File 'lib/fifty.rb', line 114 def self.compile_template_files get_template_files.each do |file| compile_template_file(file) end end |
.debug(text) ⇒ Object
Output a debug text to the logger.
235 236 237 238 239 240 241 |
# File 'lib/fifty.rb', line 235 def self.debug(text) if logger.respond_to? :info logger.info "[Fifty]: #{text}" else logger.puts "[Fifty]: #{text}" end end |
.escape_hbs(partial) ⇒ Object
Escape double and triple-mustaches.
291 292 293 294 295 296 297 |
# File 'lib/fifty.rb', line 291 def self.escape_hbs(partial) 2.times do partial.gsub!("{{", "{%{") partial.gsub!("}}", "}%}") end partial end |
.escape_javascript(javascript) ⇒ Object
Escape text for inclusion into a quoted JS string.
285 286 287 288 |
# File 'lib/fifty.rb', line 285 def self.escape_javascript(javascript) regexp = /(\\|<\/|\r\n|\342\200\250|[\n\r"'])/u javascript.gsub(regexp) {|match| JS_ESCAPE_MAP[match] } end |
.eval_js(code) ⇒ Object
Evaluate Javascript code within the context of the JS runtime and return the code as plaintext.
248 249 250 251 252 253 |
# File 'lib/fifty.rb', line 248 def self.eval_js(code) hbs.instance_eval do @js.runtime.eval(code) end code end |
.find_template_file(name) ⇒ Object
Find a template file given it’s name.
201 202 203 204 205 |
# File 'lib/fifty.rb', line 201 def self.find_template_file(name) name = name.to_s.gsub('-', '/') file = File.join('views', name) + '.haml' return file if File.readable?(file) end |
.get_inline_templates ⇒ Object
Get the inline templates defined in Sinatra::Application, excluding templates containing the word “layout”.
139 140 141 142 143 |
# File 'lib/fifty.rb', line 139 def self.get_inline_templates Sinatra::Application.templates .map { |p| Dir[p] }.flatten .reject { |x| x.to_s.index('layout') } end |
.get_template(name) ⇒ Object
Find a template and get its contents.
189 190 191 192 193 194 195 196 197 198 |
# File 'lib/fifty.rb', line 189 def self.get_template(name) inlines = Sinatra::Application.templates if path = find_template_file(name) File.read(path) elsif partial = inlines[name.intern] partial.first else raise "Couldn't find template for #{name}." end end |
.get_template_files ⇒ Object
Return a list of the template files, as defined in the list of view paths, excluding the templates containing the word “layout” (which are assumed to be static and part of the page that is always rendered server-side).
107 108 109 110 |
# File 'lib/fifty.rb', line 107 def self.get_template_files views.map { |p| Dir[p] }.flatten .select { |x| x.index('layout').nil? } end |
.haml2hbs(name, options = {}) ⇒ Object
Render a HAML template into HTML/HBS.
164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/fifty.rb', line 164 def self.haml2hbs(name, = {}) result = render_haml(name, layout: false) while data = result.match(/{{> ([^}]*)}}/) partial = render_haml($1, layout: false) result = result.gsub(data[0], partial) end render_layout(context, result, ) rescue debug "Couldn't render template #{name}" raise end |
.hbs2html(html, data) ⇒ Object
Render HBS to HTML.
230 231 232 |
# File 'lib/fifty.rb', line 230 def self.hbs2html(html, data) unescape_hbs(hbs.compile(html).call(@@current = data)) end |
.header(type) ⇒ Object
Generate a header of a given type.
76 77 78 79 80 81 82 |
# File 'lib/fifty.rb', line 76 def self.header(type) header, list = '', self.send(type) list.each do |name, code| header += code + "\n" end script_tag(type, header) end |
.headers ⇒ Object
Output the helpers, the partials, and the data inside script tags.
68 69 70 71 72 73 |
# File 'lib/fifty.rb', line 68 def self.headers scripts = ['helpers', 'partials', 'shareds'] headers = '' scripts.each { |type| headers += header(type) } headers end |
.helper(name, helper) ⇒ Object
Register a Handlebars helper with a name and a Javascript function.
54 55 56 57 |
# File 'lib/fifty.rb', line 54 def self.helper(name, helper) code = helper_registerer(name, helper) helpers[name] = eval_js(code) end |
.helper_registerer(name, fn) ⇒ Object
Generates JS code to register a Handlebars helper.
261 262 263 |
# File 'lib/fifty.rb', line 261 def self.helper_registerer(name, fn) "Handlebars.registerHelper('#{name}', #{fn});" end |
.included(base) ⇒ Object
When Fifty is included into an application, compile each of the helpers.
312 313 314 315 316 |
# File 'lib/fifty.rb', line 312 def self.included(base) helpers = Fifty::Helpers.constants .map { |c| Fifty::Helpers.const_get(c) } helpers.each { |h| h.compile } end |
.partial_registerer(name, code) ⇒ Object
Generates JS code to register a Handlebars partial.
266 267 268 269 |
# File 'lib/fifty.rb', line 266 def self.partial_registerer(name, code) "Handlebars.registerPartial('#{name[1..-1]}', " + "'#{escape_javascript(code)}');" end |
.path_to_name(path) ⇒ Object
Convert a file path to a template name.
224 225 226 227 |
# File 'lib/fifty.rb', line 224 def self.path_to_name(path) trimmed = path.gsub('./', '').gsub('.haml', '') '_' + trimmed.split('/')[1..-1].join('-') end |
.render_haml(name, options = {}, &block) ⇒ Object
Get the contents of a HAML template by name and render the template to HTML with nested HBS.
209 210 211 212 213 214 215 |
# File 'lib/fifty.rb', line 209 def self.render_haml(name, = {}, &block) Haml::Engine.new(get_template(name), ) .render(context, [:locals] || {}, &block) rescue debug "Couldn't render template #{name}" raise end |
.render_layout(context, insert, options) ⇒ Object
If the :layout option is set to true, render the supplied template inside the layout.
178 179 180 181 182 183 184 185 186 |
# File 'lib/fifty.rb', line 178 def self.render_layout(context, insert, ) return insert unless [:layout] layout = if [:layout].is_a?(Symbol) [:layout] else [:layout] ? :layout : false end render_haml(layout, ) { insert } end |
.render_raw_haml(haml) ⇒ Object
Render actual HAML content.
218 219 220 221 |
# File 'lib/fifty.rb', line 218 def self.render_raw_haml(haml) args = [ context, layout: false ] Haml::Engine.new(haml).render(*args) end |
.script_tag(id, code, type = 'text/javascript') ⇒ Object
Generates a Javascript script tag with inline code.
256 257 258 |
# File 'lib/fifty.rb', line 256 def self.script_tag(id, code, type = 'text/javascript') "\n<script id='#{id}' type='#{type}'>#{code}</script>\n" end |
.shared(name, data) ⇒ Object
Make a piece of Ruby data available to the client as a JSON object.
61 62 63 64 |
# File 'lib/fifty.rb', line 61 def self.shared(name, data) code = "var #{name} = #{data};\n" shareds[name] = eval_js(code) end |
.unescape_hbs(html) ⇒ Object
Unescape double and triple-mustaches.
300 301 302 303 304 305 306 |
# File 'lib/fifty.rb', line 300 def self.unescape_hbs(html) 2.times do html.gsub!("{%{", "{{") html.gsub!("}%}", "}}") end html end |