module Tennpipes::Rendering::InstanceMethods
Instance methods that allow enhanced rendering to function properly in Tennpipes
.
Attributes
Public Instance Methods
Get/Set the content_type
@param [String, nil] type
The Content-Type to use.
@param [Symbol, nil] type.
Look and parse the given symbol to the matched Content-Type.
@param [Hash] params
Additional params to append to the Content-Type.
@example
case content_type when :js then do_some when :css then do_another end content_type :js # => set the response with 'application/javascript' Content-Type content_type 'text/html' # => set directly the Content-Type to 'text/html'
# File lib/tennpipes/rendering.rb, line 166 def content_type(type=nil, params={}) if type super(type, params) @_content_type = type end @_content_type end
Private Instance Methods
# File lib/tennpipes/rendering.rb, line 329 def ensure_rendering_engine(engine) return true if settings.respond_to?(engine) return nil unless engine == :erb require 'erb' rescue LoadError else require 'tennpipes/rendering/erb_template' settings.set :erb, Tennpipes::Rendering.engine_configurations[:erb] end
# File lib/tennpipes/rendering.rb, line 296 def glob_templates(views_path, template_path) parts = [] parts << views_path if views_path.present? if respond_to?(:request) && request.respond_to?(:controller) && request.controller.present? && Pathname.new(template_path).relative? parts << "{,#{request.controller}}" end parts << template_path.chomp(File.extname(template_path)) + '.*' Dir.glob(File.join(parts)).inject([]) do |all,file| next all if IGNORE_FILE_PATTERN.any?{ |pattern| file.to_s =~ pattern } all << path_and_engine(file, views_path) end end
Return the I18n.locale if I18n is defined.
# File lib/tennpipes/rendering.rb, line 261 def locale I18n.locale if defined?(I18n) end
# File lib/tennpipes/rendering.rb, line 320 def path_and_engine(path, relative=nil) extname = File.extname(path) engine = (extname[1..-1]||'none').to_sym path = path.chomp(extname) path.insert(0, '/') unless Pathname.new(path).absolute? path = path.squeeze('/').sub(relative, '') if relative [path.to_sym, engine.to_sym] end
Enhancing Sinatra render functionality for:
-
Using layout similar to rails
-
Use render 'path/to/my/template' (without symbols)
-
Use render 'path/to/my/template' (with engine lookup)
-
Use render 'path/to/template.haml' (with explicit engine lookup)
-
Use render 'path/to/template', :layout => false
-
Use render 'path/to/template', :layout => false, :engine => 'haml'
# File lib/tennpipes/rendering.rb, line 186 def render(engine, data=nil, options={}, locals={}, &block) # If engine is nil, ignore engine parameter and shift up all arguments # render nil, "index", { :layout => true }, { :localvar => "foo" } engine, data, options = data, options, locals if engine.nil? && data # Data is a hash of options when no engine isn't explicit # render "index", { :layout => true }, { :localvar => "foo" } # Data is options, and options is locals in this case data, options, locals = nil, data, options if data.is_a?(Hash) # If data is unassigned then this is a likely a template to be resolved # This means that no engine was explicitly defined data, engine = resolve_template(engine, options) if data.nil? ensure_rendering_engine(engine) || (options[:layout] ||= false) # Cleanup the template. @current_engine, engine_was = engine, @current_engine @_out_buf, buf_was = ActiveSupport::SafeBuffer.new, @_out_buf # Pass arguments to Sinatra render method. super(engine, data, with_layout(options), locals, &block) ensure @current_engine = engine_was @_out_buf = buf_was end
# File lib/tennpipes/rendering.rb, line 265 def resolve_layout(layout, options={}) layouts_path = options[:layout_options] && options[:layout_options][:views] || options[:views] || settings.views || "./views" template_path = settings.fetch_layout_path(layout, layouts_path) rendering_options = [template_path, content_type || :html, locale] settings.cache_template_path(rendering_options) do template_candidates = glob_templates(layouts_path, template_path) selected_template = select_template(template_candidates, *rendering_options) fail TemplateNotFound, "Layout '#{template_path}' not found in '#{layouts_path}'" if !selected_template && layout.present? selected_template end end
Returns the template path and engine that match content_type
(if present), I18n.locale.
@param [String] template_path
The path of the template.
@param [Hash] options
Additional options.
@option options [Boolean] :strict_format (false)
The resolved template must match the content_type of the request.
@option options [Boolean] :raise_exceptions (false)
Raises a {TemplateNotFound} exception if the template cannot be located.
@return [Array<Symbol, Symbol>]
The path and format of the template.
@raise [TemplateNotFound]
The template could not be found.
@example
get "/foo", :provides => [:html, :js] do; render 'path/to/foo'; end # If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb] # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
# File lib/tennpipes/rendering.rb, line 240 def resolve_template(template_path, options={}) template_path = template_path.to_s controller_key = respond_to?(:request) && request.respond_to?(:controller) && request.controller rendering_options = [template_path, content_type || :html, locale] settings.cache_template_path(["#{controller_key}/#{template_path}", rendering_options[1], rendering_options[2]]) do options = DEFAULT_RENDERING_OPTIONS.merge(options) view_path = options[:views] || settings.views || "./views" template_candidates = glob_templates(view_path, template_path) selected_template = select_template(template_candidates, *rendering_options) selected_template ||= template_candidates.first unless options[:strict_format] fail TemplateNotFound, "Template '#{template_path}' not found in '#{view_path}'" if !selected_template && options[:raise_exceptions] selected_template end end
# File lib/tennpipes/rendering.rb, line 309 def select_template(templates, template_path, content_type, _locale) simple_content_type = [:html, :plain].include?(content_type) target_path, target_engine = path_and_engine(template_path) templates.find{ |file,_| file.to_s == "#{target_path}.#{locale}.#{content_type}" } || templates.find{ |file,_| file.to_s == "#{target_path}.#{locale}" && simple_content_type } || templates.find{ |file,engine| engine == target_engine || File.extname(file.to_s) == ".#{target_engine}" } || templates.find{ |file,_| file.to_s == "#{target_path}.#{content_type}" } || templates.find{ |file,_| file.to_s == "#{target_path}" && simple_content_type } end
# File lib/tennpipes/rendering.rb, line 279 def with_layout(options) options = options.dup layout = options[:layout] return options if layout == false layout = @layout if !layout || layout == true return options if settings.templates.has_key?(:layout) && layout.blank? if layout.kind_of?(String) && Pathname.new(layout).absolute? layout_path, _, layout = layout.rpartition('/') options[:layout_options] ||= {} options[:layout_options][:views] ||= layout_path end layout, layout_engine = resolve_layout(layout, options) options.update(:layout => layout, :layout_engine => layout_engine) end