Module: Syro::Tilt
- Includes:
- Cache
- Defined in:
- lib/syro/tilt.rb,
lib/syro/tilt/cache.rb
Overview
Render Tilt templates in Syro routes.
Defined Under Namespace
Modules: Cache
Constant Summary collapse
- DEFAULT_MIME_TYPE =
'text/plain'
- DOT =
'.'
- EMPTY =
''
- HTTP_ACCEPT =
'HTTP_ACCEPT'
- MIME_TYPE_ANY =
'*/*'
- ACCEPT_CAPTURE_QUALITY =
/\Aq=([\d.]+)/.freeze
- ACCEPT_SPLIT_MULTIPLES =
/\s*,\s*/.freeze
- ACCEPT_SPLIT_PARTS =
/\s*;\s*/.freeze
Instance Method Summary collapse
-
#content_for(key) ⇒ String
Capture content from a block for use later.
-
#content_for?(key) ⇒ Boolean
Determine if there’s content to display.
-
#layout(templ = nil) ⇒ String?
Set or get the current layout.
-
#partial(path, locals = {}) ⇒ String
Generate a string by rendering the Tilt template in the context of ‘self` with the locals that were passed in.
-
#render(path, locals = {}) ⇒ Object
Render a template to Syro’s #res object and write the appropriate MIME type based on the rendered template.
-
#template(path) ⇒ Tilt::Template
A Tilt template for the file path passed in.
-
#template_mime_type(path) ⇒ String
Get the MIME type of a template file.
-
#template_options(_templ = nil) ⇒ Hash
Options passed to Tilt.new.
-
#template_path(path, from = nil, accept = nil) ⇒ String
Find a template’s file path based on a “fuzzy” name like “posts/show”.
-
#templates_directory ⇒ String
The default directory to look for templates within.
Methods included from Cache
template_cache, template_path_cache
Instance Method Details
#content_for(key) ⇒ String
Capture content from a block for use later. Note that capturing the block is not implemented here due to the differences in varying template languages. Erubi::CaptureEndEngine and Hamlit::Block::Engine work well with this method.
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/syro/tilt.rb', line 167 def content_for(key) inbox[:tilt_content_for] ||= {} inbox[:tilt_content_for][key] ||= [] if block_given? inbox[:tilt_content_for][key].push yield EMPTY # Returned to prevent the result of #push from displaying. else inbox[:tilt_content_for].delete(key).join end end |
#content_for?(key) ⇒ Boolean
Determine if there’s content to display.
187 188 189 190 191 192 |
# File 'lib/syro/tilt.rb', line 187 def content_for?(key) inbox[:tilt_content_for] ||= {} inbox[:tilt_content_for][key] ||= [] !inbox[:tilt_content_for][key].empty? end |
#layout(templ = nil) ⇒ String?
Set or get the current layout. A layout is just another template to wrap other templates in. If set, it’ll be used by #render.
131 132 133 134 |
# File 'lib/syro/tilt.rb', line 131 def layout(templ = nil) inbox[:tilt_layout] = templ if templ inbox[:tilt_layout] end |
#partial(path, locals = {}) ⇒ String
Generate a string by rendering the Tilt template in the context of ‘self` with the locals that were passed in.
117 118 119 120 121 122 |
# File 'lib/syro/tilt.rb', line 117 def partial(path, locals = {}) accept = env.fetch(HTTP_ACCEPT) { EMPTY } from = locals.delete(:from) { templates_directory } template(template_path(path, from, accept)).render(self, locals) { yield if block_given? } end |
#render(path, locals = {}) ⇒ Object
Render a template to Syro’s #res object and write the appropriate MIME type based on the rendered template.
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/syro/tilt.rb', line 145 def render(path, locals = {}) accept = env.fetch(HTTP_ACCEPT) { EMPTY } from = locals.delete(:from) { templates_directory } content = partial(path, locals.dup) { yield if block_given? } content = partial(layout, locals.dup) { content } if layout res.headers[Rack::CONTENT_TYPE] = template_mime_type(template_path(path, from, accept)) res.write content end |
#template(path) ⇒ Tilt::Template
A Tilt template for the file path passed in.
21 22 23 |
# File 'lib/syro/tilt.rb', line 21 def template(path) ::Tilt.new(path, (::Tilt.template_for(path))) end |
#template_mime_type(path) ⇒ String
Get the MIME type of a template file. The MIME type is looked up from Rack’s MIME type list.
97 98 99 100 101 |
# File 'lib/syro/tilt.rb', line 97 def template_mime_type(path) File.basename(path).split(DOT).reverse.map do |ext| Rack::Mime::MIME_TYPES[".#{ ext.downcase }"] end.compact.first || DEFAULT_MIME_TYPE end |
#template_options(_templ = nil) ⇒ Hash
Options passed to Tilt.new.
31 32 33 |
# File 'lib/syro/tilt.rb', line 31 def (_templ = nil) {} end |
#template_path(path, from = nil, accept = nil) ⇒ String
Find a template’s file path based on a “fuzzy” name like “posts/show”. The HTTP Accept header will be checked and the first template found that matches the MIME type of the Accept header will be used, otherwise the first matching template file will be used.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/syro/tilt.rb', line 54 def template_path(path, from = nil, accept = nil) from ||= templates_directory path = File.join(from, path) # Taken from Rack::Request#parse_http_accept_header (which is a private # method). accepts = (accept || env.fetch(HTTP_ACCEPT) { EMPTY }).to_s.split(ACCEPT_SPLIT_MULTIPLES).map do |part| attribute, parameters = part.split(ACCEPT_SPLIT_PARTS, 2) quality = if parameters =~ ACCEPT_CAPTURE_QUALITY ACCEPT_CAPTURE_QUALITY.match(parameters)[1].to_f else 1.0 end [attribute, quality] end # Reject "*/*" because it will always match the first thing it is compared # to, regardless of wether there's a better match coming up. accepts.reject! { |acc, _q| acc == MIME_TYPE_ANY } # Find all potential templates e.g. ones with the same name but different # template engines or MIME types. potentials = Dir.glob(File.join(from, '**', '*')).select do |potential| potential.start_with?(path) end.sort # Select the best potential template match based on MIME type and HTTP # Accept header. potentials.find do |potential| content_type = template_mime_type(potential) accepts.any? do |acc, _quality| Rack::Mime.match?(content_type, acc) end end || potentials.first end |
#templates_directory ⇒ String
The default directory to look for templates within.
38 39 40 |
# File 'lib/syro/tilt.rb', line 38 def templates_directory 'views' end |