more problem and hacks in theme_support plugin
Dorren_mii_thumb by dorren, 11/09/2007
Looks like theme_support doesn't work if route ends with an extension, like "/blog/rss.rxml", nor does it work with namespaced action mailer templates. So I had to change the actionview_ex.rb quite a bit to make it to work. here the updated code:

Changes are:
  1. added "../.." for namespaced mailer template
  2. do not pick_template_extension if extension exists in route.
  3. Move __render_file() into try catch block.

Updates, ActionView::TemplateError check

cool, somebody actually read my stuff! well, yes, above hack returns a very bad exception message if you have a error anywhere in ruby code or in rhtml template. Below is the code I should've put up earlier, just never got time to do it. Now here it is.

# Extending ActionView::Base to support rendering themes
#
module ActionView
   
   # Extending ActionView::Base to support rendering themes
   class Base
      alias_method :__render_file, :render_file

      # Overrides the default Base#render_file to allow theme-specific views
      def render_file(template_path, use_full_path = true, local_assigns = {})        
         search_path = [
            # "../themes/#{controller.current_theme}/views/",       # I don't use components
            "../../themes/#{controller.current_theme}/views/",    # for normal views
            "../../themes/#{controller.current_theme}/",          # for layouts
            # "../../../themes/#{controller.current_theme}/views/", # for mailer views, not using now.
            "",                                                   # fallback
            "../",                                                # Mailer fallback
            "../../"                                              # namespaced Mailer fallback
         ]
         
         if use_full_path
            search_path.each do |prefix|
               theme_path = prefix + template_path
               begin
                  template_path_without_extension, template_extension = path_and_extension(theme_path)
                  template_extension = pick_template_extension(theme_path).to_s if !template_extension

                  # Prevent .rhtml (or any other template type) if force_liquid == true
                  if force_liquid? and
                     template_extension.to_s != 'liquid' and 
                     prefix != '.'
                     raise ThemeError.new("Template '#{template_path}' must be a liquid document")
                  end
                  local_assigns['active_theme'] = get_current_theme(local_assigns)
                  return __render_file(theme_path, use_full_path, local_assigns)
               rescue ActionView::TemplateError => err
                   next if err.message =~ /No such file or directory/            # for rxml templates
                   raise err
               rescue ActionView::ActionViewError => err
                   next
               rescue ThemeError => err
                  # Should it raise an exception, or just call 'next' and revert to
                  # the default template?
                  raise err
               end

            end
            raise ActionViewError, "No rhtml, rxml, or delegate template found for #{template_path} in #{@base_path}"
         else
            __render_file(template_path, use_full_path, local_assigns)
         end
      end
      
   private
   
    def force_liquid?
      unless controller.nil?
        if controller.respond_to?('force_liquid_template')
          controller.force_liquid_template
        end
      else
        false
      end
    end

    def get_current_theme(local_assigns)
      unless controller.nil?
        if controller.respond_to?('current_theme')
          return controller.current_theme || false
        end
      end
      # Used with ActionMailers
      if local_assigns.include? :current_theme 
        return local_assigns.delete :current_theme
      end
    end
  end
end
Views: 1202   Replies: 2   Last Reply: dorren, 12/04.     Tags: theme

comments

amontano 12/03  
Happy_face_w50 Your solution does work but introduces a new bug. I understand that you moved the __render_file call to be inside the block rescued to catch the raised exception when pick_template_extension is not called.

Nevertheless this makes it really hard to debug, since any errors in the templates are also "rescued" and all you see is a "no template found" instead of the actual error!

I blogged about it here: http://www.gaugeus.com/ramblings/2007/12/3/rendering-templates-extensions-theme_support-errors-template-missing-no-rhtml-rxml-delegate-template-found

See there my proposal on fixing this issue.
dorren 12/04  
Dorren_mii_thumb updated. added ActionView::TemplateError check. Pretty much like your solution too. but your way added an extra file read.

anyway, rails is showing its age now. That's why I have great hope for the merb (merbivore.com), which doesn't do rendering so eagerly, so you have alot of freedom to massage the final output, and no need for these crazy theme_support hacks.
 
login or sign up to participate.




Money_dollar moneywill