lib/pancake/mixins/render.rb in pancake-0.1.29 vs lib/pancake/mixins/render.rb in pancake-0.2.0

- old
+ new

@@ -1,22 +1,19 @@ require 'pancake/mixins/render/template' -require 'pancake/mixins/render/render' require 'pancake/mixins/render/view_context' module Pancake module Mixins module Render class TemplateNotFound < Pancake::Errors::NotFound; end RENDER_SETUP = lambda do |base| base.class_eval do extend Pancake::Mixins::Render::ClassMethods include Pancake::Mixins::Render::InstanceMethods - include Pancake::Mixins::RequestHelper - class self::ViewContext < Pancake::Mixins::Render::ViewContext - include Pancake::Mixins::RequestHelper - end + class base::ViewContext < Pancake::Mixins::Render::ViewContext; end + inheritable_inner_classes :ViewContext unless ancestors.include?(Pancake::Paths) extend Pancake::Paths end @@ -31,49 +28,81 @@ def _template_cache @_template_cache ||= {} end - def _find_template(name) - renderer = _template_cache[name] - return renderer if renderer + # Allows you to set path label for the templates for this class + # + # @example + # MyClass.push_paths(:my_templates, "somewhere", "**/*") + # + # MyClass._template_path_name #=> :my_templates + # @api public + def _template_path_name(opts = {}) + opts[:template_path_name] || :views + end - renderer_path = unique_paths_for(:views, :invert => true).detect do |path| - path.last =~ %r[^\/?(#{name})\.\w+$] - end - - raise TemplateNotFound unless renderer_path - _template_cache[name] = Template.new(name, self, renderer_path.join) + def _find_template(name, opts = {}) + template(name, opts) end def _view_context_cache @_view_context_cache ||= {} @_view_context_cache end def _find_view_context_class_for(template) _view_context_cache[template] ||= begin - Class.new(self::ViewContext) + self::ViewContext end _view_context_cache[template] end - def _renderer_and_view_context_class_for(template) - [_find_template(template), _find_view_context_class_for(template)] + def _renderer_and_view_context_class_for(tplate) + [template(tplate), _find_view_context_class_for(tplate)] end - def _template_name_for(name, opts = {}) - opts[:format] ||= :html - "#{name}.#{opts[:format]}" + def _template_name_for(name, opts) + "#{name}" end - def template(name_or_template, opts = {}) - case name_or_template - when String, Symbol - _find_template(_template_name_for(name_or_template, opts)) + def template(name, opts = {}) + case name when Template - name_or_template + name + when String, Symbol + + template_names = case __template = _template_name_for(name, opts) + when String, Symbol + [__template] + when Array + __template + when Proc + [__template.call(opts)].flatten + else + nil + end + + renderer = _template_cache[template_names] + return renderer if renderer + + unique_paths = unique_paths_for(_template_path_name(opts), :invert => true) + + renderer_path = nil + template_name = nil + + template_names.detect do |tn| + unique_paths.detect do |path| + if path.last =~ %r[^\/?(#{tn})\.\w+$] + template_name = tn + renderer_path = path.join + end + end + end + + raise TemplateNotFound unless renderer_path + _template_cache[template_names] = Template.new(template_name, self, renderer_path) else nil end end @@ -85,19 +114,19 @@ module InstanceMethods def render(*args) opts = Hash === args.last ? args.pop : {} name = args.shift - template_name = _template_name_for(name, opts) + template = self.class.template(name, opts) return opts[:text] if opts[:text] # Get the view context for the tempalte - template, vc_class = self.class._renderer_and_view_context_class_for(template_name) + template, vc_class = self.class._renderer_and_view_context_class_for(template) yield v if block_given? - view_context = vc_class.new(env, self) + view_context = vc_class.new(self) view_context_before_render(view_context) view_context.render(template, opts) end def partial(*args) @@ -109,11 +138,11 @@ partial_name = _partial_template_name_for(name, opts) # Get the view context for the tempalte template, vc_class = self.class._renderer_and_view_context_class_for(partial_name) - view_context = vc_class.new(env, self) + view_context = vc_class.new(self) view_context_before_render(view_context) out = "" if with.kind_of?(Array) @@ -127,62 +156,23 @@ end out end def template(name_or_template, opts = {}) - opts[:format] ||= content_type self.class.template(name_or_template, opts) end - def negotiate_content_type!(*allowed_types) - return content_type if content_type - - allowed_types = allowed_types.flatten - opts = allowed_types.pop if allowed_types.last.kind_of?(Hash) - if opts[:format] - cont, ct, mt = Pancake::MimeTypes.negotiate_by_extension(opts[:format].to_s, allowed_types) - else - env["HTTP_ACCEPT"] ||= "*/*" - cont, ct, mt = Pancake::MimeTypes.negotiate_accept_type(env["HTTP_ACCEPT"], allowed_types) - end - - raise Errors::NotAcceptable unless cont - - headers["Content-Type"] = ct - self.mime_type = mt - self.content_type = cont - cont - end - - def content_type - env['pancake.request.format'] - end - - def content_type=(format) - env['pancake.request.format'] = format - end - - def mime_type - env['pancake.request.mime'] - end - - def mime_type=(mime) - env['pancake.request.mime'] = mime - end - - - # A place holder method for any implementor that wants # to configure the view context prior to rendering occuring # any time this method is overwritten, it should call super! # # @api overwritable def view_context_before_render(context) end private + # @api_overwritable def _template_name_for(name, opts = {}) - opts[:format] ||= content_type self.class._template_name_for(name, opts) end def _partial_template_name_for(name, opts) "_#{_template_name_for(name, opts)}"