Module: Fifty
- Defined in:
- lib/fifty.rb
Defined Under Namespace
Modules: Helpers
Constant Summary collapse
- VERSION =
Version of the gem.
'0.1.4'- 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 HTML compiled partials.
-
.shareds ⇒ Object
Hash of compiled shared data.
-
.updated ⇒ Object
Time last updated at.
-
.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.
- .recompile_templates ⇒ Object
-
.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 HTML 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 |
.updated ⇒ Object
Time last updated at.
31 32 33 |
# File 'lib/fifty.rb', line 31 def updated @updated 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.
99 100 101 102 103 |
# File 'lib/fifty.rb', line 99 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.
174 175 176 177 178 179 180 181 182 |
# File 'lib/fifty.rb', line 174 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.
167 168 169 170 171 |
# File 'lib/fifty.rb', line 167 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.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/fifty.rb', line 141 def self.compile_template_file(file) contents = File.read(file) partial = render_raw_haml(contents) name = path_to_name(file) path = './.hbs/' + name.to_s + '.handlebars' File.open(path, 'w+') { |f| f.write(partial) } 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.
118 119 120 121 122 123 124 |
# File 'lib/fifty.rb', line 118 def self.compile_template_files FileUtils.mkdir_p('./.hbs') get_template_files.each do |file| updated[file] = File.mtime(file) compile_template_file(file) end end |
.debug(text) ⇒ Object
Output a debug text to the logger.
256 257 258 259 260 261 262 |
# File 'lib/fifty.rb', line 256 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.
312 313 314 315 316 317 318 |
# File 'lib/fifty.rb', line 312 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.
306 307 308 309 |
# File 'lib/fifty.rb', line 306 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.
269 270 271 272 273 274 |
# File 'lib/fifty.rb', line 269 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.
222 223 224 225 226 |
# File 'lib/fifty.rb', line 222 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”.
160 161 162 163 164 |
# File 'lib/fifty.rb', line 160 def self.get_inline_templates Sinatra::Application.templates .map { |p| Dir[p] }.flatten .reject { |x| x.to_s.index('layout.haml') } end |
.get_template(name) ⇒ Object
Find a template and get its contents.
210 211 212 213 214 215 216 217 218 219 |
# File 'lib/fifty.rb', line 210 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).
111 112 113 114 |
# File 'lib/fifty.rb', line 111 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.
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/fifty.rb', line 185 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.
251 252 253 |
# File 'lib/fifty.rb', line 251 def self.hbs2html(html, data) unescape_hbs(hbs.compile(html).call(@@current = data)) end |
.header(type) ⇒ Object
Generate a header of a given type.
80 81 82 83 84 85 86 |
# File 'lib/fifty.rb', line 80 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.
72 73 74 75 76 77 |
# File 'lib/fifty.rb', line 72 def self.headers scripts = ['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.
58 59 60 61 |
# File 'lib/fifty.rb', line 58 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.
282 283 284 |
# File 'lib/fifty.rb', line 282 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.
333 334 335 336 337 |
# File 'lib/fifty.rb', line 333 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.
287 288 289 290 |
# File 'lib/fifty.rb', line 287 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.
245 246 247 248 |
# File 'lib/fifty.rb', line 245 def self.path_to_name(path) trimmed = path.gsub('./', '').gsub('.haml', '') '_' + trimmed.split('/')[1..-1].join('-') end |
.recompile_templates ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/fifty.rb', line 126 def self.recompile_templates FileUtils.mkdir_p('./.hbs') recompiled = false get_template_files.each do |file| if File.mtime(file) != updated[file] compile_template_file(file) updated[file] = File.mtime(file) recompiled = true end end yield if recompiled 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.
230 231 232 233 234 235 236 |
# File 'lib/fifty.rb', line 230 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.
199 200 201 202 203 204 205 206 207 |
# File 'lib/fifty.rb', line 199 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.
239 240 241 242 |
# File 'lib/fifty.rb', line 239 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.
277 278 279 |
# File 'lib/fifty.rb', line 277 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.
65 66 67 68 |
# File 'lib/fifty.rb', line 65 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.
321 322 323 324 325 326 327 |
# File 'lib/fifty.rb', line 321 def self.unescape_hbs(html) 2.times do html.gsub!("{%{", "{{") html.gsub!("}%}", "}}") end html end |
Instance Method Details
#fifty(view, data, globals = {}) ⇒ Object Also known as: fy
Main API for rendering templates with Fifty.
89 90 91 92 |
# File 'lib/fifty.rb', line 89 def fifty(view, data, globals = {}) Fifty.compile unless Fifty.compiled Fifty.hbs2html(Fifty.haml2hbs(view, globals), data) end |